summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab/ci/reports.gitlab-ci.yml2
-rw-r--r--.gitlab/ci/review.gitlab-ci.yml2
-rw-r--r--CHANGELOG.md231
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--Gemfile9
-rw-r--r--Gemfile.lock11
-rw-r--r--VERSION2
-rw-r--r--app/assets/javascripts/boards/components/board_blank_state.vue10
-rw-r--r--app/assets/javascripts/boards/components/board_card.vue2
-rw-r--r--app/assets/javascripts/boards/components/board_list.vue7
-rw-r--r--app/assets/javascripts/boards/components/board_new_issue.vue2
-rw-r--r--app/assets/javascripts/boards/components/issue_card_inner.vue23
-rw-r--r--app/assets/javascripts/boards/components/issue_due_date.vue6
-rw-r--r--app/assets/javascripts/boards/components/issue_time_estimate.vue2
-rw-r--r--app/assets/javascripts/boards/components/modal/empty_state.vue4
-rw-r--r--app/assets/javascripts/boards/components/modal/header.vue6
-rw-r--r--app/assets/javascripts/boards/components/modal/index.vue13
-rw-r--r--app/assets/javascripts/boards/components/modal/list.vue4
-rw-r--r--app/assets/javascripts/boards/mixins/issue_card_inner.js5
-rw-r--r--app/assets/javascripts/clusters/components/application_row.vue56
-rw-r--r--app/assets/javascripts/clusters/components/applications.vue7
-rw-r--r--app/assets/javascripts/clusters/components/uninstall_application_button.vue14
-rw-r--r--app/assets/javascripts/clusters/constants.js15
-rw-r--r--app/assets/javascripts/clusters/stores/clusters_store.js55
-rw-r--r--app/assets/javascripts/gfm_auto_complete.js5
-rw-r--r--app/assets/javascripts/monitoring/stores/monitoring_store.js7
-rw-r--r--app/assets/javascripts/notes/components/discussion_actions.vue58
-rw-r--r--app/assets/javascripts/notes/components/noteable_discussion.vue46
-rw-r--r--app/assets/stylesheets/components/dashboard_skeleton.scss15
-rw-r--r--app/assets/stylesheets/pages/boards.scss200
-rw-r--r--app/controllers/application_controller.rb2
-rw-r--r--app/controllers/projects/issues_controller.rb8
-rw-r--r--app/models/ci/build.rb20
-rw-r--r--app/models/ci/job_artifact.rb17
-rw-r--r--app/models/concerns/issuable.rb8
-rw-r--r--app/models/concerns/update_project_statistics.rb60
-rw-r--r--app/models/namespace.rb5
-rw-r--r--app/views/projects/_merge_request_merge_checks_settings.html.haml19
-rw-r--r--app/views/projects/_merge_request_merge_method_settings.html.haml49
-rw-r--r--app/views/projects/_merge_request_merge_options_settings.html.haml14
-rw-r--r--app/views/projects/_merge_request_merge_settings.html.haml24
-rw-r--r--app/views/projects/_merge_request_settings.html.haml4
-rw-r--r--app/views/projects/edit.html.haml2
-rw-r--r--app/views/projects/issues/show.html.haml2
-rw-r--r--app/views/projects/new.html.haml7
-rw-r--r--app/views/shared/_label_row.html.haml11
-rw-r--r--app/views/shared/boards/_show.html.haml10
-rw-r--r--app/views/shared/boards/components/_board.html.haml13
-rw-r--r--app/views/shared/boards/components/_sidebar.html.haml6
-rw-r--r--app/views/shared/issuable/_label_page_default.html.haml2
-rw-r--r--app/views/shared/issuable/_search_bar.html.haml6
-rw-r--r--changelogs/unreleased/10012-move-ee-diff-for-boards-issue-card-inner.yml5
-rw-r--r--changelogs/unreleased/10029-env-item.yml5
-rw-r--r--changelogs/unreleased/10081-env-table.yml5
-rw-r--r--changelogs/unreleased/10735-geo-gitlab-revision-can-return-not-consistent-results.yml5
-rw-r--r--changelogs/unreleased/11124-update-deployment-service-fails-if-project-is-nil.yml5
-rw-r--r--changelogs/unreleased/13784-validate-variables-for-masking.yml5
-rw-r--r--changelogs/unreleased/24936-remove-type-from-review-app-name.yml5
-rw-r--r--changelogs/unreleased/24971-align-emailvalidator-to-validate_email-gem-implementation.yml5
-rw-r--r--changelogs/unreleased/25942-remove-fake-repository-path-response.yml5
-rw-r--r--changelogs/unreleased/29249-show-download-diff-even-when-merge-request-is-closed.yml5
-rw-r--r--changelogs/unreleased/38564-cant-leave-subgroup.yml5
-rw-r--r--changelogs/unreleased/43263-git-push-option-to-create-mr.yml5
-rw-r--r--changelogs/unreleased/43297-authorized-application-count.yml5
-rw-r--r--changelogs/unreleased/46787-create-project-label-window-is-cut-off-at-the-bottom.yml5
-rw-r--r--changelogs/unreleased/47234-composable-auto-devops.yml5
-rw-r--r--changelogs/unreleased/47771-highlighting-in-diff.yml5
-rw-r--r--changelogs/unreleased/48090-filter-sensitive-metric-labels.yml5
-rw-r--r--changelogs/unreleased/48132-display-output-from-pre-receive-scripts.yml5
-rw-r--r--changelogs/unreleased/48297-fix-code-selection.yml6
-rw-r--r--changelogs/unreleased/49856-upgrade-bootstrap-form-gem.yml5
-rw-r--r--changelogs/unreleased/49863-ingress-ip-loading-state.yml5
-rw-r--r--changelogs/unreleased/49910-reopening-a-closed-milestone-from-the-closed-milestones-page-fails2.yml5
-rw-r--r--changelogs/unreleased/51988-install-group-runner-on-group-cluster.yml5
-rw-r--r--changelogs/unreleased/52258-labels-with-long-names-overflow-on-metrics-dashboard.yml5
-rw-r--r--changelogs/unreleased/52366-improved-group-lists-ui-spinners.yml5
-rw-r--r--changelogs/unreleased/52447-auto-devops-at-group-level.yml5
-rw-r--r--changelogs/unreleased/52560-fix-duplicate-tag-system-hooks.yml5
-rw-r--r--changelogs/unreleased/53139-hide-tree-single-file.yml5
-rw-r--r--changelogs/unreleased/53198-git-push-option-merge-when-pipeline-succeeds.yml6
-rw-r--r--changelogs/unreleased/53210-add-uniq-constraints-on-issues-and-mrs-labels.yml5
-rw-r--r--changelogs/unreleased/53459-quick-action-adds-multiple-labels-to-issue-if-middle-words-overlap-with-existing-label.yml5
-rw-r--r--changelogs/unreleased/54417-graphql-type-authorization.yml5
-rw-r--r--changelogs/unreleased/54506-show-error-when-namespace-svc-missing.yml5
-rw-r--r--changelogs/unreleased/54670-external-diffs-when-outdated.yml5
-rw-r--r--changelogs/unreleased/54916-extended-tooltip-for-merge-request-links.yml5
-rw-r--r--changelogs/unreleased/55268-exclude-system-notes-from-commits-in-mr.yml5
-rw-r--r--changelogs/unreleased/55964-fix-email-encoding.yml5
-rw-r--r--changelogs/unreleased/55980-remove-add-issue-on-blank-list.yml5
-rw-r--r--changelogs/unreleased/56015-remove-remote-timeout.yml5
-rw-r--r--changelogs/unreleased/56089-merge-gitlab-keys.yml5
-rw-r--r--changelogs/unreleased/56762-fix-commit-swipe-view-26968.yml5
-rw-r--r--changelogs/unreleased/56833-project-improve-empty-repository-state-ui-fe.yml5
-rw-r--r--changelogs/unreleased/56864-reopen-locked-mr.yml5
-rw-r--r--changelogs/unreleased/56954-improve-knative-after-installing-tiller.yml5
-rw-r--r--changelogs/unreleased/57115-just-in-time-k8s-resource-creation.yml5
-rw-r--r--changelogs/unreleased/57131-external_auth_to_core.yml5
-rw-r--r--changelogs/unreleased/57319-hide-kubernetes-cluster-warning-if-project-has-cluster-related.yml5
-rw-r--r--changelogs/unreleased/57357-automate-base-domain-help-text.yml5
-rw-r--r--changelogs/unreleased/57364-improve-diff-nav-header.yml5
-rw-r--r--changelogs/unreleased/57409-loading-button-transition.yml5
-rw-r--r--changelogs/unreleased/57482-shortcut-to-create-merge-request-from-web-ide.yml5
-rw-r--r--changelogs/unreleased/57493-add-limit-to-user-name.yml5
-rw-r--r--changelogs/unreleased/57540-filename-trailing-space.yml5
-rw-r--r--changelogs/unreleased/57602-create-cluster-validations.yml5
-rw-r--r--changelogs/unreleased/57648-make-emoji-picker-full-width-on-mobile.yml5
-rw-r--r--changelogs/unreleased/57655-fix-markdown-tables-border.yml5
-rw-r--r--changelogs/unreleased/57668-create-file-from-url.yml5
-rw-r--r--changelogs/unreleased/57669-fix-bug-clicking-file-header-refreshes-page.yml6
-rw-r--r--changelogs/unreleased/57894-buttons-on-group-page-are-misaligned.yml5
-rw-r--r--changelogs/unreleased/57984-store-branch-name.yml5
-rw-r--r--changelogs/unreleased/58208-explicitly-set-masterauth.yml6
-rw-r--r--changelogs/unreleased/58293-extract-discussion-actions.yml5
-rw-r--r--changelogs/unreleased/58375-api-controller.yml5
-rw-r--r--changelogs/unreleased/58375-reactive-caching-changes.yml5
-rw-r--r--changelogs/unreleased/58405-basic-limiting-complexity-of-graphql-queries.yml5
-rw-r--r--changelogs/unreleased/58410-change-pixel-size-of-instance-header-footer-message-to-16px.yml5
-rw-r--r--changelogs/unreleased/58482-update-airminc-clair-local-scan-to-2-0-6.yml5
-rw-r--r--changelogs/unreleased/58717-checkbox-cannot-be-checked-if-a-blockquote-is-above.yml5
-rw-r--r--changelogs/unreleased/58739-hashed-storage-prevent-a-migration-and-rollback-running-at-the-same-time.yml5
-rw-r--r--changelogs/unreleased/58751-fix-project-name-members-page.yml5
-rw-r--r--changelogs/unreleased/58781-silent-progress-in-auto-devops.yml5
-rw-r--r--changelogs/unreleased/58789-some-system-notes-on-issuable-are-folded-on-mobile.yml5
-rw-r--r--changelogs/unreleased/58793-fix-nav-links-archived-project.yml5
-rw-r--r--changelogs/unreleased/58797-broken-ui-on-a-closed-merge-request-from-a-deleted-source-project.yml5
-rw-r--r--changelogs/unreleased/58805-allow-incomplete-commit-data-to-be-fetched-from-collection.yml5
-rw-r--r--changelogs/unreleased/58835-button-run-pipeline.yml5
-rw-r--r--changelogs/unreleased/58839-automatically-set-prometheus-step-interval.yml5
-rw-r--r--changelogs/unreleased/58883-fix-fetching-comments.yml5
-rw-r--r--changelogs/unreleased/58889-spinners-are-active-prematurely-in-bitbucket-cloud-import.yml5
-rw-r--r--changelogs/unreleased/58933-broken-ui-on-commits-on-mobile.yml5
-rw-r--r--changelogs/unreleased/58971-sentry-api-keyerror.yml5
-rw-r--r--changelogs/unreleased/58981-migrate-clusters-tests-to-jest.yml5
-rw-r--r--changelogs/unreleased/59057-buttons-on-top-from-a-user-profile-page-on-mobile.yml5
-rw-r--r--changelogs/unreleased/59062-update-gitlab-markup-python-3.yml5
-rw-r--r--changelogs/unreleased/59079-fix-jupyter-render-loop.yml5
-rw-r--r--changelogs/unreleased/59117-inconsistent-hover-behavior-on-navbar-items.yml5
-rw-r--r--changelogs/unreleased/59131-set-the-size-of-instance-system-message-text-12px.yml5
-rw-r--r--changelogs/unreleased/59189-long-names-in-project-path-namespace-dropdown-breaks-past-container.yml5
-rw-r--r--changelogs/unreleased/59273-update-fugit.yml5
-rw-r--r--changelogs/unreleased/59296-add-filter-by-title-milestones-api.yml5
-rw-r--r--changelogs/unreleased/59324-queries-which-return-multiple-series-are-not-working-correctly.yml5
-rw-r--r--changelogs/unreleased/59352-fix-mr-discussion-expansion.yml5
-rw-r--r--changelogs/unreleased/59441-add-base-domain-to-cluster-api.yml5
-rw-r--r--changelogs/unreleased/59502-fix-breadcrumb-artifacts.yml5
-rw-r--r--changelogs/unreleased/59546-fix-error-handling-for-missing-domain.yml5
-rw-r--r--changelogs/unreleased/59621-order-labels-alphabetically-in-issue-boards.yml5
-rw-r--r--changelogs/unreleased/60006-add-touch-events-to-image-diff-26971.yml5
-rw-r--r--changelogs/unreleased/60068-avoid-null-domain-help-text.yml5
-rw-r--r--changelogs/unreleased/60116-fix-button-wrapping.yml5
-rw-r--r--changelogs/unreleased/60149-nameerror-uninitialized-constant-sentry-client-sentryerror.yml5
-rw-r--r--changelogs/unreleased/60241-merge-request-popover-doesn-t-go-away-on-mouse-leave.yml5
-rw-r--r--changelogs/unreleased/60304-long-file-names-in-mr-diffs-cause-horizontal-scrolling.yml5
-rw-r--r--changelogs/unreleased/MaxWinterstein-master-patch-23232.yml5
-rw-r--r--changelogs/unreleased/_acet-related-mrs-widget-rewrite.yml5
-rw-r--r--changelogs/unreleased/add-runner-access-level-registration.yml5
-rw-r--r--changelogs/unreleased/add_backtrace_to_kubernetes_log.yml5
-rw-r--r--changelogs/unreleased/allow-filtering-labels-by-a-single-character.yml5
-rw-r--r--changelogs/unreleased/allow-ref-name-caching-projects-controller.yml5
-rw-r--r--changelogs/unreleased/an-use-labkit.yml5
-rw-r--r--changelogs/unreleased/avoid_es_loading_project_ci_status.yml5
-rw-r--r--changelogs/unreleased/ce-10725-restructure-project-merge-request-settings-page.yml5
-rw-r--r--changelogs/unreleased/ce-56153-error-tracking-counts.yml5
-rw-r--r--changelogs/unreleased/ce-proj-settings-ok-avatar-only.yml5
-rw-r--r--changelogs/unreleased/ce-proj-settings-ok-mr-settings-only.yml5
-rw-r--r--changelogs/unreleased/check-mergeability-in-merge-to-ref-service.yml5
-rw-r--r--changelogs/unreleased/create-label-and-list-checkbox.yml5
-rw-r--r--changelogs/unreleased/delete-release-when-delete-tag.yml5
-rw-r--r--changelogs/unreleased/deploy-keys-ext.yml5
-rw-r--r--changelogs/unreleased/disallow-guests-to-access-releases.yml5
-rw-r--r--changelogs/unreleased/do-not-force-2fa.yml6
-rw-r--r--changelogs/unreleased/drop-usage-of-leagcy-artifacts.yml5
-rw-r--r--changelogs/unreleased/duplicate-related-mrs.yml5
-rw-r--r--changelogs/unreleased/ekigbo-extend-timezone-dropdown.yml5
-rw-r--r--changelogs/unreleased/expose-group-id-on-home-panel.yml5
-rw-r--r--changelogs/unreleased/extend-cte-optimisations-to-projects.yml5
-rw-r--r--changelogs/unreleased/feature-gb-serverless-switch-to-gitlabktl.yml5
-rw-r--r--changelogs/unreleased/feature-users-search-results.yml5
-rw-r--r--changelogs/unreleased/feature-webide_escaping.yml5
-rw-r--r--changelogs/unreleased/filter-merge-requests-by-target-branch.yml5
-rw-r--r--changelogs/unreleased/fix-UI-links-to-route-map-info.yml5
-rw-r--r--changelogs/unreleased/fix-container-scanning-on-k8s.yml5
-rw-r--r--changelogs/unreleased/fix-expand-full-file-on-image.yml5
-rw-r--r--changelogs/unreleased/fix-hidden-statistics.yml5
-rw-r--r--changelogs/unreleased/fix-ide-web-worker-relative-url.yml5
-rw-r--r--changelogs/unreleased/fix-include-ci-yaml.yml5
-rw-r--r--changelogs/unreleased/fix-issues-time-counter.yml5
-rw-r--r--changelogs/unreleased/fix-merge-request-relations-with-pipeline-on-mwps.yml5
-rw-r--r--changelogs/unreleased/fix-new-merge-request-diff-headers-sticky-position.yml5
-rw-r--r--changelogs/unreleased/fix-pipeline-entity.yml5
-rw-r--r--changelogs/unreleased/fix-review-app-env-url.yml5
-rw-r--r--changelogs/unreleased/fix-routes-n-plus-one-in-user-autocomplete.yml5
-rw-r--r--changelogs/unreleased/fix-transfer-group-possibilities.yml5
-rw-r--r--changelogs/unreleased/fixed-duplicated-large-text-on-diffs.yml5
-rw-r--r--changelogs/unreleased/fixed-web-ide-merge-request-review.yml5
-rw-r--r--changelogs/unreleased/gitaly-version-v1.29.0.yml5
-rw-r--r--changelogs/unreleased/gitaly-version-v1.32.0.yml5
-rw-r--r--changelogs/unreleased/gitaly-version-v1.33.0.yml5
-rw-r--r--changelogs/unreleased/gitlab-issue-54894.yml6
-rw-r--r--changelogs/unreleased/graphql-prometheus.yml5
-rw-r--r--changelogs/unreleased/gt-externalize-app-views-projects-pipelines.yml5
-rw-r--r--changelogs/unreleased/id-51433-sort-wiki-by-date.yml5
-rw-r--r--changelogs/unreleased/ide-fix-detect-mr-from-fork.yml5
-rw-r--r--changelogs/unreleased/issue_58547.yml5
-rw-r--r--changelogs/unreleased/jc-guard-against-empty-dereferenced_target.yml5
-rw-r--r--changelogs/unreleased/jc-upgrade-gitaly-1-34-0.yml5
-rw-r--r--changelogs/unreleased/k8s_new_deployment_labels.yml5
-rw-r--r--changelogs/unreleased/knative-prometheus.yml5
-rw-r--r--changelogs/unreleased/knative-update.yml5
-rw-r--r--changelogs/unreleased/kube_helm_auto_devops_213.yml5
-rw-r--r--changelogs/unreleased/limit-amount-of-created-pipelines.yml5
-rw-r--r--changelogs/unreleased/localize-notification-dropdown.yml5
-rw-r--r--changelogs/unreleased/markdown-autocomplete-escaping.yml5
-rw-r--r--changelogs/unreleased/minimized-multiple-queries-ce.yml5
-rw-r--r--changelogs/unreleased/move-allow-developers-to-create-projects-in-groups-to-core.yml5
-rw-r--r--changelogs/unreleased/nfriend-css-updates-for-gitlab-design-system-compliance.yml5
-rw-r--r--changelogs/unreleased/nfriend-update-job-detail-view-sidebar.yml5
-rw-r--r--changelogs/unreleased/nfriend-update-merge-request-widget-for-post-merge-pipelines.yml5
-rw-r--r--changelogs/unreleased/nfriend-update-merge-request-widget-pipeline-block.yml6
-rw-r--r--changelogs/unreleased/nfriend-update-pipeline-detail-view.yml5
-rw-r--r--changelogs/unreleased/nfriend-update-pipeline-list-view.yml5
-rw-r--r--changelogs/unreleased/only-counted-active-milestones-as-started.yml5
-rw-r--r--changelogs/unreleased/osw-multi-line-suggestions-creation-strategy.yml5
-rw-r--r--changelogs/unreleased/osw-multi-line-suggestions-parsing.yml5
-rw-r--r--changelogs/unreleased/osw-support-multi-line-suggestions.yml5
-rw-r--r--changelogs/unreleased/persist-fulll-ref-path-for-mr-pipelines.yml5
-rw-r--r--changelogs/unreleased/pravi-gitlab-ce-update-recaptcha.yml5
-rw-r--r--changelogs/unreleased/prevent-running-mr-pipelines-when-target-updated.yml5
-rw-r--r--changelogs/unreleased/related-mr-link-cutoff.yml5
-rw-r--r--changelogs/unreleased/remove-ci-charts-undescriptive-header.yml5
-rw-r--r--changelogs/unreleased/rename_auto_deploy_app_links.yml5
-rw-r--r--changelogs/unreleased/security-55503-fix-pdf-js-vulnerability.yml5
-rw-r--r--changelogs/unreleased/security-56224.yml5
-rw-r--r--changelogs/unreleased/security-56927-xss-resolve-conflicts-branch-name.yml5
-rw-r--r--changelogs/unreleased/security-exif-migration.yml5
-rw-r--r--changelogs/unreleased/security-id-potential-denial-languages.yml5
-rw-r--r--changelogs/unreleased/security-mass-assignment-on-project-update.yml5
-rw-r--r--changelogs/unreleased/sh-add-gitaly-duration-logs.yml5
-rw-r--r--changelogs/unreleased/sh-add-gitaly-ref-name-caching-tree-controller.yml5
-rw-r--r--changelogs/unreleased/sh-bump-ruby-required-version-check.yml5
-rw-r--r--changelogs/unreleased/sh-cache-pipeline-find-commits.yml5
-rw-r--r--changelogs/unreleased/sh-cache-root-ref-asymetrically.yml5
-rw-r--r--changelogs/unreleased/sh-clear-pipeline-status-cache-upon-destroy.yml5
-rw-r--r--changelogs/unreleased/sh-fix-gitaly-find-commit-caching.yml5
-rw-r--r--changelogs/unreleased/sh-fix-issue-59065.yml5
-rw-r--r--changelogs/unreleased/sh-fix-merge-requests-api-remove-branch-param.yml5
-rw-r--r--changelogs/unreleased/sh-fix-realtime-changes-with-reserved-words.yml5
-rw-r--r--changelogs/unreleased/sh-fix-ref-name-caching.yml5
-rw-r--r--changelogs/unreleased/sh-git-gc-after-initial-fetch.yml5
-rw-r--r--changelogs/unreleased/sh-improve-find-commit-caching.yml5
-rw-r--r--changelogs/unreleased/sh-reject-info-refs-head-requests.yml5
-rw-r--r--changelogs/unreleased/sh-skip-sti-tables-reltuples.yml5
-rw-r--r--changelogs/unreleased/sh-update-rails-5-0-7-2.yml5
-rw-r--r--changelogs/unreleased/stop-signing-avatar-paths.yml5
-rw-r--r--changelogs/unreleased/tpresa-add-highest-role-to-user.yml5
-rw-r--r--changelogs/unreleased/update-gitlab-runner-helm-chart-to-0-3-0.yml5
-rw-r--r--changelogs/unreleased/update-gitlab-shell.yml5
-rw-r--r--changelogs/unreleased/update-rack-oauth2.yml5
-rw-r--r--changelogs/unreleased/update-workhorse-8-5-1.yml5
-rw-r--r--changelogs/unreleased/use-only-all-pipelines.yml5
-rw-r--r--changelogs/unreleased/use-untrusted-regexp.yml5
-rw-r--r--changelogs/unreleased/winh-toggle-comment-draft.yml5
-rw-r--r--changelogs/unreleased/xanf-gitlab-ce-add-template-link.yml5
-rw-r--r--changelogs/unreleased/xanf-gitlab-ce-move-project-tags.yml5
-rw-r--r--changelogs/unreleased/xanf-gitlab-ce-transfer-disables-js.yml5
-rw-r--r--config/initializers/lograge.rb2
-rw-r--r--config/initializers/peek.rb2
-rw-r--r--config/initializers/tracing.rb16
-rw-r--r--config/prometheus/common_metrics.yml161
-rw-r--r--db/importers/common_metrics_importer.rb26
-rw-r--r--doc/api/projects.md7
-rw-r--r--doc/api/runners.md1
-rw-r--r--doc/ci/examples/code_quality.md46
-rw-r--r--doc/ci/merge_request_pipelines/index.md2
-rw-r--r--doc/development/documentation/index.md4
-rw-r--r--doc/development/documentation/styleguide.md77
-rw-r--r--doc/topics/autodevops/index.md8
-rw-r--r--doc/user/admin_area/settings/external_authorization.md112
-rw-r--r--doc/user/admin_area/settings/img/classification_label_on_project_page.pngbin0 -> 19568 bytes
-rw-r--r--doc/user/admin_area/settings/img/external_authorization_service_settings.pngbin0 -> 74753 bytes
-rw-r--r--doc/user/discussions/index.md16
-rw-r--r--doc/user/profile/account/delete_account.md2
-rw-r--r--doc/user/project/clusters/index.md40
-rw-r--r--doc/user/project/clusters/serverless/index.md15
-rw-r--r--lib/api/entities.rb10
-rw-r--r--lib/api/runner.rb4
-rw-r--r--lib/gitlab/gitaly_client.rb6
-rw-r--r--lib/gitlab/grape_logging/loggers/correlation_id_logger.rb2
-rw-r--r--lib/gitlab/graphql/authorize.rb2
-rw-r--r--lib/gitlab/graphql/authorize/authorize_field_service.rb86
-rw-r--r--lib/gitlab/graphql/connections/keyset_connection.rb16
-rw-r--r--lib/gitlab/graphql/errors.rb1
-rw-r--r--lib/gitlab/json_logger.rb2
-rw-r--r--lib/gitlab/middleware/correlation_id.rb2
-rw-r--r--lib/gitlab/sentry.rb2
-rw-r--r--lib/gitlab/sidekiq_middleware/correlation_injector.rb4
-rw-r--r--lib/gitlab/sidekiq_middleware/correlation_logger.rb4
-rw-r--r--lib/gitlab/tracing/common.rb69
-rw-r--r--lib/gitlab/tracing/factory.rb61
-rw-r--r--lib/gitlab/tracing/grpc_interceptor.rb54
-rw-r--r--lib/gitlab/tracing/jaeger_factory.rb97
-rw-r--r--lib/gitlab/tracing/rack_middleware.rb46
-rw-r--r--lib/gitlab/tracing/rails/action_view_subscriber.rb75
-rw-r--r--lib/gitlab/tracing/rails/active_record_subscriber.rb49
-rw-r--r--lib/gitlab/tracing/rails/rails_common.rb24
-rw-r--r--lib/gitlab/tracing/sidekiq/client_middleware.rb26
-rw-r--r--lib/gitlab/tracing/sidekiq/server_middleware.rb26
-rw-r--r--lib/gitlab/tracing/sidekiq/sidekiq_common.rb22
-rw-r--r--lib/peek/views/tracing.rb6
-rw-r--r--lib/system_check/app/ruby_version_check.rb2
-rw-r--r--locale/gitlab.pot98
-rw-r--r--qa/qa/page/component/note.rb2
-rw-r--r--spec/controllers/application_controller_spec.rb2
-rw-r--r--spec/db/importers/common_metrics_importer_spec.rb44
-rw-r--r--spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb25
-rw-r--r--spec/frontend/clusters/components/application_row_spec.js28
-rw-r--r--spec/frontend/clusters/stores/clusters_store_spec.js23
-rw-r--r--spec/frontend/gfm_auto_complete_spec.js21
-rw-r--r--spec/frontend/notes/components/discussion_actions_spec.js104
-rw-r--r--spec/frontend/pages/admin/abuse_reports/abuse_reports_spec.js3
-rw-r--r--spec/graphql/features/authorization_spec.rb77
-rw-r--r--spec/graphql/gitlab_schema_spec.rb2
-rw-r--r--spec/javascripts/boards/board_list_common_spec.js58
-rw-r--r--spec/javascripts/boards/board_list_spec.js51
-rw-r--r--spec/javascripts/boards/issue_card_spec.js6
-rw-r--r--spec/javascripts/monitoring/monitoring_store_spec.js24
-rw-r--r--spec/lib/gitlab/correlation_id_spec.rb77
-rw-r--r--spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb130
-rw-r--r--spec/lib/gitlab/graphql/connections/keyset_connection_spec.rb5
-rw-r--r--spec/lib/gitlab/json_logger_spec.rb2
-rw-r--r--spec/lib/gitlab/sentry_spec.rb4
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/correlation_injector_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/correlation_logger_spec.rb2
-rw-r--r--spec/lib/gitlab/tracing/factory_spec.rb43
-rw-r--r--spec/lib/gitlab/tracing/grpc_interceptor_spec.rb47
-rw-r--r--spec/lib/gitlab/tracing/jaeger_factory_spec.rb71
-rw-r--r--spec/lib/gitlab/tracing/rack_middleware_spec.rb62
-rw-r--r--spec/lib/gitlab/tracing/rails/action_view_subscriber_spec.rb147
-rw-r--r--spec/lib/gitlab/tracing/rails/active_record_subscriber_spec.rb73
-rw-r--r--spec/lib/gitlab/tracing/sidekiq/client_middleware_spec.rb43
-rw-r--r--spec/lib/gitlab/tracing/sidekiq/server_middleware_spec.rb43
-rw-r--r--spec/models/ci/build_spec.rb52
-rw-r--r--spec/models/ci/job_artifact_spec.rb44
-rw-r--r--spec/models/namespace_spec.rb22
-rw-r--r--spec/requests/api/graphql/project/issues_spec.rb28
-rw-r--r--spec/requests/api/helpers_spec.rb2
-rw-r--r--spec/requests/api/projects_spec.rb36
-rw-r--r--spec/requests/api/runner_spec.rb26
-rw-r--r--spec/spec_helper.rb1
-rw-r--r--spec/support/helpers/wait_for_requests.rb14
-rw-r--r--spec/support/helpers/wait_helpers.rb20
-rw-r--r--spec/support/shared_examples/models/update_project_statistics_spec.rb76
-rw-r--r--spec/views/shared/_label_row.html.haml.rb32
353 files changed, 1855 insertions, 3239 deletions
diff --git a/.gitlab/ci/reports.gitlab-ci.yml b/.gitlab/ci/reports.gitlab-ci.yml
index df1fec61c25..8bcf8d4cb48 100644
--- a/.gitlab/ci/reports.gitlab-ci.yml
+++ b/.gitlab/ci/reports.gitlab-ci.yml
@@ -1,5 +1,5 @@
include:
- - local: /lib/gitlab/ci/templates/Code-Quality.gitlab-ci.yml
+ - template: Code-Quality.gitlab-ci.yml
code_quality:
extends: .dedicated-no-docs-no-db-pull-cache-job
diff --git a/.gitlab/ci/review.gitlab-ci.yml b/.gitlab/ci/review.gitlab-ci.yml
index bec71a83945..dee72930a28 100644
--- a/.gitlab/ci/review.gitlab-ci.yml
+++ b/.gitlab/ci/review.gitlab-ci.yml
@@ -83,7 +83,6 @@ schedule:review-build-cng:
<<: *review-schedules-only
<<: *review-build-cng-base
-
.review-deploy-base: &review-deploy-base
<<: *review-base
allow_failure: true
@@ -176,6 +175,7 @@ review-performance:
<<: *review-performance-base
review-stop:
+ <<: *review-base
extends: .single-script-job-dedicated-runner
image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-charts-build-base
allow_failure: true
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 41506746c98..c512585ff6a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,237 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
+## 11.10.0 (2019-04-22)
+
+### Security (9 changes)
+
+- Update Rails to 5.0.7.2. !27022
+- Disallow guest users from accessing Releases.
+- Return cached languages if they've been detected before.
+- Added rake task for removing EXIF data from existing uploads.
+- Disallow updating namespace when updating a project.
+- Fix XSS in resolve conflicts form.
+- Hide "related branches" when user does not have permission.
+- Fix PDF.js vulnerability.
+- Use UntrustedRegexp for matching refs policy.
+
+### Fixed (81 changes, 21 of them are from the community)
+
+- Update `border-radius` of form controls and remove extra space above page titles. !24497
+- Disallow reopening of a locked merge request. !24882 (Jan Beckmann)
+- Align EmailValidator to validate_email gem implementation. !24971 (Horatiu Eugen Vlad)
+- add a uniq constraints on issues and mrs labels. !25435 (Antoine Huret)
+- Display draft when toggling replies. !25563
+- Fix markdown table header and table content borders. !25666
+- Fix authorized application count. !25715 (moyuru)
+- Added "Add List" checkbox to create label dropdown to make creation of list optional. !25716 (Tucker Chapman)
+- Makes emoji picker full width on mobile. !25883 (Jacopo Beschi @jacopo-beschi)
+- Don't cutoff letters in MR and Issue links. !25910 (gfyoung)
+- Fix unwanted character replacement on project members page caused by usage of sanitize function. !25946 (Elias Werberich)
+- Fix UI for closed MR when source project is removed. !25967 (Takuya Noguchi)
+- Keep inline as much as possible in system notes on issuable. !25968 (Takuya Noguchi)
+- Fixes long review app subdomains. !25990 (walkafwalka)
+- Fix counting of groups in admin dashboard. !26009
+- Disable inaccessible navigation links upon archiving a project. !26020 (Elias Werberich)
+- Fixed - Create project label window is cut off at the bottom. !26049
+- Fix error shown when loading links to specific comments. !26092
+- Fix group transfer selection possibilities. !26123 (Peter Marko)
+- Fix UI layout on Commits on mobile. !26133 (Takuya Noguchi)
+- Fix continuous bitbucket import loading spinner. !26175
+- Resolves Branch name is lost if I change commit mode in Web IDE. !26180
+- Fix removing remote mirror failure which leaves unnecessary refs behind. !26213
+- Fix Error 500 when user commits Wiki page with no commit message. !26247
+- Handle missing keys in sentry api response. !26264
+- Implemented whitespace-trimming for file names in Web IDE. !26270
+- Fix misalignment of group overview page buttons. !26292
+- Reject HEAD requests to info/refs endpoint. !26334
+- Prevent namespace dropdown in new project form from exceeding container. !26343
+- Fix hover animation consistency in top navbar items. !26345
+- Exclude system notes from commits in merge request discussions. !26396
+- Resolve Code in other column of side-by-side diff is highlighted when selecting code on one side. !26423
+- Prevent fade out transition on loading-button component. !26428
+- Fix merge commits being used as default squash commit messages. !26445
+- Expand resolved discussion when linking to a comment in the discussion. !26483
+- Show statistics also when repository is disabled. !26509 (Peter Marko)
+- Fix multiple series queries on metrics dashboard. !26514
+- Releases will now be automatically deleted when deleting corresponding tag. !26530
+- Make stylistic improvements to diff nav header. !26557
+- Clear pipeline status cache after destruction of pipeline. !26575
+- Update fugit which fixes a potential infinite loop. !26579
+- Fixes job link in artifacts page breadcrumb. !26592
+- Fix quick actions add label name middle word overlaps. !26602 (Jacopo Beschi @jacopo-beschi)
+- Fix Auto DevOps missing domain error handling. !26627
+- Fix jupyter rendering bug that ended in an infinite loop. !26656 (ROSPARS Benoit)
+- Use a fixed git abbrev parameter when we fetch a git revision. !26707
+- Enabled text selection highlighting in diffs in Web IDE. !26721 (Isaac Smith)
+- Remove `path` and `branch` labels from metrics. !26744
+- Resolve "Hide Kubernetes cluster warning if project has cluster related". !26749
+- Fix long label overflow on metrics dashboard. !26775
+- Group transfer now properly redirects to edit on failure. !26837
+- Only execute system hooks once when pushing tags. !26888
+- Fix UI anchor links after docs refactor. !26890
+- Fix MWPS does not work for merge request pipelines. !26906
+- Create pipelines for merge requests only when source branch is updated. !26921
+- Fix notfication emails having wrong encoding. !26931
+- Allow task lists that follow a blockquote to work correctly. !26937
+- Fix image diff swipe view on commit and compare pages. !26968 (ftab)
+- Fix IDE detection of MR from fork with same branch name. !26986
+- Fix single string values for the 'include' keyword validation of gitlab-ci.yml. !26998 (Paul Bonaud (@paulrbr))
+- Do not display Ingress IP help text when there isn’t an Ingress IP assigned. !27057
+- Fix real-time updates for projects that contain a reserved word. !27060
+- Remove duplicates from issue related merge requests. !27067
+- Add to white-space nowrap to all buttons. !27069
+- Handle possible HTTP exception for Sentry client. !27080
+- Guard against nil dereferenced_target. !27192
+- Update GitLab Workhorse to v8.5.1. !27217
+- Fix long file header names bug in diffs. !27233
+- Always return the deployment in the UpdateDeploymentService#execute method. !27322
+- Fix remove_source_branch merge request API handling. !27392
+- Fixed bug with hashes in urls in WebIDE. !54376 (Kieran Andrews)
+- Fix bug where MR popover doesn't go away on mouse leave.
+- Only consider active milestones when using the special Started milestone filter.
+- Scroll to diff file content when clicking on file header name and it is not a link to other page.
+- Remove non-functional add issue button on welcome list.
+- Fixed expand full file button showing on images.
+- Fixed Web IDE web workers not working with relative URLs.
+- Fixed Web IDE not loading merge request files.
+- Fixed duplicated diff too large error message.
+- Fixed sticky headers in merge request creation diffs.
+- Fix bug when reopening milestone from index page.
+
+### Deprecated (1 change)
+
+- Allow to use untrusted Regexp via feature flag. !26905
+
+### Changed (35 changes, 4 of them are from the community)
+
+- Create MR pipelines with `refs/merge-requests/:iid/head`. !25504
+- Create Kubernetes resources for projects when their deployment jobs run. !25586
+- Remove unnecessary folder prefix from environment name. !25600
+- Update deploy boards to additionally select on "app.gitlab.com" annotations. !25623
+- Allow failed custom hook script errors to safely appear in GitLab UI by filtering error messages by the prefix GL-HOOK-ERR:. !25625
+- Add link on two-factor authorization settings page to leave group that enforces two-factor authorization. !25731
+- Reduce height of instance system header and footer. !25752
+- Unify behaviour of 'Copy commit SHA to clipboard' to use full commit SHA. !25829 (Max Winterstein)
+- Show loading spinner while Ingress/Knative IP is being assigned. !25912
+- Hashed Storage: Prevent a migration and rollback running at the same time. !25976
+- Make time counters show 'just now' for everything under one minute. !25992 (Sergiu Marton)
+- Allow filtering labels list by one or two characters. !26012
+- Implements the creation strategy for multi-line suggestions. !26057
+- Automate base domain help text on Clusters page. !26124
+- Set user.name limit to 128 characters. !26146
+- Update gitlab-markup to 1.7.0 which requies python3. !26246
+- Update system message banner font size to 12px. !26293
+- Extend timezone dropdown. !26311
+- Upgrade to Gitaly v1.29.0. !26406
+- Automatically set Prometheus step interval. !26441
+- Knative version bump 0.2.2 -> 0.3.0. !26459 (Chris Baumbauer)
+- Display cluster form validation error messages inline. !26502
+- Split Auto-DevOps.gitlab-ci.yml into reusable templates. !26520
+- Update spinners in group list component. !26572
+- Allow removing last owner from subgroup if parent group has owners. !26718
+- Check mergeability in MergeToRefService. !26757
+- Show download diff links for closed MRs. !26772
+- Fix Container Scanning in Kubernetes Runners. !26793
+- Move "Authorize project access with external service" to Core. !26823
+- Localize notifications dropdown. !26844
+- Order labels alphabetically in issue boards. !26927
+- Upgrade to Gitaly v1.32.0. !26989
+- Upgrade to Gitaly v1.33.0. !27065
+- collapse file tree by default if the merge request changes only one file. (Riccardo Padovani <riccardo@rpadovani.com>)
+- Removes the undescriptive CI Charts header.
+
+### Performance (17 changes)
+
+- Drop legacy artifacts usage as there are no leftovers. !24294
+- Cache Repository#root_ref within a request. !25903
+- Allow ref name caching CommitService#find_commit. !26248
+- Avoid loading pipeline status in project search. !26342
+- Fix some N+1s in loading routes and counting members for groups in @-autocomplete. !26491
+- GitHub import: Run housekeeping after initial import. !26600
+- Add initial complexity limits to GraphQL queries. !26629
+- Cache FindCommit results in pipelines view. !26776
+- Fix and expand Gitaly FindCommit caching. !27018
+- Enable FindCommit caching for project and commits pages. !27048
+- Expand FindCommit caching to blob and refs. !27084
+- Enable Gitaly FindCommit caching for TreeController. !27100
+- Improve performance of PR import. !27121
+- Process at most 4 pipelines during push. !27205
+- Disable method instrumentation for diffs. !27235
+- Speed up filtering issues in a project when searching.
+- Speed up generation of avatar URLs when using object storage.
+
+### Added (35 changes, 6 of them are from the community)
+
+- Add users search results to global search. !21197 (Alexis Reigel)
+- Add target branch filter to merge requests search bar. !24380 (Hiroyuki Sato)
+- Add Knative metrics to Prometheus. !24663 (Chris Baumbauer <cab@cabnetworks.net>)
+- Support multi-line suggestions. !25211
+- Allow to sort wiki pages by date and title. !25365
+- Allow external diffs to be used conditionally. !25432
+- Add usage counts for error tracking feature. !25472
+- Enable/disable Auto DevOps at the Group level. !25533
+- Update pipeline list view to accommodate post-merge pipeline information. !25690
+- GraphQL Types can be made to always authorize access to resources of that Type. !25724
+- Update clair-local-scan to 2.0.6. !25743 (Takuya Noguchi)
+- Update pipeline block on merge request page to accommodate post-merge pipeline information. !25745
+- Support multiple queries per chart on metrics dash. !25758
+- Update pipeline detail view to accommodate post-merge pipelines. !25775
+- Update job detail sidebar to accommodate post-merge pipeline information. !25777
+- Add merge request pipeline flag to pipeline entity. !25846
+- Expose group id on home panel. !25897 (Peter Marko)
+- Move allow developers to create projects in groups to Core. !25975
+- Add two new warning messages to the MR widget about merge request pipelines. !25983
+- Support installing Group runner on group-level cluster. !26260
+- Improve the Knative installation on Clusters. !26339
+- Show error when namespace/svc account missing. !26362
+- Add select by title to milestones API. !26573
+- Implemented support for creation of new files from URL in Web IDE. !26622
+- Add control for masking variable values in runner logs. !26751
+- Allow merge requests to be created via git push options. !26752
+- Create a shortcut for a new MR in the Web IDE. !26792
+- Allow reactive caching to be used in services. !26839
+- Add a Prometheus API per environment. !26841
+- Allow merge requests to be set to merge when pipeline succeeds via git push options. !26842
+- Use gitlabktl to build and deploy GitLab Serverless Functions. !26926
+- Make touch events work on image diff swipe view and onion skin. !26971 (ftab)
+- Add extended merge request tooltip.
+- Added prometheus monitoring to GraphQL.
+- Adding highest role property to admin's user details page.
+
+### Other (29 changes, 6 of them are from the community)
+
+- Update rack-oauth2 1.2.1 -> 1.9.3. !17868
+- Merge the gitlab-shell "gitlab-keys" functionality into GitLab CE. !25598
+- Refactor all_pipelines in Merge request. !25676
+- Show error backtrace when logging errors to kubernetes.log. !25726
+- Apply recaptcha API change in 4.0. !25921 (Praveen Arimbrathodiyil)
+- Remove fake repository_path response. !25942 (Fabio Papa)
+- Use curl silent/show-error options on Auto DevOps. !25954 (Takuya Noguchi)
+- Explicitly set master_auth setting to enable basic auth and client certificate for new GKE clusters. !26018
+- Project: Improve empty repository state UI. !26024
+- Externalize strings from `/app/views/projects/pipelines`. !26035 (George Tsiolis)
+- Prepare multi-line suggestions for rendering in Markdown. !26107
+- Improve mobile UI on User Profile page. !26240 (Takuya Noguchi)
+- Update GitLab Runner Helm Chart to 0.3.0/11.9.0. !26467
+- Improve project merge request settings. !26495
+- Bump kubectl to 1.11.9 and Helm to 2.13.1 in Auto-DevOps.gitlab-ci.yml. !26534
+- Upgrade bootstrap_form Gem. !26568
+- Add API access check to Graphql. !26570
+- Change project avatar remove button to a link. !26589
+- Log Gitaly RPC duration to api_json.log and production_json.log. !26652
+- Add cluster domain to Project Cluster API. !26735
+- Move project tags to separate line. !26797
+- Changed button label at /pipelines/new. !26893 (antfobe,leonardofl)
+- Update GitLab Shell to v9.0.0. !27002
+- Migrate clusters tests to jest. !27013
+- Rewrite related MRs widget with Vue. !27027
+- Restore HipChat project service. !27172
+- Externalize admin deploy keys strings.
+- Removes EE differences for environments_table.vue.
+- Removes EE differences for environment_item.vue.
+
+
## 11.9.8 (2019-04-11)
### Deprecated (1 change)
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 7aa332e4163..2b17ffd5042 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-1.33.0
+1.34.0
diff --git a/Gemfile b/Gemfile
index 50099f5a3b1..eaaf8125009 100644
--- a/Gemfile
+++ b/Gemfile
@@ -274,6 +274,9 @@ gem 'sentry-raven', '~> 2.7'
gem 'premailer-rails', '~> 1.9.7'
+# LabKit: Tracing and Correlation
+gem 'gitlab-labkit', '~> 0.1.2'
+
# I18n
gem 'ruby_parser', '~> 3.8', require: false
gem 'rails-i18n', '~> 5.1'
@@ -301,12 +304,6 @@ group :metrics do
gem 'raindrops', '~> 0.18'
end
-group :tracing do
- # OpenTracing
- gem 'opentracing', '~> 0.4.3'
- gem 'jaeger-client', '~> 0.10.0'
-end
-
group :development do
gem 'foreman', '~> 0.84.0'
gem 'brakeman', '~> 4.2', require: false
diff --git a/Gemfile.lock b/Gemfile.lock
index 95c377e2725..ba4418cd8b3 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -286,6 +286,12 @@ GEM
github-markup (1.7.0)
gitlab-default_value_for (3.1.1)
activerecord (>= 3.2.0, < 6.0)
+ gitlab-labkit (0.1.2)
+ actionpack (~> 5)
+ activesupport (~> 5)
+ grpc (~> 1.15)
+ jaeger-client (~> 0.10)
+ opentracing (~> 0.4)
gitlab-markup (1.7.0)
gitlab-sidekiq-fetcher (0.4.0)
sidekiq (~> 5)
@@ -571,7 +577,7 @@ GEM
validate_email
validate_url
webfinger (>= 1.0.1)
- opentracing (0.4.3)
+ opentracing (0.5.0)
optimist (3.0.0)
org-ruby (0.9.12)
rubypants (~> 0.2)
@@ -1050,6 +1056,7 @@ DEPENDENCIES
gitaly-proto (~> 1.19.0)
github-markup (~> 1.7.0)
gitlab-default_value_for (~> 3.1.1)
+ gitlab-labkit (~> 0.1.2)
gitlab-markup (~> 1.7.0)
gitlab-sidekiq-fetcher (~> 0.4.0)
gitlab-styles (~> 2.5)
@@ -1076,7 +1083,6 @@ DEPENDENCIES
httparty (~> 0.16.4)
icalendar
influxdb (~> 0.2)
- jaeger-client (~> 0.10.0)
jira-ruby (~> 1.4)
js_regex (~> 3.1)
json-schema (~> 2.8.0)
@@ -1117,7 +1123,6 @@ DEPENDENCIES
omniauth-twitter (~> 1.4)
omniauth-ultraauth (~> 0.0.1)
omniauth_crowd (~> 2.2.0)
- opentracing (~> 0.4.3)
org-ruby (~> 0.9.12)
peek (~> 1.0.1)
peek-gc (~> 0.0.2)
diff --git a/VERSION b/VERSION
index 1a954017bf3..fd59314f1ad 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-11.10.0-pre
+11.11.0-pre
diff --git a/app/assets/javascripts/boards/components/board_blank_state.vue b/app/assets/javascripts/boards/components/board_blank_state.vue
index 667eea17d44..47a46502bff 100644
--- a/app/assets/javascripts/boards/components/board_blank_state.vue
+++ b/app/assets/javascripts/boards/components/board_blank_state.vue
@@ -60,11 +60,15 @@ export default {
</script>
<template>
- <div class="board-blank-state">
+ <div class="board-blank-state p-3">
<p>Add the following default lists to your Issue Board with one click:</p>
- <ul class="board-blank-state-list">
+ <ul class="list-unstyled board-blank-state-list">
<li v-for="(label, index) in predefinedLabels" :key="index">
- <span :style="{ backgroundColor: label.color }" class="label-color"> </span>
+ <span
+ :style="{ backgroundColor: label.color }"
+ class="label-color position-relative d-inline-block rounded"
+ >
+ </span>
{{ label.title }}
</li>
</ul>
diff --git a/app/assets/javascripts/boards/components/board_card.vue b/app/assets/javascripts/boards/components/board_card.vue
index f569322ab70..c9effa0639b 100644
--- a/app/assets/javascripts/boards/components/board_card.vue
+++ b/app/assets/javascripts/boards/components/board_card.vue
@@ -83,7 +83,7 @@ export default {
}"
:index="index"
:data-issue-id="issue.id"
- class="board-card"
+ class="board-card position-relative p-3 rounded"
@mousedown="mouseDown"
@mousemove="mouseMove"
@mouseup="showIssue($event)"
diff --git a/app/assets/javascripts/boards/components/board_list.vue b/app/assets/javascripts/boards/components/board_list.vue
index f3f341ece5c..c9972d051aa 100644
--- a/app/assets/javascripts/boards/components/board_list.vue
+++ b/app/assets/javascripts/boards/components/board_list.vue
@@ -221,7 +221,10 @@ export default {
</script>
<template>
- <div class="board-list-component">
+ <div
+ :class="{ 'd-none': !list.isExpanded, 'd-flex flex-column': list.isExpanded }"
+ class="board-list-component position-relative h-100"
+ >
<div v-if="loading" class="board-list-loading text-center" aria-label="Loading issues">
<gl-loading-icon />
</div>
@@ -236,7 +239,7 @@ export default {
:data-board="list.id"
:data-board-type="list.type"
:class="{ 'is-smaller': showIssueForm }"
- class="board-list js-board-list"
+ class="board-list w-100 h-100 list-unstyled mb-0 p-1 js-board-list"
>
<board-card
v-for="(issue, index) in issues"
diff --git a/app/assets/javascripts/boards/components/board_new_issue.vue b/app/assets/javascripts/boards/components/board_new_issue.vue
index 28d96dab605..70daba352f9 100644
--- a/app/assets/javascripts/boards/components/board_new_issue.vue
+++ b/app/assets/javascripts/boards/components/board_new_issue.vue
@@ -95,7 +95,7 @@ export default {
<template>
<div class="board-new-issue-form">
- <div class="board-card">
+ <div class="board-card position-relative p-3 rounded">
<form @submit="submit($event)">
<div v-if="error" class="flash-container">
<div class="flash-alert">An error occurred. Please try again.</div>
diff --git a/app/assets/javascripts/boards/components/issue_card_inner.vue b/app/assets/javascripts/boards/components/issue_card_inner.vue
index be0de63e772..6aa689b4056 100644
--- a/app/assets/javascripts/boards/components/issue_card_inner.vue
+++ b/app/assets/javascripts/boards/components/issue_card_inner.vue
@@ -4,6 +4,7 @@ import { GlTooltipDirective } from '@gitlab/ui';
import { sprintf, __ } from '~/locale';
import Icon from '~/vue_shared/components/icon.vue';
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue';
+import issueCardInner from 'ee_else_ce/boards/mixins/issue_card_inner';
import UserAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
import eventHub from '../eventhub';
import IssueDueDate from './issue_due_date.vue';
@@ -19,11 +20,13 @@ export default {
TooltipOnTruncate,
IssueDueDate,
IssueTimeEstimate,
+ IssueCardWeight: () => import('ee_component/boards/components/issue_card_weight.vue'),
IssueCardInnerScopedLabel,
},
directives: {
GlTooltip: GlTooltipDirective,
},
+ mixins: [issueCardInner],
props: {
issue: {
type: Object,
@@ -135,14 +138,6 @@ export default {
this.applyFilter(filter);
},
- filterByWeight(weight) {
- if (!this.updateFilters) return;
-
- const issueWeight = encodeURIComponent(weight);
- const filter = `weight=${issueWeight}`;
-
- this.applyFilter(filter);
- },
applyFilter(filter) {
const filterPath = boardsStore.filter.path.split('&');
const filterIndex = filterPath.indexOf(filter);
@@ -173,7 +168,7 @@ export default {
</script>
<template>
<div>
- <div class="board-card-header">
+ <div class="d-flex board-card-header">
<h4 class="board-card-title append-bottom-0 prepend-top-0">
<icon
v-if="issue.confidential"
@@ -214,11 +209,11 @@ export default {
</div>
<div class="board-card-footer d-flex justify-content-between align-items-end">
<div
- class="d-flex align-items-start flex-wrap-reverse board-card-number-container js-board-card-number-container"
+ class="d-flex align-items-start flex-wrap-reverse board-card-number-container overflow-hidden js-board-card-number-container"
>
<span
v-if="issue.referencePath"
- class="board-card-number d-flex append-right-8 prepend-top-8"
+ class="board-card-number overflow-hidden d-flex append-right-8 prepend-top-8"
>
<tooltip-on-truncate
v-if="issueReferencePath"
@@ -232,10 +227,14 @@ export default {
<issue-due-date v-if="issue.dueDate" :date="issue.dueDate" /><issue-time-estimate
v-if="issue.timeEstimate"
:estimate="issue.timeEstimate"
+ /><issue-card-weight
+ v-if="issue.weight"
+ :weight="issue.weight"
+ @click="filterByWeight(issue.weight)"
/>
</span>
</div>
- <div class="board-card-assignee">
+ <div class="board-card-assignee d-flex">
<user-avatar-link
v-for="(assignee, index) in issue.assignees"
v-if="shouldRenderAssignee(index)"
diff --git a/app/assets/javascripts/boards/components/issue_due_date.vue b/app/assets/javascripts/boards/components/issue_due_date.vue
index 9bc66978198..3bc7f13a9e6 100644
--- a/app/assets/javascripts/boards/components/issue_due_date.vue
+++ b/app/assets/javascripts/boards/components/issue_due_date.vue
@@ -82,7 +82,11 @@ export default {
<template>
<span>
<span ref="issueDueDate" :class="cssClass" class="board-card-info card-number">
- <icon :class="{ 'text-danger': isPastDue, 'board-card-info-icon': true }" name="calendar" />
+ <icon
+ :class="{ 'text-danger': isPastDue }"
+ class="board-card-info-icon align-top"
+ name="calendar"
+ />
<time :class="{ 'text-danger': isPastDue }" datetime="date" class="board-card-info-text">{{
body
}}</time>
diff --git a/app/assets/javascripts/boards/components/issue_time_estimate.vue b/app/assets/javascripts/boards/components/issue_time_estimate.vue
index 5acc3025b2c..98c1d29db16 100644
--- a/app/assets/javascripts/boards/components/issue_time_estimate.vue
+++ b/app/assets/javascripts/boards/components/issue_time_estimate.vue
@@ -28,7 +28,7 @@ export default {
<template>
<span>
<span ref="issueTimeEstimate" class="board-card-info card-number">
- <icon name="hourglass" css-classes="board-card-info-icon" /><time
+ <icon name="hourglass" css-classes="board-card-info-icon align-top" /><time
class="board-card-info-text"
>{{ timeEstimate }}</time
>
diff --git a/app/assets/javascripts/boards/components/modal/empty_state.vue b/app/assets/javascripts/boards/components/modal/empty_state.vue
index 2a0008467c4..091700de93f 100644
--- a/app/assets/javascripts/boards/components/modal/empty_state.vue
+++ b/app/assets/javascripts/boards/components/modal/empty_state.vue
@@ -42,8 +42,8 @@ export default {
</script>
<template>
- <section class="empty-state">
- <div class="row">
+ <section class="empty-state d-flex mt-0 h-100">
+ <div class="row w-100 my-auto mx-0">
<div class="col-12 col-md-6 order-md-last">
<aside class="svg-content d-none d-md-block"><img :src="emptyStateSvg" /></aside>
</div>
diff --git a/app/assets/javascripts/boards/components/modal/header.vue b/app/assets/javascripts/boards/components/modal/header.vue
index 1f0961e02d8..1cfa6d39362 100644
--- a/app/assets/javascripts/boards/components/modal/header.vue
+++ b/app/assets/javascripts/boards/components/modal/header.vue
@@ -50,8 +50,8 @@ export default {
</script>
<template>
<div>
- <header class="add-issues-header form-actions">
- <h2>
+ <header class="add-issues-header border-top-0 form-actions">
+ <h2 class="m-0">
Add issues
<button
type="button"
@@ -65,7 +65,7 @@ export default {
</h2>
</header>
<modal-tabs v-if="!loading && issuesCount > 0" />
- <div v-if="showSearch" class="add-issues-search append-bottom-10">
+ <div v-if="showSearch" class="d-flex append-bottom-10">
<modal-filters :store="filter" />
<button
ref="selectAllBtn"
diff --git a/app/assets/javascripts/boards/components/modal/index.vue b/app/assets/javascripts/boards/components/modal/index.vue
index 1e5761cf268..8e09e265cfb 100644
--- a/app/assets/javascripts/boards/components/modal/index.vue
+++ b/app/assets/javascripts/boards/components/modal/index.vue
@@ -143,8 +143,11 @@ export default {
};
</script>
<template>
- <div v-if="showAddIssuesModal" class="add-issues-modal">
- <div class="add-issues-container">
+ <div
+ v-if="showAddIssuesModal"
+ class="add-issues-modal d-flex position-fixed position-top-0 position-bottom-0 position-left-0 position-right-0 h-100"
+ >
+ <div class="add-issues-container d-flex flex-column m-auto rounded">
<modal-header
:project-id="projectId"
:milestone-path="milestonePath"
@@ -161,8 +164,10 @@ export default {
:new-issue-path="newIssuePath"
:empty-state-svg="emptyStateSvg"
/>
- <section v-if="loading || filterLoading" class="add-issues-list text-center">
- <div class="add-issues-list-loading"><gl-loading-icon /></div>
+ <section v-if="loading || filterLoading" class="add-issues-list d-flex h-100 text-center">
+ <div class="add-issues-list-loading w-100 align-self-center">
+ <gl-loading-icon size="md" />
+ </div>
</section>
<modal-footer />
</div>
diff --git a/app/assets/javascripts/boards/components/modal/list.vue b/app/assets/javascripts/boards/components/modal/list.vue
index e9ed2de859d..28d2019af2f 100644
--- a/app/assets/javascripts/boards/components/modal/list.vue
+++ b/app/assets/javascripts/boards/components/modal/list.vue
@@ -117,7 +117,7 @@ export default {
};
</script>
<template>
- <section ref="list" class="add-issues-list add-issues-list-columns">
+ <section ref="list" class="add-issues-list add-issues-list-columns d-flex h-100">
<div
v-if="issuesCount > 0 && issues.length === 0"
class="empty-state add-issues-empty-state-filter text-center"
@@ -129,7 +129,7 @@ export default {
<div v-for="issue in group" v-if="showIssue(issue)" :key="issue.id" class="board-card-parent">
<div
:class="{ 'is-active': issue.selected }"
- class="board-card"
+ class="board-card position-relative p-3 rounded"
@click="toggleIssue($event, issue)"
>
<issue-card-inner :issue="issue" :issue-link-base="issueLinkBase" :root-path="rootPath" />
diff --git a/app/assets/javascripts/boards/mixins/issue_card_inner.js b/app/assets/javascripts/boards/mixins/issue_card_inner.js
new file mode 100644
index 00000000000..8000237da6d
--- /dev/null
+++ b/app/assets/javascripts/boards/mixins/issue_card_inner.js
@@ -0,0 +1,5 @@
+export default {
+ methods: {
+ filterByWeight() {},
+ },
+};
diff --git a/app/assets/javascripts/clusters/components/application_row.vue b/app/assets/javascripts/clusters/components/application_row.vue
index 19e5ac1567d..937e4c3bfc3 100644
--- a/app/assets/javascripts/clusters/components/application_row.vue
+++ b/app/assets/javascripts/clusters/components/application_row.vue
@@ -6,6 +6,8 @@ import { s__, sprintf } from '../../locale';
import eventHub from '../event_hub';
import identicon from '../../vue_shared/components/identicon.vue';
import loadingButton from '../../vue_shared/components/loading_button.vue';
+import UninstallApplicationButton from './uninstall_application_button.vue';
+
import {
APPLICATION_STATUS,
REQUEST_SUBMITTED,
@@ -19,6 +21,7 @@ export default {
identicon,
TimeagoTooltip,
GlLink,
+ UninstallApplicationButton,
},
props: {
id: {
@@ -47,6 +50,11 @@ export default {
required: false,
default: false,
},
+ uninstallable: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
status: {
type: String,
required: false,
@@ -63,6 +71,11 @@ export default {
type: String,
required: false,
},
+ installed: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
version: {
type: String,
required: false,
@@ -92,15 +105,7 @@ export default {
return (
this.status === APPLICATION_STATUS.SCHEDULED ||
this.status === APPLICATION_STATUS.INSTALLING ||
- (this.requestStatus === REQUEST_SUBMITTED && !this.statusReason && !this.isInstalled)
- );
- },
- isInstalled() {
- return (
- this.status === APPLICATION_STATUS.INSTALLED ||
- this.status === APPLICATION_STATUS.UPDATED ||
- this.status === APPLICATION_STATUS.UPDATING ||
- this.status === APPLICATION_STATUS.UPDATE_ERRORED
+ (this.requestStatus === REQUEST_SUBMITTED && !this.statusReason && !this.installed)
);
},
canInstall() {
@@ -125,6 +130,12 @@ export default {
rowJsClass() {
return `js-cluster-application-row-${this.id}`;
},
+ displayUninstallButton() {
+ return this.installed && this.uninstallable;
+ },
+ displayInstallButton() {
+ return !this.installed || !this.uninstallable;
+ },
installButtonLoading() {
return !this.status || this.status === APPLICATION_STATUS.SCHEDULED || this.isInstalling;
},
@@ -145,7 +156,7 @@ export default {
label = s__('ClusterIntegration|Install');
} else if (this.isInstalling) {
label = s__('ClusterIntegration|Installing');
- } else if (this.isInstalled) {
+ } else if (this.installed) {
label = s__('ClusterIntegration|Installed');
}
@@ -257,7 +268,7 @@ export default {
<div
:class="[
rowJsClass,
- isInstalled && 'cluster-application-installed',
+ installed && 'cluster-application-installed',
disabled && 'cluster-application-disabled',
]"
class="cluster-application-row gl-responsive-table-row gl-responsive-table-row-col-span"
@@ -280,10 +291,9 @@ export default {
target="blank"
rel="noopener noreferrer"
class="js-cluster-application-title"
+ >{{ title }}</a
>
- {{ title }}
- </a>
- <span v-else class="js-cluster-application-title"> {{ title }} </span>
+ <span v-else class="js-cluster-application-title">{{ title }}</span>
</strong>
<slot name="description"></slot>
<div
@@ -308,17 +318,15 @@ export default {
class="form-text text-muted label p-0 js-cluster-application-upgrade-details"
>
{{ versionLabel }}
-
- <span v-if="upgradeSuccessful"> to</span>
+ <span v-if="upgradeSuccessful">to</span>
<gl-link
v-if="upgradeSuccessful"
:href="chartRepo"
target="_blank"
class="js-cluster-application-upgrade-version"
+ >chart v{{ version }}</gl-link
>
- chart v{{ version }}
- </gl-link>
</div>
<div
@@ -333,7 +341,6 @@ export default {
class="bs-callout bs-callout-success cluster-application-banner mt-2 mb-0 p-0 pl-3"
>
{{ upgradeSuccessDescription }}
-
<button class="close cluster-application-banner-close" @click="dismissUpgradeSuccess">
&times;
</button>
@@ -354,18 +361,23 @@ export default {
role="gridcell"
>
<div v-if="showManageButton" class="btn-group table-action-buttons">
- <a :href="manageLink" :class="{ disabled: disabled }" class="btn">
- {{ manageButtonLabel }}
- </a>
+ <a :href="manageLink" :class="{ disabled: disabled }" class="btn">{{
+ manageButtonLabel
+ }}</a>
</div>
<div class="btn-group table-action-buttons">
<loading-button
+ v-if="displayInstallButton"
:loading="installButtonLoading"
:disabled="disabled || installButtonDisabled"
:label="installButtonLabel"
class="js-cluster-application-install-button"
@click="installClicked"
/>
+ <uninstall-application-button
+ v-if="displayUninstallButton"
+ class="js-cluster-application-uninstall-button"
+ />
</div>
</div>
</div>
diff --git a/app/assets/javascripts/clusters/components/applications.vue b/app/assets/javascripts/clusters/components/applications.vue
index d54f9ce552c..ae4fe11c6ae 100644
--- a/app/assets/javascripts/clusters/components/applications.vue
+++ b/app/assets/javascripts/clusters/components/applications.vue
@@ -238,6 +238,7 @@ export default {
:status-reason="applications.helm.statusReason"
:request-status="applications.helm.requestStatus"
:request-reason="applications.helm.requestReason"
+ :installed="applications.helm.installed"
class="rounded-top"
title-link="https://docs.helm.sh/"
>
@@ -265,6 +266,7 @@ export default {
:status-reason="applications.ingress.statusReason"
:request-status="applications.ingress.requestStatus"
:request-reason="applications.ingress.requestReason"
+ :installed="applications.ingress.installed"
:disabled="!helmInstalled"
title-link="https://kubernetes.io/docs/concepts/services-networking/ingress/"
>
@@ -341,6 +343,7 @@ export default {
:status-reason="applications.cert_manager.statusReason"
:request-status="applications.cert_manager.requestStatus"
:request-reason="applications.cert_manager.requestReason"
+ :installed="applications.cert_manager.installed"
:install-application-request-params="{ email: applications.cert_manager.email }"
:disabled="!helmInstalled"
title-link="https://cert-manager.readthedocs.io/en/latest/#"
@@ -387,6 +390,7 @@ export default {
:status-reason="applications.prometheus.statusReason"
:request-status="applications.prometheus.requestStatus"
:request-reason="applications.prometheus.requestReason"
+ :installed="applications.prometheus.installed"
:disabled="!helmInstalled"
title-link="https://prometheus.io/docs/introduction/overview/"
>
@@ -403,6 +407,7 @@ export default {
:version="applications.runner.version"
:chart-repo="applications.runner.chartRepo"
:upgrade-available="applications.runner.upgradeAvailable"
+ :installed="applications.runner.installed"
:disabled="!helmInstalled"
title-link="https://docs.gitlab.com/runner/"
>
@@ -424,6 +429,7 @@ export default {
:status-reason="applications.jupyter.statusReason"
:request-status="applications.jupyter.requestStatus"
:request-reason="applications.jupyter.requestReason"
+ :installed="applications.jupyter.installed"
:install-application-request-params="{ hostname: applications.jupyter.hostname }"
:disabled="!helmInstalled"
title-link="https://jupyterhub.readthedocs.io/en/stable/"
@@ -483,6 +489,7 @@ export default {
:status-reason="applications.knative.statusReason"
:request-status="applications.knative.requestStatus"
:request-reason="applications.knative.requestReason"
+ :installed="applications.knative.installed"
:install-application-request-params="{ hostname: applications.knative.hostname }"
:disabled="!helmInstalled"
title-link="https://github.com/knative/docs"
diff --git a/app/assets/javascripts/clusters/components/uninstall_application_button.vue b/app/assets/javascripts/clusters/components/uninstall_application_button.vue
new file mode 100644
index 00000000000..30918d1d115
--- /dev/null
+++ b/app/assets/javascripts/clusters/components/uninstall_application_button.vue
@@ -0,0 +1,14 @@
+<script>
+// TODO: Implement loading button component
+import LoadingButton from '~/vue_shared/components/loading_button.vue';
+
+export default {
+ components: {
+ LoadingButton,
+ },
+};
+</script>
+
+<template>
+ <loading-button @click="$emit('click')" />
+</template>
diff --git a/app/assets/javascripts/clusters/constants.js b/app/assets/javascripts/clusters/constants.js
index 67f481f2afb..17849497c87 100644
--- a/app/assets/javascripts/clusters/constants.js
+++ b/app/assets/javascripts/clusters/constants.js
@@ -15,9 +15,24 @@ export const APPLICATION_STATUS = {
UPDATING: 'updating',
UPDATED: 'updated',
UPDATE_ERRORED: 'update_errored',
+ UNINSTALLING: 'uninstalling',
+ UNINSTALL_ERRORED: 'uninstall_errored',
ERROR: 'errored',
};
+/*
+ * The application cannot be in any of the following states without
+ * not being installed.
+ */
+export const APPLICATION_INSTALLED_STATUSES = [
+ APPLICATION_STATUS.INSTALLED,
+ APPLICATION_STATUS.UPDATING,
+ APPLICATION_STATUS.UPDATED,
+ APPLICATION_STATUS.UPDATE_ERRORED,
+ APPLICATION_STATUS.UNINSTALLING,
+ APPLICATION_STATUS.UNINSTALL_ERRORED,
+];
+
// These are only used client-side
export const REQUEST_SUBMITTED = 'request-submitted';
export const REQUEST_FAILURE = 'request-failure';
diff --git a/app/assets/javascripts/clusters/stores/clusters_store.js b/app/assets/javascripts/clusters/stores/clusters_store.js
index 92993337f02..38512ac28c2 100644
--- a/app/assets/javascripts/clusters/stores/clusters_store.js
+++ b/app/assets/javascripts/clusters/stores/clusters_store.js
@@ -1,6 +1,23 @@
import { s__ } from '../../locale';
import { parseBoolean } from '../../lib/utils/common_utils';
-import { INGRESS, JUPYTER, KNATIVE, CERT_MANAGER, RUNNER } from '../constants';
+import {
+ INGRESS,
+ JUPYTER,
+ KNATIVE,
+ CERT_MANAGER,
+ RUNNER,
+ APPLICATION_INSTALLED_STATUSES,
+} from '../constants';
+
+const isApplicationInstalled = appStatus => APPLICATION_INSTALLED_STATUSES.includes(appStatus);
+
+const applicationInitialState = {
+ status: null,
+ statusReason: null,
+ requestReason: null,
+ requestStatus: null,
+ installed: false,
+};
export default class ClusterStore {
constructor() {
@@ -12,60 +29,39 @@ export default class ClusterStore {
statusReason: null,
applications: {
helm: {
+ ...applicationInitialState,
title: s__('ClusterIntegration|Helm Tiller'),
- status: null,
- statusReason: null,
- requestStatus: null,
- requestReason: null,
},
ingress: {
+ ...applicationInitialState,
title: s__('ClusterIntegration|Ingress'),
- status: null,
- statusReason: null,
- requestStatus: null,
- requestReason: null,
externalIp: null,
externalHostname: null,
},
cert_manager: {
+ ...applicationInitialState,
title: s__('ClusterIntegration|Cert-Manager'),
- status: null,
- statusReason: null,
- requestStatus: null,
- requestReason: null,
email: null,
},
runner: {
+ ...applicationInitialState,
title: s__('ClusterIntegration|GitLab Runner'),
- status: null,
- statusReason: null,
- requestStatus: null,
- requestReason: null,
version: null,
chartRepo: 'https://gitlab.com/charts/gitlab-runner',
upgradeAvailable: null,
},
prometheus: {
+ ...applicationInitialState,
title: s__('ClusterIntegration|Prometheus'),
- status: null,
- statusReason: null,
- requestStatus: null,
- requestReason: null,
},
jupyter: {
+ ...applicationInitialState,
title: s__('ClusterIntegration|JupyterHub'),
- status: null,
- statusReason: null,
- requestStatus: null,
- requestReason: null,
hostname: null,
},
knative: {
+ ...applicationInitialState,
title: s__('ClusterIntegration|Knative'),
- status: null,
- statusReason: null,
- requestStatus: null,
- requestReason: null,
hostname: null,
isEditingHostName: false,
externalIp: null,
@@ -118,6 +114,7 @@ export default class ClusterStore {
...(this.state.applications[appId] || {}),
status,
statusReason,
+ installed: isApplicationInstalled(status),
};
if (appId === INGRESS) {
diff --git a/app/assets/javascripts/gfm_auto_complete.js b/app/assets/javascripts/gfm_auto_complete.js
index c81e754df4c..f1e26cdfa21 100644
--- a/app/assets/javascripts/gfm_auto_complete.js
+++ b/app/assets/javascripts/gfm_auto_complete.js
@@ -461,7 +461,10 @@ class GfmAutoComplete {
// We can ignore this for quick actions because they are processed
// before Markdown.
if (!this.setting.skipMarkdownCharacterTest) {
- withoutAt = withoutAt.replace(/([~\-_*`])/g, '\\$&');
+ withoutAt = withoutAt
+ .replace(/(~~|`|\*)/g, '\\$1')
+ .replace(/(\b)(_+)/g, '$1\\$2') // only escape underscores at the start
+ .replace(/(_+)(\b)/g, '\\$1$2'); // or end of words
}
return `${at}${withoutAt}`;
diff --git a/app/assets/javascripts/monitoring/stores/monitoring_store.js b/app/assets/javascripts/monitoring/stores/monitoring_store.js
index 9761fe168be..013fb0d4540 100644
--- a/app/assets/javascripts/monitoring/stores/monitoring_store.js
+++ b/app/assets/javascripts/monitoring/stores/monitoring_store.js
@@ -45,14 +45,13 @@ function removeTimeSeriesNoData(queries) {
// ]
function groupQueriesByChartInfo(metrics) {
const metricsByChart = metrics.reduce((accumulator, metric) => {
- const { id, queries, ...chart } = metric;
+ const { queries, ...chart } = metric;
+ const metricId = chart.id ? chart.id.toString() : null;
const chartKey = `${chart.title}|${chart.y_label}`;
accumulator[chartKey] = accumulator[chartKey] || { ...chart, queries: [] };
- queries.forEach(queryAttrs =>
- accumulator[chartKey].queries.push({ metricId: id.toString(), ...queryAttrs }),
- );
+ queries.forEach(queryAttrs => accumulator[chartKey].queries.push({ metricId, ...queryAttrs }));
return accumulator;
}, {});
diff --git a/app/assets/javascripts/notes/components/discussion_actions.vue b/app/assets/javascripts/notes/components/discussion_actions.vue
new file mode 100644
index 00000000000..22cca756ef6
--- /dev/null
+++ b/app/assets/javascripts/notes/components/discussion_actions.vue
@@ -0,0 +1,58 @@
+<script>
+import ReplyPlaceholder from './discussion_reply_placeholder.vue';
+import ResolveDiscussionButton from './discussion_resolve_button.vue';
+import ResolveWithIssueButton from './discussion_resolve_with_issue_button.vue';
+import JumpToNextDiscussionButton from './discussion_jump_to_next_button.vue';
+
+export default {
+ name: 'DiscussionActions',
+ components: {
+ ReplyPlaceholder,
+ ResolveDiscussionButton,
+ ResolveWithIssueButton,
+ JumpToNextDiscussionButton,
+ },
+ props: {
+ discussion: {
+ type: Object,
+ required: true,
+ },
+ isResolving: {
+ type: Boolean,
+ required: true,
+ },
+ resolveButtonTitle: {
+ type: String,
+ required: true,
+ },
+ resolveWithIssuePath: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ shouldShowJumpToNextDiscussion: {
+ type: Boolean,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="discussion-with-resolve-btn">
+ <reply-placeholder class="qa-discussion-reply" @onClick="$emit('showReplyForm')" />
+ <resolve-discussion-button
+ v-if="discussion.resolvable"
+ :is-resolving="isResolving"
+ :button-title="resolveButtonTitle"
+ @onClick="$emit('resolve')"
+ />
+ <div v-if="discussion.resolvable" class="btn-group discussion-actions ml-sm-2" role="group">
+ <resolve-with-issue-button v-if="resolveWithIssuePath" :url="resolveWithIssuePath" />
+ <jump-to-next-discussion-button
+ v-if="shouldShowJumpToNextDiscussion"
+ @onClick="$emit('jumpToNextDiscussion')"
+ />
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/notes/components/noteable_discussion.vue b/app/assets/javascripts/notes/components/noteable_discussion.vue
index a3d664a738f..89563711bcd 100644
--- a/app/assets/javascripts/notes/components/noteable_discussion.vue
+++ b/app/assets/javascripts/notes/components/noteable_discussion.vue
@@ -14,7 +14,6 @@ import { SYSTEM_NOTE } from '../constants';
import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
import noteableNote from './noteable_note.vue';
import noteHeader from './note_header.vue';
-import resolveDiscussionButton from './discussion_resolve_button.vue';
import toggleRepliesWidget from './toggle_replies_widget.vue';
import noteSignedOutWidget from './note_signed_out_widget.vue';
import noteEditedText from './note_edited_text.vue';
@@ -25,10 +24,8 @@ import placeholderSystemNote from '../../vue_shared/components/notes/placeholder
import noteable from '../mixins/noteable';
import resolvable from '../mixins/resolvable';
import discussionNavigation from '../mixins/discussion_navigation';
-import ReplyPlaceholder from './discussion_reply_placeholder.vue';
-import ResolveWithIssueButton from './discussion_resolve_with_issue_button.vue';
-import jumpToNextDiscussionButton from './discussion_jump_to_next_button.vue';
import eventHub from '../event_hub';
+import DiscussionActions from './discussion_actions.vue';
export default {
name: 'NoteableDiscussion',
@@ -40,16 +37,13 @@ export default {
noteSignedOutWidget,
noteEditedText,
noteForm,
- resolveDiscussionButton,
- jumpToNextDiscussionButton,
toggleRepliesWidget,
- ReplyPlaceholder,
placeholderNote,
placeholderSystemNote,
- ResolveWithIssueButton,
systemNote,
DraftNote: () => import('ee_component/batch_comments/components/draft_note.vue'),
TimelineEntryItem,
+ DiscussionActions,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -465,31 +459,17 @@ Please check your network connection and try again.`;
:class="{ 'is-replying': isReplying }"
class="discussion-reply-holder"
>
- <template v-if="!isReplying && canReply">
- <div class="discussion-with-resolve-btn">
- <reply-placeholder class="qa-discussion-reply" @onClick="showReplyForm" />
- <resolve-discussion-button
- v-if="discussion.resolvable"
- :is-resolving="isResolving"
- :button-title="resolveButtonTitle"
- @onClick="resolveHandler"
- />
- <div
- v-if="discussion.resolvable"
- class="btn-group discussion-actions ml-sm-2"
- role="group"
- >
- <resolve-with-issue-button
- v-if="resolveWithIssuePath"
- :url="resolveWithIssuePath"
- />
- <jump-to-next-discussion-button
- v-if="shouldShowJumpToNextDiscussion"
- @onClick="jumpToNextDiscussion"
- />
- </div>
- </div>
- </template>
+ <discussion-actions
+ v-if="!isReplying && canReply"
+ :discussion="discussion"
+ :is-resolving="isResolving"
+ :resolve-button-title="resolveButtonTitle"
+ :resolve-with-issue-path="resolveWithIssuePath"
+ :should-show-jump-to-next-discussion="shouldShowJumpToNextDiscussion"
+ @showReplyForm="showReplyForm"
+ @resolve="resolveHandler"
+ @jumpToNextDiscussion="jumpToNextDiscussion"
+ />
<note-form
v-if="isReplying"
ref="noteForm"
diff --git a/app/assets/stylesheets/components/dashboard_skeleton.scss b/app/assets/stylesheets/components/dashboard_skeleton.scss
index 42ede599bc6..9775c329922 100644
--- a/app/assets/stylesheets/components/dashboard_skeleton.scss
+++ b/app/assets/stylesheets/components/dashboard_skeleton.scss
@@ -8,10 +8,6 @@
&-warning {
background-color: $orange-100;
}
-
- &-failed {
- background-color: $red-100;
- }
}
&-body {
@@ -36,10 +32,6 @@
border-radius: $gl-padding;
height: $gl-padding-32;
- &-failed {
- background-color: $red-100;
- }
-
&-arrow {
color: $gray-300;
}
@@ -56,6 +48,13 @@
}
}
+ &-header,
+ &-footer {
+ &-failed {
+ background-color: $red-100;
+ }
+ }
+
&-skeleton-info {
border-radius: $gl-padding;
height: $gl-padding;
diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss
index fc1c1bd9962..61fab445793 100644
--- a/app/assets/stylesheets/pages/boards.scss
+++ b/app/assets/stylesheets/pages/boards.scss
@@ -1,7 +1,3 @@
-[v-cloak] {
- display: none;
-}
-
.user-can-drag {
cursor: grab;
}
@@ -40,35 +36,15 @@
margin: 0 8px 10px;
padding-bottom: 10px;
border-bottom: 1px solid $dropdown-divider-bg;
-
- > p {
- margin: 0;
- font-size: 14px;
- }
}
.issue-boards-page {
.content-wrapper {
padding-bottom: 0;
}
-
- .issues-details-filters {
- display: flex;
- }
-
- .filter-form {
- width: 100%;
- }
-}
-
-.board-extra-actions {
- font-size: 0;
- white-space: nowrap;
}
.boards-app {
- position: relative;
-
@include media-breakpoint-up(sm) {
transition: width $sidebar-transition-duration;
width: 100%;
@@ -79,17 +55,9 @@
}
}
-.boards-app-loading {
- width: 100%;
- font-size: 34px;
-}
-
.boards-list {
height: calc(100vh - #{$issue-board-list-difference-xs});
- width: 100%;
- padding: $gl-padding ($gl-padding / 2);
overflow-x: scroll;
- white-space: nowrap;
min-height: 200px;
@include media-breakpoint-only(sm) {
@@ -114,13 +82,7 @@
}
.board {
- display: inline-block;
width: calc(85vw - 15px);
- height: 100%;
- padding-right: ($gl-padding / 2);
- padding-left: ($gl-padding / 2);
- white-space: normal;
- vertical-align: top;
@include media-breakpoint-up(sm) {
width: 400px;
@@ -135,23 +97,7 @@
&.is-collapsed {
width: 50px;
- .board-header {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
-
- button {
- display: none;
- }
- }
-
.board-title {
- padding: 0;
- border-bottom: 0;
- justify-content: center;
-
> span {
width: 100%;
margin-top: -12px;
@@ -167,34 +113,16 @@
left: 50%;
margin-left: -10px;
}
-
- .board-list-component,
- .issue-count-badge {
- display: none;
- }
- }
-
- &:not(.is-collapsed) {
- .board-list-component {
- display: flex;
- flex-direction: column;
- }
}
}
.board-inner {
- position: relative;
- height: 100%;
font-size: $issue-boards-font-size;
background: $gray-light;
border: 1px solid $border-color;
- border-radius: $border-radius-default;
- flex: 1;
}
.board-header {
- position: relative;
-
&.has-border::before {
border-top: 3px solid;
border-color: inherit;
@@ -219,18 +147,9 @@
}
}
-.board-inner-container {
- border-bottom: 1px solid $border-color;
- padding: $gl-padding;
-}
-
.board-title {
- margin: 0;
- padding: $gl-padding-8 $gl-padding;
font-size: 1em;
border-bottom: 1px solid $border-color;
- display: flex;
- align-items: center;
}
.board-title-text {
@@ -239,10 +158,8 @@
.board-delete {
margin-right: 10px;
- padding: 0;
color: $gray-darkest;
background-color: transparent;
- border: 0;
outline: 0;
&:hover {
@@ -252,7 +169,6 @@
.board-blank-state,
.board-promotion-state {
- padding: $gl-padding;
background-color: $white-light;
flex: 1;
overflow-y: auto;
@@ -260,35 +176,23 @@
}
.board-blank-state-list {
- list-style: none;
-
> li:not(:last-child) {
margin-bottom: 8px;
}
.label-color {
- position: relative;
top: 2px;
- display: inline-block;
width: 16px;
height: 16px;
margin-right: 3px;
- border-radius: $border-radius-default;
}
}
.board-list-component {
- position: relative;
- flex: 1;
min-height: 0; // firefox fix
}
.board-list {
- height: 100%;
- width: 100%;
- margin-bottom: 0;
- padding: $gl-padding-4;
- list-style: none;
overflow-y: auto;
overflow-x: hidden;
}
@@ -299,13 +203,9 @@
}
.board-card {
- position: relative;
- padding: $gl-padding;
background: $white-light;
- border-radius: $border-radius-default;
border: 1px solid $gray-200;
box-shadow: 0 1px 2px $issue-boards-card-shadow;
- list-style: none;
line-height: $gl-padding;
&:not(:last-child) {
@@ -333,10 +233,6 @@
}
}
- svg {
- vertical-align: top;
- }
-
.confidential-icon {
color: $orange-600;
cursor: help;
@@ -360,12 +256,7 @@
}
}
-.board-card-header {
- display: flex;
-}
-
.board-card-assignee {
- display: flex;
margin-top: -$gl-padding-4;
margin-bottom: -$gl-padding-4;
@@ -425,34 +316,16 @@
.board-card-number {
font-size: $gl-font-size-xs;
color: $gl-text-color-secondary;
- overflow: hidden;
@include media-breakpoint-up(md) {
font-size: $label-font-size;
}
}
-.board-card-number-container {
- overflow: hidden;
-}
-
-.issue-boards-search {
- width: 395px;
-
- .form-control {
- display: inline-block;
- width: 210px;
- }
-}
-
.board-list-count {
padding: 10px 0;
color: $gl-text-color-secondary;
font-size: 13px;
-
- > .fa {
- margin-right: 5px;
- }
}
.board-new-issue-form {
@@ -460,16 +333,9 @@
margin: 5px;
}
-.page-with-contextual-sidebar.layout-page .issue-boards-sidebar {
- .issuable-sidebar-header {
- position: relative;
- }
-
+.issue-boards-sidebar {
.gutter-toggle {
- position: absolute;
- top: 0;
bottom: 15px;
- right: 0;
width: 22px;
color: $gray-darkest;
@@ -489,10 +355,6 @@
.issuable-header-text {
@include overflow-break-word();
padding-right: 35px;
-
- > strong {
- font-weight: $gl-font-weight-bold;
- }
}
}
@@ -511,44 +373,25 @@
}
.add-issues-modal {
- display: flex;
- position: fixed;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
background-color: rgba($black, 0.3);
z-index: 9999;
}
.add-issues-container {
- display: flex;
- flex-direction: column;
width: 90vw;
height: 85vh;
max-width: 1100px;
min-height: 500px;
- margin: auto;
padding: 25px 15px 0;
background-color: $white-light;
- border-radius: $border-radius-default;
box-shadow: 0 2px 12px rgba($black, 0.5);
.empty-state {
- display: flex;
- flex: 1;
- margin-top: 0;
-
&.add-issues-empty-state-filter {
flex-direction: column;
justify-content: center;
}
- > .row {
- width: 100%;
- margin: auto 0;
- }
-
.svg-content {
margin-top: -40px;
}
@@ -557,25 +400,15 @@
.add-issues-header {
margin: -25px -15px -5px;
- border-top: 0;
border-bottom: 1px solid $border-color;
border-top-right-radius: $border-radius-default;
border-top-left-radius: $border-radius-default;
> h2 {
- margin: 0;
font-size: 18px;
}
}
-.add-issues-search {
- display: flex;
-
- .issues-filters {
- flex: 1;
- }
-}
-
.add-issues-list-column {
width: 100%;
@@ -589,8 +422,6 @@
}
.add-issues-list {
- display: flex;
- flex: 1;
padding-top: 3px;
margin-left: -$gl-vert-padding;
margin-right: -$gl-vert-padding;
@@ -607,14 +438,6 @@
}
}
-.add-issues-list-loading {
- align-self: center;
- width: 100%;
- padding-left: $gl-vert-padding;
- padding-right: $gl-vert-padding;
- font-size: 35px;
-}
-
.add-issues-footer {
margin: auto -15px 0;
padding-left: 15px;
@@ -642,27 +465,6 @@
border-radius: 50%;
}
-.modal-filters {
- display: flex;
-
- > .dropdown {
- display: none;
- margin-right: 10px;
-
- @include media-breakpoint-up(sm) {
- display: block;
- }
- }
-
- .dropdown-menu-toggle {
- width: 100px;
-
- @include media-breakpoint-up(md) {
- width: 140px;
- }
- }
-}
-
.board-card-info {
color: $gl-text-color-secondary;
white-space: nowrap;
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index d5f1e35a79b..ceaa84acaba 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -128,7 +128,7 @@ class ApplicationController < ActionController::Base
payload[:ua] = request.env["HTTP_USER_AGENT"]
payload[:remote_ip] = request.remote_ip
- payload[Gitlab::CorrelationId::LOG_KEY] = Gitlab::CorrelationId.current_id
+ payload[Labkit::Correlation::CorrelationId::LOG_KEY] = Labkit::Correlation::CorrelationId.current_id
logged_user = auth_user
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 3d16a368f23..2ef5c207d67 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -10,11 +10,11 @@ class Projects::IssuesController < Projects::ApplicationController
include SpammableActions
include RecordUserLastActivity
- def self.issue_except_actions
+ def issue_except_actions
%i[index calendar new create bulk_update import_csv]
end
- def self.set_issuables_index_only_actions
+ def set_issuables_index_only_actions
%i[index calendar]
end
@@ -25,9 +25,9 @@ class Projects::IssuesController < Projects::ApplicationController
before_action :whitelist_query_limiting, only: [:create, :create_merge_request, :move, :bulk_update]
before_action :check_issues_available!
- before_action :issue, except: issue_except_actions
+ before_action :issue, unless: ->(c) { c.issue_except_actions.include?(c.action_name.to_sym) }
- before_action :set_issuables_index, only: set_issuables_index_only_actions
+ before_action :set_issuables_index, if: ->(c) { c.set_issuables_index_only_actions.include?(c.action_name.to_sym) }
# Allow write(create) issue
before_action :authorize_create_issue!, only: [:new, :create]
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 5cf9bb4979a..e5236051118 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -15,6 +15,7 @@ module Ci
include Gitlab::Utils::StrongMemoize
include Deployable
include HasRef
+ include UpdateProjectStatistics
BuildArchivedError = Class.new(StandardError)
@@ -157,8 +158,7 @@ module Ci
run_after_commit { BuildHooksWorker.perform_async(build.id) }
end
- after_save :update_project_statistics_after_save, if: :artifacts_size_changed?
- after_destroy :update_project_statistics_after_destroy, unless: :project_destroyed?
+ update_project_statistics stat: :build_artifacts_size, attribute: :artifacts_size
class << self
# This is needed for url_for to work,
@@ -847,21 +847,5 @@ module Ci
pipeline.config_processor.build_attributes(name)
end
-
- def update_project_statistics_after_save
- update_project_statistics(read_attribute(:artifacts_size).to_i - artifacts_size_was.to_i)
- end
-
- def update_project_statistics_after_destroy
- update_project_statistics(-artifacts_size)
- end
-
- def update_project_statistics(difference)
- ProjectStatistics.increment_statistic(project_id, :build_artifacts_size, difference)
- end
-
- def project_destroyed?
- project.pending_delete?
- end
end
end
diff --git a/app/models/ci/job_artifact.rb b/app/models/ci/job_artifact.rb
index 9695d49d18b..7c836c6f95c 100644
--- a/app/models/ci/job_artifact.rb
+++ b/app/models/ci/job_artifact.rb
@@ -4,6 +4,7 @@ module Ci
class JobArtifact < ApplicationRecord
include AfterCommitQueue
include ObjectStorage::BackgroundMove
+ include UpdateProjectStatistics
extend Gitlab::Ci::Model
NotSupportedAdapterError = Class.new(StandardError)
@@ -52,8 +53,8 @@ module Ci
validates :file_format, presence: true, unless: :trace?, on: :create
validate :valid_file_format?, unless: :trace?, on: :create
before_save :set_size, if: :file_changed?
- after_save :update_project_statistics_after_save, if: :size_changed?
- after_destroy :update_project_statistics_after_destroy, unless: :project_destroyed?
+
+ update_project_statistics stat: :build_artifacts_size
after_save :update_file_store, if: :file_changed?
@@ -176,18 +177,6 @@ module Ci
self.size = file.size
end
- def update_project_statistics_after_save
- update_project_statistics(size.to_i - size_was.to_i)
- end
-
- def update_project_statistics_after_destroy
- update_project_statistics(-self.size.to_i)
- end
-
- def update_project_statistics(difference)
- ProjectStatistics.increment_statistic(project_id, :build_artifacts_size, difference)
- end
-
def project_destroyed?
# Use job.project to avoid extra DB query for project
job.project.pending_delete?
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index 3232c51bfbd..775aaa44e5b 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -128,10 +128,6 @@ module Issuable
assignees.count > 1
end
- def milestone_available?
- project_id == milestone&.project_id || project.ancestors_upto.compact.include?(milestone&.group)
- end
-
private
def milestone_is_valid
@@ -277,6 +273,10 @@ module Issuable
end
end
+ def milestone_available?
+ project_id == milestone&.project_id || project.ancestors_upto.compact.include?(milestone&.group)
+ end
+
def assignee_or_author?(user)
author_id == user.id || assignees.exists?(user.id)
end
diff --git a/app/models/concerns/update_project_statistics.rb b/app/models/concerns/update_project_statistics.rb
new file mode 100644
index 00000000000..bffc711c886
--- /dev/null
+++ b/app/models/concerns/update_project_statistics.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+# This module is providing helpers for updating `ProjectStatistics` with `after_save` and `before_destroy` hooks.
+#
+# It deals with `ProjectStatistics.increment_statistic` making sure not to update statistics on a cascade delete from the
+# project, and keeping track of value deltas on each save. It updates the DB only when a change is needed.
+#
+# How to use
+# - Invoke `update_project_statistics stat: :a_project_statistics_column, attribute: :an_attr_to_track` in a model class body.
+#
+# Expectation
+# - `attribute` must be an ActiveRecord attribute
+# - The model must implement `project` and `project_id`. i.e. direct Project relationship or delegation
+module UpdateProjectStatistics
+ extend ActiveSupport::Concern
+
+ class_methods do
+ attr_reader :statistic_name, :statistic_attribute
+
+ # Configure the model to update +stat+ on ProjectStatistics when +attribute+ changes
+ #
+ # +stat+:: a column of ProjectStatistics to update
+ # +attribute+:: an attribute of the current model, default to +:size+
+ def update_project_statistics(stat:, attribute: :size)
+ @statistic_name = stat
+ @statistic_attribute = attribute
+
+ after_save(:update_project_statistics_after_save, if: :update_project_statistics_attribute_changed?)
+ after_destroy(:update_project_statistics_after_destroy, unless: :project_destroyed?)
+ end
+ private :update_project_statistics
+ end
+
+ included do
+ private
+
+ def project_destroyed?
+ project.pending_delete?
+ end
+
+ def update_project_statistics_attribute_changed?
+ attribute_changed?(self.class.statistic_attribute)
+ end
+
+ def update_project_statistics_after_save
+ attr = self.class.statistic_attribute
+ delta = read_attribute(attr).to_i - attribute_was(attr).to_i
+
+ update_project_statistics(delta)
+ end
+
+ def update_project_statistics_after_destroy
+ update_project_statistics(-read_attribute(self.class.statistic_attribute).to_i)
+ end
+
+ def update_project_statistics(delta)
+ ProjectStatistics.increment_statistic(project_id, self.class.statistic_name, delta)
+ end
+ end
+end
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index dea34e812ca..8638c5a9c53 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -51,6 +51,7 @@ class Namespace < ApplicationRecord
validate :nesting_level_allowed
delegate :name, to: :owner, allow_nil: true, prefix: true
+ delegate :avatar_url, to: :owner, allow_nil: true
after_commit :refresh_access_of_projects_invited_groups, on: :update, if: -> { previous_changes.key?('share_with_group_lock') }
@@ -149,6 +150,10 @@ class Namespace < ApplicationRecord
type == 'Group' ? 'group' : 'user'
end
+ def user?
+ kind == 'user'
+ end
+
def find_fork_of(project)
return unless project.fork_network
diff --git a/app/views/projects/_merge_request_merge_checks_settings.html.haml b/app/views/projects/_merge_request_merge_checks_settings.html.haml
new file mode 100644
index 00000000000..1ab467a3710
--- /dev/null
+++ b/app/views/projects/_merge_request_merge_checks_settings.html.haml
@@ -0,0 +1,19 @@
+- form = local_assigns.fetch(:form)
+
+.form-group
+ %b= s_('ProjectSettings|Merge checks')
+ %p.text-secondary= s_('ProjectSettings|These checks must pass before merge requests can be merged')
+ .form-check.mb-2.builds-feature{ class: ("hidden" if @project && @project.project_feature.send(:builds_access_level) == 0) }
+ = form.check_box :only_allow_merge_if_pipeline_succeeds, class: 'form-check-input'
+ = form.label :only_allow_merge_if_pipeline_succeeds, class: 'form-check-label' do
+ = s_('ProjectSettings|Pipelines must succeed')
+ .descr.text-secondary
+ = s_('ProjectSettings|Pipelines need to be configured to enable this feature.')
+ = link_to icon('question-circle'),
+ help_page_path('ci/merge_request_pipelines/index.md',
+ anchor: 'pipelines-for-merge-requests'),
+ target: '_blank'
+ .form-check.mb-2
+ = form.check_box :only_allow_merge_if_all_discussions_are_resolved, class: 'form-check-input'
+ = form.label :only_allow_merge_if_all_discussions_are_resolved, class: 'form-check-label' do
+ = s_('ProjectSettings|All discussions must be resolved')
diff --git a/app/views/projects/_merge_request_merge_method_settings.html.haml b/app/views/projects/_merge_request_merge_method_settings.html.haml
index 9082bfc409d..47c311f42d0 100644
--- a/app/views/projects/_merge_request_merge_method_settings.html.haml
+++ b/app/views/projects/_merge_request_merge_method_settings.html.haml
@@ -1,30 +1,33 @@
- form = local_assigns.fetch(:form)
.form-group
- = label_tag :merge_method_merge, class: 'label-bold' do
- = _('Merge method')
- .form-check
+ %b= s_('ProjectSettings|Merge method')
+ %p.text-secondary= s_('ProjectSettings|This will dictate the commit history when you merge a merge request')
+ .form-check.mb-2
= form.radio_button :merge_method, :merge, class: "js-merge-method-radio form-check-input"
= label_tag :project_merge_method_merge, class: 'form-check-label' do
- .mb-3
- = _('Merge commit')
- .text-secondary
- = _('A merge commit is created for every merge, and merging is allowed as long as there are no conflicts.')
+ = s_('ProjectSettings|Merge commit')
+ .descr.text-secondary
+ = s_('ProjectSettings|Every merge creates a merge commit')
-.form-check
- = form.radio_button :merge_method, :rebase_merge, class: "js-merge-method-radio form-check-input"
- = label_tag :project_merge_method_rebase_merge, class: 'form-check-label' do
- .mb-3
- = _('Merge commit with semi-linear history')
- .text-secondary
- = _('A merge commit is created for every merge, but merging is only allowed if fast-forward merge is possible. This way you could make sure that if this merge request would build, after merging to target branch it would also build.')
- .text-secondary
- = _('When fast-forward merge is not possible, the user is given the option to rebase.')
+ .form-check.mb-2
+ = form.radio_button :merge_method, :rebase_merge, class: "js-merge-method-radio form-check-input"
+ = label_tag :project_merge_method_rebase_merge, class: 'form-check-label' do
+ = s_('ProjectSettings|Merge commit with semi-linear history')
+ .descr.text-secondary
+ = s_('ProjectSettings|Every merge creates a merge commit')
+ %br
+ = s_('ProjectSettings|Fast-forward merges only')
+ %br
+ = s_('ProjectSettings|When conflicts arise the user is given the option to rebase')
-.form-check
- = form.radio_button :merge_method, :ff, class: "js-merge-method-radio qa-radio-button-merge-ff form-check-input"
- = label_tag :project_merge_method_ff, class: 'form-check-label' do
- .mb-3
- = _('Fast-forward merge')
- .text-secondary
- = _('No merge commits are created and all merges are fast-forwarded, which means that merging is only allowed if the branch could be fast-forwarded. When fast-forward merge is not possible, the user is given the option to rebase.')
+ .form-check.mb-2
+ = form.radio_button :merge_method, :ff, class: "js-merge-method-radio qa-radio-button-merge-ff form-check-input"
+ = label_tag :project_merge_method_ff, class: 'form-check-label' do
+ = s_('ProjectSettings|Fast-forward merge')
+ .descr.text-secondary
+ = s_('ProjectSettings|No merge commits are created')
+ %br
+ = s_('ProjectSettings|Fast-forward merges only')
+ %br
+ = s_('ProjectSettings|When conflicts arise the user is given the option to rebase')
diff --git a/app/views/projects/_merge_request_merge_options_settings.html.haml b/app/views/projects/_merge_request_merge_options_settings.html.haml
new file mode 100644
index 00000000000..5ab475822de
--- /dev/null
+++ b/app/views/projects/_merge_request_merge_options_settings.html.haml
@@ -0,0 +1,14 @@
+- form = local_assigns.fetch(:form)
+
+.form-group
+ %b= s_('ProjectSettings|Merge options')
+ %p.text-secondary= s_('ProjectSettings|Additional merge request capabilities that influence how and when merges will be performed')
+ = render_if_exists 'projects/merge_pipelines_settings', form: form
+ .form-check.mb-2
+ = form.check_box :resolve_outdated_diff_discussions, class: 'form-check-input'
+ = form.label :resolve_outdated_diff_discussions, class: 'form-check-label' do
+ = s_('ProjectSettings|Automatically resolve merge request diff discussions when they become outdated')
+ .form-check.mb-2
+ = form.check_box :printing_merge_request_link_enabled, class: 'form-check-input'
+ = form.label :printing_merge_request_link_enabled, class: 'form-check-label' do
+ = s_('ProjectSettings|Show link to create/view merge request when pushing from the command line')
diff --git a/app/views/projects/_merge_request_merge_settings.html.haml b/app/views/projects/_merge_request_merge_settings.html.haml
deleted file mode 100644
index 3a9f7ca42db..00000000000
--- a/app/views/projects/_merge_request_merge_settings.html.haml
+++ /dev/null
@@ -1,24 +0,0 @@
-- form = local_assigns.fetch(:form)
-
-.form-group
- .form-check.builds-feature{ class: ("hidden" if @project && @project.project_feature.send(:builds_access_level) == 0) }
- = form.check_box :only_allow_merge_if_pipeline_succeeds, class: 'form-check-input'
- = form.label :only_allow_merge_if_pipeline_succeeds, class: 'form-check-label' do
- .mb-3
- = _('Only allow merge requests to be merged if the pipeline succeeds')
- .text-secondary
- = _('Pipelines need to be configured to enable this feature.')
- = link_to icon('question-circle'), help_page_path('user/project/merge_requests/merge_when_pipeline_succeeds', anchor: 'only-allow-merge-requests-to-be-merged-if-the-pipeline-succeeds'), target: '_blank'
- = render_if_exists 'projects/merge_pipelines_settings', form: form
- .form-check
- = form.check_box :only_allow_merge_if_all_discussions_are_resolved, class: 'form-check-input'
- = form.label :only_allow_merge_if_all_discussions_are_resolved, class: 'form-check-label' do
- %p= _('Only allow merge requests to be merged if all discussions are resolved')
- .form-check
- = form.check_box :resolve_outdated_diff_discussions, class: 'form-check-input'
- = form.label :resolve_outdated_diff_discussions, class: 'form-check-label' do
- %p= _('Automatically resolve merge request diff discussions when they become outdated')
- .form-check
- = form.check_box :printing_merge_request_link_enabled, class: 'form-check-input'
- = form.label :printing_merge_request_link_enabled, class: 'form-check-label' do
- %p= _('Show link to create/view merge request when pushing from the command line')
diff --git a/app/views/projects/_merge_request_settings.html.haml b/app/views/projects/_merge_request_settings.html.haml
index c80e831dd33..f2ba38387a3 100644
--- a/app/views/projects/_merge_request_settings.html.haml
+++ b/app/views/projects/_merge_request_settings.html.haml
@@ -2,4 +2,6 @@
= render 'projects/merge_request_merge_method_settings', project: @project, form: form
-= render 'projects/merge_request_merge_settings', form: form
+= render 'projects/merge_request_merge_options_settings', project: @project, form: form
+
+= render 'projects/merge_request_merge_checks_settings', project: @project, form: form
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index 1a3e4a5d608..c04530dc62c 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -27,7 +27,7 @@
.settings-header
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only= _('Merge requests')
%button.btn.btn-default.js-settings-toggle{ type: 'button' }= expanded ? _('Collapse') : _('Expand')
- %p= _('Choose your merge method, set up a default merge request description template.')
+ %p= _('Choose your merge method, options, checks, and set up a default merge request description template.')
.settings-content
= render_if_exists 'shared/promotions/promote_mr_features'
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index 2c95ac6dbb3..4bf1d8702af 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -77,7 +77,7 @@
= edited_time_ago_with_tooltip(@issue, placement: 'bottom', html_class: 'issue-edited-ago js-issue-edited-ago')
- #js-related-merge-requests{ data: { endpoint: api_v4_projects_issues_related_merge_requests_path(id: @project.id, issue_iid: @issue.iid), project_namespace: @project.namespace.path, project_path: @project.path } }
+ #js-related-merge-requests{ data: { endpoint: expose_url(api_v4_projects_issues_related_merge_requests_path(id: @project.id, issue_iid: @issue.iid)), project_namespace: @project.namespace.path, project_path: @project.path } }
- if can?(current_user, :download_code, @project)
#related-branches{ data: { url: related_branches_project_issue_path(@project, @issue) } }
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index ff7c36c2d5b..95027634de2 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -48,7 +48,12 @@
= form_for @project, html: { class: 'new_project' } do |f|
= render 'new_project_fields', f: f, project_name_id: "blank-project-name"
- .tab-pane.no-padding{ id: 'create-from-template-pane', class: active_when(active_tab == 'template'), role: 'tabpanel' }
+ #create-from-template-pane.tab-pane.px-0.pb-0{ class: active_when(active_tab == 'template'), role: 'tabpanel' }
+ .card-slim.m-4.p-4
+ %div
+ - contributing_templates_url = 'https://gitlab.com/gitlab-org/project-templates/contributing'
+ - link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: contributing_templates_url }
+ = _('Learn how to %{link_start}contribute to the built-in templates%{link_end}').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
= form_for @project, html: { class: 'new_project' } do |f|
.project-template
.form-group
diff --git a/app/views/shared/_label_row.html.haml b/app/views/shared/_label_row.html.haml
index 6651f12f6de..9d1648fbf70 100644
--- a/app/views/shared/_label_row.html.haml
+++ b/app/views/shared/_label_row.html.haml
@@ -1,13 +1,11 @@
- subject = local_assigns[:subject]
- force_priority = local_assigns.fetch(:force_priority, false)
-- show_label_issues_link = defined?(@project) && show_label_issuables_link?(label, :issues, project: @project)
-- show_label_merge_requests_link = defined?(@project) && show_label_issuables_link?(label, :merge_requests, project: @project)
+- subject_or_group_defined = defined?(@project) || defined?(@group)
+- show_label_issues_link = subject_or_group_defined && show_label_issuables_link?(label, :issues, project: @project)
+- show_label_merge_requests_link = subject_or_group_defined && show_label_issuables_link?(label, :merge_requests, project: @project)
.label-name
- - if defined?(@project)
- = link_to_label(label, subject: @project, tooltip: false)
- - else
- = render_label(label, tooltip: false)
+ = render_label(label, tooltip: false)
.label-description
.append-right-default.prepend-left-default
- if label.description.present?
@@ -22,5 +20,6 @@
%li.label-link-item.inline
= link_to_label(label, subject: subject, type: :merge_request) { _('Merge requests') }
- if force_priority
+ &middot;
%li.label-link-item.priority-badge.js-priority-badge.inline.prepend-left-10
.label-badge.label-badge-blue= _('Prioritized label')
diff --git a/app/views/shared/boards/_show.html.haml b/app/views/shared/boards/_show.html.haml
index f0d1dd162df..813fccd217b 100644
--- a/app/views/shared/boards/_show.html.haml
+++ b/app/views/shared/boards/_show.html.haml
@@ -13,14 +13,14 @@
%script#js-board-modal-filter{ type: "text/x-template" }= render "shared/issuable/search_bar", type: :boards_modal, show_sorting_dropdown: false
%script#js-board-promotion{ type: "text/x-template" }= render_if_exists "shared/promotions/promote_issue_board"
-#board-app.boards-app{ "v-cloak" => true, data: board_data, ":class" => "{ 'is-compact': detailIssueVisible }" }
+#board-app.boards-app.position-relative{ "v-cloak" => "true", data: board_data, ":class" => "{ 'is-compact': detailIssueVisible }" }
.d-none.d-sm-none.d-md-block
= render 'shared/issuable/search_bar', type: :boards, board: board
- .boards-list
- .boards-app-loading.text-center{ "v-if" => "loading" }
- = icon("spinner spin")
- %board{ "v-cloak" => true,
+ .boards-list.w-100.py-3.px-2.text-nowrap
+ .boards-app-loading.w-100.text-center{ "v-if" => "loading" }
+ = icon("spinner spin 2x")
+ %board{ "v-cloak" => "true",
"v-for" => "list in state.lists",
"ref" => "board",
":list" => "list",
diff --git a/app/views/shared/boards/components/_board.html.haml b/app/views/shared/boards/components/_board.html.haml
index 307a0919a4c..f9cfcabc015 100644
--- a/app/views/shared/boards/components/_board.html.haml
+++ b/app/views/shared/boards/components/_board.html.haml
@@ -1,8 +1,8 @@
-.board{ ":class" => '{ "is-draggable": !list.preset, "is-expandable": list.isExpandable, "is-collapsed": !list.isExpanded, "board-type-assignee": list.type === "assignee" }',
+.board.d-inline-block.h-100.px-2.align-top.ws-normal{ ":class" => '{ "is-draggable": !list.preset, "is-expandable": list.isExpandable, "is-collapsed": !list.isExpanded, "board-type-assignee": list.type === "assignee" }',
":data-id" => "list.id" }
- .board-inner.d-flex.flex-column
- %header.board-header{ ":class" => '{ "has-border": list.label && list.label.color }', ":style" => "{ borderTopColor: (list.label && list.label.color ? list.label.color : null) }", "@click" => "toggleExpanded($event)" }
- %h3.board-title.js-board-handle{ ":class" => '{ "user-can-drag": (!disabled && !list.preset) }' }
+ .board-inner.d-flex.flex-column.position-relative.h-100.rounded
+ %header.board-header{ ":class" => '{ "has-border": list.label && list.label.color, "position-relative": list.isExpanded, "position-absolute position-top-0 position-left-0 w-100 h-100": !list.isExpanded }', ":style" => "{ borderTopColor: (list.label && list.label.color ? list.label.color : null) }", "@click" => "toggleExpanded($event)" }
+ %h3.board-title.m-0.d-flex.align-items-center.py-2.px-3.js-board-handle{ ":class" => '{ "user-can-drag": (!disabled && !list.preset), "p-0 border-bottom-0 justify-content-center": !list.isExpanded }' }
%i.fa.fa-fw.board-title-expandable-toggle{ "v-if": "list.isExpandable",
":class": "{ \"fa-caret-down\": list.isExpanded, \"fa-caret-right\": !list.isExpanded }",
"aria-hidden": "true" }
@@ -31,9 +31,9 @@
%board-delete{ "inline-template" => true,
":list" => "list",
"v-if" => "!list.preset && list.id" }
- %button.board-delete.has-tooltip.float-right{ type: "button", title: _("Delete list"), "aria-label" => _("Delete list"), data: { placement: "bottom" }, "@click.stop" => "deleteBoard" }
+ %button.board-delete.p-0.border-0.has-tooltip.float-right{ type: "button", title: _("Delete list"), ":class": "{ 'd-none': !list.isExpanded }", "aria-label" => _("Delete list"), data: { placement: "bottom" }, "@click.stop" => "deleteBoard" }
= icon("trash")
- .issue-count-badge.text-secondary{ "v-if" => 'list.type !== "blank" && list.type !== "promotion"', ":title": "counterTooltip", "v-tooltip": true, data: { placement: "top" } }
+ .issue-count-badge.text-secondary{ "v-if" => 'list.type !== "blank" && list.type !== "promotion"', ":title": "counterTooltip", ":class": "{ 'd-none': !list.isExpanded }", "v-tooltip": true, data: { placement: "top" } }
%span.issue-count-badge-count
%icon.mr-1{ name: "issues" }
{{ list.issuesSize }}
@@ -42,6 +42,7 @@
%button.issue-count-badge-add-button.btn.btn-sm.btn-default.ml-1.has-tooltip.js-no-trigger-collapse{ type: "button",
"@click" => "showNewIssueForm",
"v-if" => "isNewIssueShown",
+ ":class": "{ 'd-none': !list.isExpanded }",
"aria-label" => _("New issue"),
"title" => _("New issue"),
data: { placement: "top", container: "body" } }
diff --git a/app/views/shared/boards/components/_sidebar.html.haml b/app/views/shared/boards/components/_sidebar.html.haml
index 30e51ecc261..b4f75967a67 100644
--- a/app/views/shared/boards/components/_sidebar.html.haml
+++ b/app/views/shared/boards/components/_sidebar.html.haml
@@ -2,16 +2,16 @@
%transition{ name: "boards-sidebar-slide" }
%aside.right-sidebar.right-sidebar-expanded.issue-boards-sidebar{ "v-show" => "showSidebar" }
.issuable-sidebar
- .block.issuable-sidebar-header
+ .block.issuable-sidebar-header.position-relative
%span.issuable-header-text.hide-collapsed.float-left
- %strong
+ %strong.bold
{{ issue.title }}
%br/
%span
= render_if_exists "shared/boards/components/sidebar/issue_project_path"
= precede "#" do
{{ issue.iid }}
- %a.gutter-toggle.float-right{ role: "button",
+ %a.gutter-toggle.position-absolute.position-top-0.position-right-0{ role: "button",
href: "#",
"@click.prevent" => "closeSidebar",
"aria-label" => "Toggle sidebar" }
diff --git a/app/views/shared/issuable/_label_page_default.html.haml b/app/views/shared/issuable/_label_page_default.html.haml
index aa4a5f0e0d3..a0fb5229fc3 100644
--- a/app/views/shared/issuable/_label_page_default.html.haml
+++ b/app/views/shared/issuable/_label_page_default.html.haml
@@ -11,7 +11,7 @@
= dropdown_title(title)
- if show_boards_content
.issue-board-dropdown-content
- %p
+ %p.m-0
= content_title
= dropdown_filter(filter_placeholder)
= dropdown_content
diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml
index 2bcfcb6fa7c..3d6c5d29d44 100644
--- a/app/views/shared/issuable/_search_bar.html.haml
+++ b/app/views/shared/issuable/_search_bar.html.haml
@@ -3,11 +3,11 @@
- block_css_class = type != :boards_modal ? 'row-content-block second-block' : ''
- user_can_admin_list = board && can?(current_user, :admin_list, board.parent)
-.issues-filters
- .issues-details-filters.filtered-search-block{ class: block_css_class, "v-pre" => type == :boards_modal }
+.issues-filters{ class: ("w-100" if type == :boards_modal) }
+ .issues-details-filters.filtered-search-block.d-flex{ class: block_css_class, "v-pre" => type == :boards_modal }
- if type == :boards
= render_if_exists "shared/boards/switcher", board: board
- = form_tag page_filter_path, method: :get, class: 'filter-form js-filter-form' do
+ = form_tag page_filter_path, method: :get, class: 'filter-form js-filter-form w-100' do
- if params[:search].present?
= hidden_field_tag :search, params[:search]
- if @can_bulk_update
diff --git a/changelogs/unreleased/10012-move-ee-diff-for-boards-issue-card-inner.yml b/changelogs/unreleased/10012-move-ee-diff-for-boards-issue-card-inner.yml
new file mode 100644
index 00000000000..f15375e83f4
--- /dev/null
+++ b/changelogs/unreleased/10012-move-ee-diff-for-boards-issue-card-inner.yml
@@ -0,0 +1,5 @@
+---
+title: Move ee-specific code from boards/components/issue_card_inner.vue
+merge_request: 27394
+author: Roman Rodionov
+type: other
diff --git a/changelogs/unreleased/10029-env-item.yml b/changelogs/unreleased/10029-env-item.yml
deleted file mode 100644
index f4e742d3e17..00000000000
--- a/changelogs/unreleased/10029-env-item.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Removes EE differences for environment_item.vue
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/10081-env-table.yml b/changelogs/unreleased/10081-env-table.yml
deleted file mode 100644
index b27a1be8cca..00000000000
--- a/changelogs/unreleased/10081-env-table.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Removes EE differences for environments_table.vue
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/10735-geo-gitlab-revision-can-return-not-consistent-results.yml b/changelogs/unreleased/10735-geo-gitlab-revision-can-return-not-consistent-results.yml
deleted file mode 100644
index 2360295b022..00000000000
--- a/changelogs/unreleased/10735-geo-gitlab-revision-can-return-not-consistent-results.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Use a fixed git abbrev parameter when we fetch a git revision
-merge_request: 26707
-author:
-type: fixed
diff --git a/changelogs/unreleased/11124-update-deployment-service-fails-if-project-is-nil.yml b/changelogs/unreleased/11124-update-deployment-service-fails-if-project-is-nil.yml
deleted file mode 100644
index 355743f4cb0..00000000000
--- a/changelogs/unreleased/11124-update-deployment-service-fails-if-project-is-nil.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Always return the deployment in the UpdateDeploymentService#execute method
-merge_request: 27322
-author:
-type: fixed
diff --git a/changelogs/unreleased/13784-validate-variables-for-masking.yml b/changelogs/unreleased/13784-validate-variables-for-masking.yml
deleted file mode 100644
index e8e97fac3d2..00000000000
--- a/changelogs/unreleased/13784-validate-variables-for-masking.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add control for masking variable values in runner logs
-merge_request: 26751
-author:
-type: added
diff --git a/changelogs/unreleased/24936-remove-type-from-review-app-name.yml b/changelogs/unreleased/24936-remove-type-from-review-app-name.yml
deleted file mode 100644
index 639333264f6..00000000000
--- a/changelogs/unreleased/24936-remove-type-from-review-app-name.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove unnecessary folder prefix from environment name
-merge_request: 25600
-author:
-type: changed
diff --git a/changelogs/unreleased/24971-align-emailvalidator-to-validate_email-gem-implementation.yml b/changelogs/unreleased/24971-align-emailvalidator-to-validate_email-gem-implementation.yml
deleted file mode 100644
index 04dbc3a1d5a..00000000000
--- a/changelogs/unreleased/24971-align-emailvalidator-to-validate_email-gem-implementation.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Align EmailValidator to validate_email gem implementation
-merge_request: 24971
-author: Horatiu Eugen Vlad
-type: fixed
diff --git a/changelogs/unreleased/25942-remove-fake-repository-path-response.yml b/changelogs/unreleased/25942-remove-fake-repository-path-response.yml
deleted file mode 100644
index e1da28ab03c..00000000000
--- a/changelogs/unreleased/25942-remove-fake-repository-path-response.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove fake repository_path response
-merge_request: 25942
-author: Fabio Papa
-type: other
diff --git a/changelogs/unreleased/29249-show-download-diff-even-when-merge-request-is-closed.yml b/changelogs/unreleased/29249-show-download-diff-even-when-merge-request-is-closed.yml
deleted file mode 100644
index 5942860a20f..00000000000
--- a/changelogs/unreleased/29249-show-download-diff-even-when-merge-request-is-closed.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Show download diff links for closed MRs
-merge_request: 26772
-author:
-type: changed
diff --git a/changelogs/unreleased/38564-cant-leave-subgroup.yml b/changelogs/unreleased/38564-cant-leave-subgroup.yml
deleted file mode 100644
index a6397062343..00000000000
--- a/changelogs/unreleased/38564-cant-leave-subgroup.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow removing last owner from subgroup if parent group has owners
-merge_request: 26718
-author:
-type: changed
diff --git a/changelogs/unreleased/43263-git-push-option-to-create-mr.yml b/changelogs/unreleased/43263-git-push-option-to-create-mr.yml
deleted file mode 100644
index d50c33da162..00000000000
--- a/changelogs/unreleased/43263-git-push-option-to-create-mr.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow merge requests to be created via git push options
-merge_request: 26752
-author:
-type: added
diff --git a/changelogs/unreleased/43297-authorized-application-count.yml b/changelogs/unreleased/43297-authorized-application-count.yml
deleted file mode 100644
index d22e155fb14..00000000000
--- a/changelogs/unreleased/43297-authorized-application-count.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix authorized application count
-merge_request: 25715
-author: moyuru
-type: fixed
diff --git a/changelogs/unreleased/46787-create-project-label-window-is-cut-off-at-the-bottom.yml b/changelogs/unreleased/46787-create-project-label-window-is-cut-off-at-the-bottom.yml
deleted file mode 100644
index dca1d57d14e..00000000000
--- a/changelogs/unreleased/46787-create-project-label-window-is-cut-off-at-the-bottom.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed - Create project label window is cut off at the bottom
-merge_request: 26049
-author:
-type: fixed
diff --git a/changelogs/unreleased/47234-composable-auto-devops.yml b/changelogs/unreleased/47234-composable-auto-devops.yml
deleted file mode 100644
index 9403c5ae6d3..00000000000
--- a/changelogs/unreleased/47234-composable-auto-devops.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Split Auto-DevOps.gitlab-ci.yml into reusable templates
-merge_request: 26520
-author:
-type: changed
diff --git a/changelogs/unreleased/47771-highlighting-in-diff.yml b/changelogs/unreleased/47771-highlighting-in-diff.yml
deleted file mode 100644
index a8e8cbf0174..00000000000
--- a/changelogs/unreleased/47771-highlighting-in-diff.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enabled text selection highlighting in diffs in Web IDE
-merge_request: 26721
-author: Isaac Smith
-type: fixed
diff --git a/changelogs/unreleased/48090-filter-sensitive-metric-labels.yml b/changelogs/unreleased/48090-filter-sensitive-metric-labels.yml
deleted file mode 100644
index e588fa79619..00000000000
--- a/changelogs/unreleased/48090-filter-sensitive-metric-labels.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove `path` and `branch` labels from metrics
-merge_request: 26744
-author:
-type: fixed
diff --git a/changelogs/unreleased/48132-display-output-from-pre-receive-scripts.yml b/changelogs/unreleased/48132-display-output-from-pre-receive-scripts.yml
deleted file mode 100644
index e06a4d5ee75..00000000000
--- a/changelogs/unreleased/48132-display-output-from-pre-receive-scripts.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: "Allow failed custom hook script errors to safely appear in GitLab UI by filtering error messages by the prefix GL-HOOK-ERR:"
-merge_request: 25625
-author:
-type: changed
diff --git a/changelogs/unreleased/48297-fix-code-selection.yml b/changelogs/unreleased/48297-fix-code-selection.yml
deleted file mode 100644
index 14841b00969..00000000000
--- a/changelogs/unreleased/48297-fix-code-selection.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Resolve Code in other column of side-by-side diff is highlighted when selecting
- code on one side
-merge_request: 26423
-author:
-type: fixed
diff --git a/changelogs/unreleased/49856-upgrade-bootstrap-form-gem.yml b/changelogs/unreleased/49856-upgrade-bootstrap-form-gem.yml
deleted file mode 100644
index 1dc8d5b4179..00000000000
--- a/changelogs/unreleased/49856-upgrade-bootstrap-form-gem.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Upgrade bootstrap_form Gem
-merge_request: 26568
-author:
-type: other
diff --git a/changelogs/unreleased/49863-ingress-ip-loading-state.yml b/changelogs/unreleased/49863-ingress-ip-loading-state.yml
deleted file mode 100644
index 51bb27d3153..00000000000
--- a/changelogs/unreleased/49863-ingress-ip-loading-state.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Show loading spinner while Ingress/Knative IP is being assigned
-merge_request: 25912
-author:
-type: changed
diff --git a/changelogs/unreleased/49910-reopening-a-closed-milestone-from-the-closed-milestones-page-fails2.yml b/changelogs/unreleased/49910-reopening-a-closed-milestone-from-the-closed-milestones-page-fails2.yml
deleted file mode 100644
index 68d38cd56c5..00000000000
--- a/changelogs/unreleased/49910-reopening-a-closed-milestone-from-the-closed-milestones-page-fails2.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix bug when reopening milestone from index page
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/51988-install-group-runner-on-group-cluster.yml b/changelogs/unreleased/51988-install-group-runner-on-group-cluster.yml
deleted file mode 100644
index 86f08dd1798..00000000000
--- a/changelogs/unreleased/51988-install-group-runner-on-group-cluster.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Support installing Group runner on group-level cluster
-merge_request: 26260
-author:
-type: added
diff --git a/changelogs/unreleased/52258-labels-with-long-names-overflow-on-metrics-dashboard.yml b/changelogs/unreleased/52258-labels-with-long-names-overflow-on-metrics-dashboard.yml
deleted file mode 100644
index 5dd25d0ffc1..00000000000
--- a/changelogs/unreleased/52258-labels-with-long-names-overflow-on-metrics-dashboard.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix long label overflow on metrics dashboard
-merge_request: 26775
-author:
-type: fixed
diff --git a/changelogs/unreleased/52366-improved-group-lists-ui-spinners.yml b/changelogs/unreleased/52366-improved-group-lists-ui-spinners.yml
deleted file mode 100644
index ab09272eaf4..00000000000
--- a/changelogs/unreleased/52366-improved-group-lists-ui-spinners.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update spinners in group list component
-merge_request: 26572
-author:
-type: changed
diff --git a/changelogs/unreleased/52447-auto-devops-at-group-level.yml b/changelogs/unreleased/52447-auto-devops-at-group-level.yml
deleted file mode 100644
index 0a21c6a2b7b..00000000000
--- a/changelogs/unreleased/52447-auto-devops-at-group-level.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enable/disable Auto DevOps at the Group level
-merge_request: 25533
-author:
-type: added
diff --git a/changelogs/unreleased/52560-fix-duplicate-tag-system-hooks.yml b/changelogs/unreleased/52560-fix-duplicate-tag-system-hooks.yml
deleted file mode 100644
index b8d58d6bd30..00000000000
--- a/changelogs/unreleased/52560-fix-duplicate-tag-system-hooks.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Only execute system hooks once when pushing tags
-merge_request: 26888
-author:
-type: fixed
diff --git a/changelogs/unreleased/53139-hide-tree-single-file.yml b/changelogs/unreleased/53139-hide-tree-single-file.yml
deleted file mode 100644
index 17fe957e42e..00000000000
--- a/changelogs/unreleased/53139-hide-tree-single-file.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: collapse file tree by default if the merge request changes only one file
-merge_request:
-author: Riccardo Padovani <riccardo@rpadovani.com>
-type: changed
diff --git a/changelogs/unreleased/53198-git-push-option-merge-when-pipeline-succeeds.yml b/changelogs/unreleased/53198-git-push-option-merge-when-pipeline-succeeds.yml
deleted file mode 100644
index 6fefd05049c..00000000000
--- a/changelogs/unreleased/53198-git-push-option-merge-when-pipeline-succeeds.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Allow merge requests to be set to merge when pipeline succeeds via git push
- options
-merge_request: 26842
-author:
-type: added
diff --git a/changelogs/unreleased/53210-add-uniq-constraints-on-issues-and-mrs-labels.yml b/changelogs/unreleased/53210-add-uniq-constraints-on-issues-and-mrs-labels.yml
deleted file mode 100644
index f9cd8716b92..00000000000
--- a/changelogs/unreleased/53210-add-uniq-constraints-on-issues-and-mrs-labels.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: add a uniq constraints on issues and mrs labels
-merge_request: 25435
-author: Antoine Huret
-type: fixed
diff --git a/changelogs/unreleased/53459-quick-action-adds-multiple-labels-to-issue-if-middle-words-overlap-with-existing-label.yml b/changelogs/unreleased/53459-quick-action-adds-multiple-labels-to-issue-if-middle-words-overlap-with-existing-label.yml
deleted file mode 100644
index 30d8c0e95d7..00000000000
--- a/changelogs/unreleased/53459-quick-action-adds-multiple-labels-to-issue-if-middle-words-overlap-with-existing-label.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix quick actions add label name middle word overlaps
-merge_request: 26602
-author: Jacopo Beschi @jacopo-beschi
-type: fixed
diff --git a/changelogs/unreleased/54417-graphql-type-authorization.yml b/changelogs/unreleased/54417-graphql-type-authorization.yml
deleted file mode 100644
index 528b58a858a..00000000000
--- a/changelogs/unreleased/54417-graphql-type-authorization.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: GraphQL Types can be made to always authorize access to resources of that Type
-merge_request: 25724
-author:
-type: added
diff --git a/changelogs/unreleased/54506-show-error-when-namespace-svc-missing.yml b/changelogs/unreleased/54506-show-error-when-namespace-svc-missing.yml
deleted file mode 100644
index 3e3784d5413..00000000000
--- a/changelogs/unreleased/54506-show-error-when-namespace-svc-missing.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Show error when namespace/svc account missing
-merge_request: 26362
-author:
-type: added
diff --git a/changelogs/unreleased/54670-external-diffs-when-outdated.yml b/changelogs/unreleased/54670-external-diffs-when-outdated.yml
deleted file mode 100644
index 2a0b9e75cb4..00000000000
--- a/changelogs/unreleased/54670-external-diffs-when-outdated.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Allow external diffs to be used conditionally'
-merge_request: 25432
-author:
-type: added
diff --git a/changelogs/unreleased/54916-extended-tooltip-for-merge-request-links.yml b/changelogs/unreleased/54916-extended-tooltip-for-merge-request-links.yml
deleted file mode 100644
index 7fd0bcd1c00..00000000000
--- a/changelogs/unreleased/54916-extended-tooltip-for-merge-request-links.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add extended merge request tooltip
-merge_request: !25221
-author:
-type: added
diff --git a/changelogs/unreleased/55268-exclude-system-notes-from-commits-in-mr.yml b/changelogs/unreleased/55268-exclude-system-notes-from-commits-in-mr.yml
deleted file mode 100644
index 7af4739136b..00000000000
--- a/changelogs/unreleased/55268-exclude-system-notes-from-commits-in-mr.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Exclude system notes from commits in merge request discussions
-merge_request: 26396
-author:
-type: fixed
diff --git a/changelogs/unreleased/55964-fix-email-encoding.yml b/changelogs/unreleased/55964-fix-email-encoding.yml
deleted file mode 100644
index 2195a853702..00000000000
--- a/changelogs/unreleased/55964-fix-email-encoding.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix notfication emails having wrong encoding
-merge_request: 26931
-author:
-type: fixed
diff --git a/changelogs/unreleased/55980-remove-add-issue-on-blank-list.yml b/changelogs/unreleased/55980-remove-add-issue-on-blank-list.yml
deleted file mode 100644
index 4c16b635297..00000000000
--- a/changelogs/unreleased/55980-remove-add-issue-on-blank-list.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove non-functional add issue button on welcome list
-merge_request: !26742
-author:
-type: fixed
diff --git a/changelogs/unreleased/56015-remove-remote-timeout.yml b/changelogs/unreleased/56015-remove-remote-timeout.yml
deleted file mode 100644
index 9b40ada5291..00000000000
--- a/changelogs/unreleased/56015-remove-remote-timeout.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix removing remote mirror failure which leaves unnecessary refs behind
-merge_request: 26213
-author:
-type: fixed
diff --git a/changelogs/unreleased/56089-merge-gitlab-keys.yml b/changelogs/unreleased/56089-merge-gitlab-keys.yml
deleted file mode 100644
index 5e2cafd3254..00000000000
--- a/changelogs/unreleased/56089-merge-gitlab-keys.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Merge the gitlab-shell "gitlab-keys" functionality into GitLab CE
-merge_request: 25598
-author:
-type: other
diff --git a/changelogs/unreleased/56762-fix-commit-swipe-view-26968.yml b/changelogs/unreleased/56762-fix-commit-swipe-view-26968.yml
deleted file mode 100644
index 18bd51711d9..00000000000
--- a/changelogs/unreleased/56762-fix-commit-swipe-view-26968.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: "Fix image diff swipe view on commit and compare pages"
-merge_request: 26968
-author: ftab
-type: fixed \ No newline at end of file
diff --git a/changelogs/unreleased/56833-project-improve-empty-repository-state-ui-fe.yml b/changelogs/unreleased/56833-project-improve-empty-repository-state-ui-fe.yml
deleted file mode 100644
index 19cf3d69db1..00000000000
--- a/changelogs/unreleased/56833-project-improve-empty-repository-state-ui-fe.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Project: Improve empty repository state UI'
-merge_request: 26024
-author:
-type: other
diff --git a/changelogs/unreleased/56864-reopen-locked-mr.yml b/changelogs/unreleased/56864-reopen-locked-mr.yml
deleted file mode 100644
index d1d71531ac8..00000000000
--- a/changelogs/unreleased/56864-reopen-locked-mr.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Disallow reopening of a locked merge request
-merge_request: 24882
-author: Jan Beckmann
-type: fixed
diff --git a/changelogs/unreleased/56954-improve-knative-after-installing-tiller.yml b/changelogs/unreleased/56954-improve-knative-after-installing-tiller.yml
deleted file mode 100644
index b9fb27c3218..00000000000
--- a/changelogs/unreleased/56954-improve-knative-after-installing-tiller.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Improve the Knative installation on Clusters
-merge_request: 26339
-author:
-type: added
diff --git a/changelogs/unreleased/57115-just-in-time-k8s-resource-creation.yml b/changelogs/unreleased/57115-just-in-time-k8s-resource-creation.yml
deleted file mode 100644
index 2141c75ec72..00000000000
--- a/changelogs/unreleased/57115-just-in-time-k8s-resource-creation.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Create Kubernetes resources for projects when their deployment jobs run.
-merge_request: 25586
-author:
-type: changed
diff --git a/changelogs/unreleased/57131-external_auth_to_core.yml b/changelogs/unreleased/57131-external_auth_to_core.yml
deleted file mode 100644
index aacd3916c82..00000000000
--- a/changelogs/unreleased/57131-external_auth_to_core.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Move "Authorize project access with external service" to Core
-merge_request: 26823
-author:
-type: changed
diff --git a/changelogs/unreleased/57319-hide-kubernetes-cluster-warning-if-project-has-cluster-related.yml b/changelogs/unreleased/57319-hide-kubernetes-cluster-warning-if-project-has-cluster-related.yml
deleted file mode 100644
index a6953a68a76..00000000000
--- a/changelogs/unreleased/57319-hide-kubernetes-cluster-warning-if-project-has-cluster-related.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Resolve "Hide Kubernetes cluster warning if project has cluster related"
-merge_request: 26749
-author:
-type: fixed
diff --git a/changelogs/unreleased/57357-automate-base-domain-help-text.yml b/changelogs/unreleased/57357-automate-base-domain-help-text.yml
deleted file mode 100644
index fa1831b66ea..00000000000
--- a/changelogs/unreleased/57357-automate-base-domain-help-text.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Automate base domain help text on Clusters page
-merge_request: 26124
-author:
-type: changed
diff --git a/changelogs/unreleased/57364-improve-diff-nav-header.yml b/changelogs/unreleased/57364-improve-diff-nav-header.yml
deleted file mode 100644
index 95d119b949c..00000000000
--- a/changelogs/unreleased/57364-improve-diff-nav-header.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Make stylistic improvements to diff nav header
-merge_request: 26557
-author:
-type: fixed
diff --git a/changelogs/unreleased/57409-loading-button-transition.yml b/changelogs/unreleased/57409-loading-button-transition.yml
deleted file mode 100644
index 3cf169d79de..00000000000
--- a/changelogs/unreleased/57409-loading-button-transition.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Prevent fade out transition on loading-button component.
-merge_request: 26428
-author:
-type: fixed
diff --git a/changelogs/unreleased/57482-shortcut-to-create-merge-request-from-web-ide.yml b/changelogs/unreleased/57482-shortcut-to-create-merge-request-from-web-ide.yml
deleted file mode 100644
index c188d59fe94..00000000000
--- a/changelogs/unreleased/57482-shortcut-to-create-merge-request-from-web-ide.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Create a shortcut for a new MR in the Web IDE
-merge_request: 26792
-author:
-type: added
diff --git a/changelogs/unreleased/57493-add-limit-to-user-name.yml b/changelogs/unreleased/57493-add-limit-to-user-name.yml
deleted file mode 100644
index e6c78572d23..00000000000
--- a/changelogs/unreleased/57493-add-limit-to-user-name.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Set user.name limit to 128 characters
-merge_request: 26146
-author:
-type: changed
diff --git a/changelogs/unreleased/57540-filename-trailing-space.yml b/changelogs/unreleased/57540-filename-trailing-space.yml
deleted file mode 100644
index db85fb350db..00000000000
--- a/changelogs/unreleased/57540-filename-trailing-space.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Implemented whitespace-trimming for file names in Web IDE
-merge_request: 26270
-author:
-type: fixed
diff --git a/changelogs/unreleased/57602-create-cluster-validations.yml b/changelogs/unreleased/57602-create-cluster-validations.yml
deleted file mode 100644
index 35349c1e9f4..00000000000
--- a/changelogs/unreleased/57602-create-cluster-validations.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Display cluster form validation error messages inline
-merge_request: 26502
-author:
-type: changed
diff --git a/changelogs/unreleased/57648-make-emoji-picker-full-width-on-mobile.yml b/changelogs/unreleased/57648-make-emoji-picker-full-width-on-mobile.yml
deleted file mode 100644
index d92fd2a762e..00000000000
--- a/changelogs/unreleased/57648-make-emoji-picker-full-width-on-mobile.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Makes emoji picker full width on mobile.
-merge_request: 25883
-author: Jacopo Beschi @jacopo-beschi
-type: fixed
diff --git a/changelogs/unreleased/57655-fix-markdown-tables-border.yml b/changelogs/unreleased/57655-fix-markdown-tables-border.yml
deleted file mode 100644
index 6a8ba8c4353..00000000000
--- a/changelogs/unreleased/57655-fix-markdown-tables-border.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix markdown table header and table content borders
-merge_request: 25666
-author:
-type: fixed
diff --git a/changelogs/unreleased/57668-create-file-from-url.yml b/changelogs/unreleased/57668-create-file-from-url.yml
deleted file mode 100644
index b6033fa24ca..00000000000
--- a/changelogs/unreleased/57668-create-file-from-url.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Implemented support for creation of new files from URL in Web IDE
-merge_request: 26622
-author:
-type: added
diff --git a/changelogs/unreleased/57669-fix-bug-clicking-file-header-refreshes-page.yml b/changelogs/unreleased/57669-fix-bug-clicking-file-header-refreshes-page.yml
deleted file mode 100644
index c6161870096..00000000000
--- a/changelogs/unreleased/57669-fix-bug-clicking-file-header-refreshes-page.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Scroll to diff file content when clicking on file header name and it is not
- a link to other page
-merge_request: !26422
-author:
-type: fixed
diff --git a/changelogs/unreleased/57894-buttons-on-group-page-are-misaligned.yml b/changelogs/unreleased/57894-buttons-on-group-page-are-misaligned.yml
deleted file mode 100644
index ca0f529df6c..00000000000
--- a/changelogs/unreleased/57894-buttons-on-group-page-are-misaligned.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix misalignment of group overview page buttons
-merge_request: 26292
-author:
-type: fixed
diff --git a/changelogs/unreleased/57984-store-branch-name.yml b/changelogs/unreleased/57984-store-branch-name.yml
deleted file mode 100644
index 26dfdb7a5d6..00000000000
--- a/changelogs/unreleased/57984-store-branch-name.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Resolves Branch name is lost if I change commit mode in Web IDE
-merge_request: 26180
-author:
-type: fixed
diff --git a/changelogs/unreleased/58208-explicitly-set-masterauth.yml b/changelogs/unreleased/58208-explicitly-set-masterauth.yml
deleted file mode 100644
index e3512d11113..00000000000
--- a/changelogs/unreleased/58208-explicitly-set-masterauth.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Explicitly set master_auth setting to enable basic auth and client certificate
- for new GKE clusters
-merge_request: 26018
-author:
-type: other
diff --git a/changelogs/unreleased/58293-extract-discussion-actions.yml b/changelogs/unreleased/58293-extract-discussion-actions.yml
new file mode 100644
index 00000000000..2ca4716a6de
--- /dev/null
+++ b/changelogs/unreleased/58293-extract-discussion-actions.yml
@@ -0,0 +1,5 @@
+---
+title: Extract DiscussionActions component from NoteableDiscussion
+merge_request: 27227
+author:
+type: other
diff --git a/changelogs/unreleased/58375-api-controller.yml b/changelogs/unreleased/58375-api-controller.yml
deleted file mode 100644
index 60f21b37ae7..00000000000
--- a/changelogs/unreleased/58375-api-controller.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add a Prometheus API per environment
-merge_request: 26841
-author:
-type: added
diff --git a/changelogs/unreleased/58375-reactive-caching-changes.yml b/changelogs/unreleased/58375-reactive-caching-changes.yml
deleted file mode 100644
index cf73736b8ef..00000000000
--- a/changelogs/unreleased/58375-reactive-caching-changes.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow reactive caching to be used in services
-merge_request: 26839
-author:
-type: added
diff --git a/changelogs/unreleased/58405-basic-limiting-complexity-of-graphql-queries.yml b/changelogs/unreleased/58405-basic-limiting-complexity-of-graphql-queries.yml
deleted file mode 100644
index 058a120b500..00000000000
--- a/changelogs/unreleased/58405-basic-limiting-complexity-of-graphql-queries.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add initial complexity limits to GraphQL queries
-merge_request: 26629
-author:
-type: performance
diff --git a/changelogs/unreleased/58410-change-pixel-size-of-instance-header-footer-message-to-16px.yml b/changelogs/unreleased/58410-change-pixel-size-of-instance-header-footer-message-to-16px.yml
deleted file mode 100644
index 3e494847e75..00000000000
--- a/changelogs/unreleased/58410-change-pixel-size-of-instance-header-footer-message-to-16px.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Reduce height of instance system header and footer
-merge_request: 25752
-author:
-type: changed
diff --git a/changelogs/unreleased/58482-update-airminc-clair-local-scan-to-2-0-6.yml b/changelogs/unreleased/58482-update-airminc-clair-local-scan-to-2-0-6.yml
deleted file mode 100644
index be9c38aba1e..00000000000
--- a/changelogs/unreleased/58482-update-airminc-clair-local-scan-to-2-0-6.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update clair-local-scan to 2.0.6
-merge_request: 25743
-author: Takuya Noguchi
-type: added
diff --git a/changelogs/unreleased/58717-checkbox-cannot-be-checked-if-a-blockquote-is-above.yml b/changelogs/unreleased/58717-checkbox-cannot-be-checked-if-a-blockquote-is-above.yml
deleted file mode 100644
index 9f5881966c7..00000000000
--- a/changelogs/unreleased/58717-checkbox-cannot-be-checked-if-a-blockquote-is-above.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow task lists that follow a blockquote to work correctly
-merge_request: 26937
-author:
-type: fixed
diff --git a/changelogs/unreleased/58739-hashed-storage-prevent-a-migration-and-rollback-running-at-the-same-time.yml b/changelogs/unreleased/58739-hashed-storage-prevent-a-migration-and-rollback-running-at-the-same-time.yml
deleted file mode 100644
index 765a991bb6a..00000000000
--- a/changelogs/unreleased/58739-hashed-storage-prevent-a-migration-and-rollback-running-at-the-same-time.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Hashed Storage: Prevent a migration and rollback running at the same time'
-merge_request: 25976
-author:
-type: changed
diff --git a/changelogs/unreleased/58751-fix-project-name-members-page.yml b/changelogs/unreleased/58751-fix-project-name-members-page.yml
deleted file mode 100644
index a295afc5c48..00000000000
--- a/changelogs/unreleased/58751-fix-project-name-members-page.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: "Fix unwanted character replacement on project members page caused by usage of sanitize function"
-merge_request: 25946
-author: Elias Werberich
-type: fixed
diff --git a/changelogs/unreleased/58781-silent-progress-in-auto-devops.yml b/changelogs/unreleased/58781-silent-progress-in-auto-devops.yml
deleted file mode 100644
index e45db8eafc3..00000000000
--- a/changelogs/unreleased/58781-silent-progress-in-auto-devops.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Use curl silent/show-error options on Auto DevOps
-merge_request: 25954
-author: Takuya Noguchi
-type: other
diff --git a/changelogs/unreleased/58789-some-system-notes-on-issuable-are-folded-on-mobile.yml b/changelogs/unreleased/58789-some-system-notes-on-issuable-are-folded-on-mobile.yml
deleted file mode 100644
index ebfb7aeaa1f..00000000000
--- a/changelogs/unreleased/58789-some-system-notes-on-issuable-are-folded-on-mobile.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Keep inline as much as possible in system notes on issuable
-merge_request: 25968
-author: Takuya Noguchi
-type: fixed
diff --git a/changelogs/unreleased/58793-fix-nav-links-archived-project.yml b/changelogs/unreleased/58793-fix-nav-links-archived-project.yml
deleted file mode 100644
index a8250804c34..00000000000
--- a/changelogs/unreleased/58793-fix-nav-links-archived-project.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: "Disable inaccessible navigation links upon archiving a project"
-merge_request: 26020
-author: Elias Werberich
-type: fixed
diff --git a/changelogs/unreleased/58797-broken-ui-on-a-closed-merge-request-from-a-deleted-source-project.yml b/changelogs/unreleased/58797-broken-ui-on-a-closed-merge-request-from-a-deleted-source-project.yml
deleted file mode 100644
index e30f48ed1a8..00000000000
--- a/changelogs/unreleased/58797-broken-ui-on-a-closed-merge-request-from-a-deleted-source-project.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix UI for closed MR when source project is removed
-merge_request: 25967
-author: Takuya Noguchi
-type: fixed
diff --git a/changelogs/unreleased/58805-allow-incomplete-commit-data-to-be-fetched-from-collection.yml b/changelogs/unreleased/58805-allow-incomplete-commit-data-to-be-fetched-from-collection.yml
deleted file mode 100644
index 4377ebfdbdf..00000000000
--- a/changelogs/unreleased/58805-allow-incomplete-commit-data-to-be-fetched-from-collection.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix merge commits being used as default squash commit messages
-merge_request: 26445
-author:
-type: fixed
diff --git a/changelogs/unreleased/58835-button-run-pipeline.yml b/changelogs/unreleased/58835-button-run-pipeline.yml
deleted file mode 100644
index 39407a60780..00000000000
--- a/changelogs/unreleased/58835-button-run-pipeline.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Changed button label at /pipelines/new
-merge_request: 26893
-author: antfobe,leonardofl
-type: other
diff --git a/changelogs/unreleased/58839-automatically-set-prometheus-step-interval.yml b/changelogs/unreleased/58839-automatically-set-prometheus-step-interval.yml
deleted file mode 100644
index 2c6edf45ae2..00000000000
--- a/changelogs/unreleased/58839-automatically-set-prometheus-step-interval.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Automatically set Prometheus step interval
-merge_request: 26441
-author:
-type: changed
diff --git a/changelogs/unreleased/58883-fix-fetching-comments.yml b/changelogs/unreleased/58883-fix-fetching-comments.yml
deleted file mode 100644
index 14c0f1687f2..00000000000
--- a/changelogs/unreleased/58883-fix-fetching-comments.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix error shown when loading links to specific comments
-merge_request: 26092
-author:
-type: fixed
diff --git a/changelogs/unreleased/58889-spinners-are-active-prematurely-in-bitbucket-cloud-import.yml b/changelogs/unreleased/58889-spinners-are-active-prematurely-in-bitbucket-cloud-import.yml
deleted file mode 100644
index ec357d9a832..00000000000
--- a/changelogs/unreleased/58889-spinners-are-active-prematurely-in-bitbucket-cloud-import.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix continuous bitbucket import loading spinner
-merge_request: 26175
-author:
-type: fixed
diff --git a/changelogs/unreleased/58933-broken-ui-on-commits-on-mobile.yml b/changelogs/unreleased/58933-broken-ui-on-commits-on-mobile.yml
deleted file mode 100644
index ca9f9dd21c9..00000000000
--- a/changelogs/unreleased/58933-broken-ui-on-commits-on-mobile.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix UI layout on Commits on mobile
-merge_request: 26133
-author: Takuya Noguchi
-type: fixed
diff --git a/changelogs/unreleased/58971-sentry-api-keyerror.yml b/changelogs/unreleased/58971-sentry-api-keyerror.yml
deleted file mode 100644
index 0f195c4b4f7..00000000000
--- a/changelogs/unreleased/58971-sentry-api-keyerror.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Handle missing keys in sentry api response
-merge_request: 26264
-author:
-type: fixed
diff --git a/changelogs/unreleased/58981-migrate-clusters-tests-to-jest.yml b/changelogs/unreleased/58981-migrate-clusters-tests-to-jest.yml
deleted file mode 100644
index 3df13dbb960..00000000000
--- a/changelogs/unreleased/58981-migrate-clusters-tests-to-jest.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Migrate clusters tests to jest
-merge_request: 27013
-author:
-type: other
diff --git a/changelogs/unreleased/59057-buttons-on-top-from-a-user-profile-page-on-mobile.yml b/changelogs/unreleased/59057-buttons-on-top-from-a-user-profile-page-on-mobile.yml
deleted file mode 100644
index febbbce2139..00000000000
--- a/changelogs/unreleased/59057-buttons-on-top-from-a-user-profile-page-on-mobile.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Improve mobile UI on User Profile page
-merge_request: 26240
-author: Takuya Noguchi
-type: other
diff --git a/changelogs/unreleased/59062-update-gitlab-markup-python-3.yml b/changelogs/unreleased/59062-update-gitlab-markup-python-3.yml
deleted file mode 100644
index 265a7e36841..00000000000
--- a/changelogs/unreleased/59062-update-gitlab-markup-python-3.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update gitlab-markup to 1.7.0 which requies python3
-merge_request: 26246
-author:
-type: changed
diff --git a/changelogs/unreleased/59079-fix-jupyter-render-loop.yml b/changelogs/unreleased/59079-fix-jupyter-render-loop.yml
deleted file mode 100644
index 29264b33dfa..00000000000
--- a/changelogs/unreleased/59079-fix-jupyter-render-loop.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix jupyter rendering bug that ended in an infinite loop
-merge_request: 26656
-author: ROSPARS Benoit
-type: fixed
diff --git a/changelogs/unreleased/59117-inconsistent-hover-behavior-on-navbar-items.yml b/changelogs/unreleased/59117-inconsistent-hover-behavior-on-navbar-items.yml
deleted file mode 100644
index eb9dcef4a89..00000000000
--- a/changelogs/unreleased/59117-inconsistent-hover-behavior-on-navbar-items.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix hover animation consistency in top navbar items
-merge_request: 26345
-author:
-type: fixed
diff --git a/changelogs/unreleased/59131-set-the-size-of-instance-system-message-text-12px.yml b/changelogs/unreleased/59131-set-the-size-of-instance-system-message-text-12px.yml
deleted file mode 100644
index 688190f4458..00000000000
--- a/changelogs/unreleased/59131-set-the-size-of-instance-system-message-text-12px.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update system message banner font size to 12px
-merge_request: 26293
-author:
-type: changed
diff --git a/changelogs/unreleased/59189-long-names-in-project-path-namespace-dropdown-breaks-past-container.yml b/changelogs/unreleased/59189-long-names-in-project-path-namespace-dropdown-breaks-past-container.yml
deleted file mode 100644
index bed7fcf2651..00000000000
--- a/changelogs/unreleased/59189-long-names-in-project-path-namespace-dropdown-breaks-past-container.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Prevent namespace dropdown in new project form from exceeding container
-merge_request: 26343
-author:
-type: fixed
diff --git a/changelogs/unreleased/59273-update-fugit.yml b/changelogs/unreleased/59273-update-fugit.yml
deleted file mode 100644
index 3a1c64d87ef..00000000000
--- a/changelogs/unreleased/59273-update-fugit.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update fugit which fixes a potential infinite loop
-merge_request: 26579
-author:
-type: fixed
diff --git a/changelogs/unreleased/59296-add-filter-by-title-milestones-api.yml b/changelogs/unreleased/59296-add-filter-by-title-milestones-api.yml
deleted file mode 100644
index 440b24a548c..00000000000
--- a/changelogs/unreleased/59296-add-filter-by-title-milestones-api.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add select by title to milestones API
-merge_request: 26573
-author:
-type: added
diff --git a/changelogs/unreleased/59324-queries-which-return-multiple-series-are-not-working-correctly.yml b/changelogs/unreleased/59324-queries-which-return-multiple-series-are-not-working-correctly.yml
deleted file mode 100644
index 9ab8d2b8596..00000000000
--- a/changelogs/unreleased/59324-queries-which-return-multiple-series-are-not-working-correctly.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix multiple series queries on metrics dashboard
-merge_request: 26514
-author:
-type: fixed
diff --git a/changelogs/unreleased/59352-fix-mr-discussion-expansion.yml b/changelogs/unreleased/59352-fix-mr-discussion-expansion.yml
deleted file mode 100644
index ab9ad53835c..00000000000
--- a/changelogs/unreleased/59352-fix-mr-discussion-expansion.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Expand resolved discussion when linking to a comment in the discussion
-merge_request: 26483
-author:
-type: fixed
diff --git a/changelogs/unreleased/59441-add-base-domain-to-cluster-api.yml b/changelogs/unreleased/59441-add-base-domain-to-cluster-api.yml
deleted file mode 100644
index cb5cbba4e92..00000000000
--- a/changelogs/unreleased/59441-add-base-domain-to-cluster-api.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add cluster domain to Project Cluster API
-merge_request: 26735
-author:
-type: other
diff --git a/changelogs/unreleased/59502-fix-breadcrumb-artifacts.yml b/changelogs/unreleased/59502-fix-breadcrumb-artifacts.yml
deleted file mode 100644
index da65c3bc870..00000000000
--- a/changelogs/unreleased/59502-fix-breadcrumb-artifacts.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixes job link in artifacts page breadcrumb
-merge_request: 26592
-author:
-type: fixed
diff --git a/changelogs/unreleased/59546-fix-error-handling-for-missing-domain.yml b/changelogs/unreleased/59546-fix-error-handling-for-missing-domain.yml
deleted file mode 100644
index 8f0ce5d57c5..00000000000
--- a/changelogs/unreleased/59546-fix-error-handling-for-missing-domain.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix Auto DevOps missing domain error handling
-merge_request: 26627
-author:
-type: fixed
diff --git a/changelogs/unreleased/59621-order-labels-alphabetically-in-issue-boards.yml b/changelogs/unreleased/59621-order-labels-alphabetically-in-issue-boards.yml
deleted file mode 100644
index 8b82d757303..00000000000
--- a/changelogs/unreleased/59621-order-labels-alphabetically-in-issue-boards.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Order labels alphabetically in issue boards
-merge_request: 26927
-author:
-type: changed
diff --git a/changelogs/unreleased/60006-add-touch-events-to-image-diff-26971.yml b/changelogs/unreleased/60006-add-touch-events-to-image-diff-26971.yml
deleted file mode 100644
index bfea3ac52af..00000000000
--- a/changelogs/unreleased/60006-add-touch-events-to-image-diff-26971.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: "Make touch events work on image diff swipe view and onion skin"
-merge_request: 26971
-author: ftab
-type: added
diff --git a/changelogs/unreleased/60068-avoid-null-domain-help-text.yml b/changelogs/unreleased/60068-avoid-null-domain-help-text.yml
deleted file mode 100644
index 5305b8584a8..00000000000
--- a/changelogs/unreleased/60068-avoid-null-domain-help-text.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Do not display Ingress IP help text when there isn’t an Ingress IP assigned
-merge_request: 27057
-author:
-type: fixed
diff --git a/changelogs/unreleased/60116-fix-button-wrapping.yml b/changelogs/unreleased/60116-fix-button-wrapping.yml
deleted file mode 100644
index d6df920b51d..00000000000
--- a/changelogs/unreleased/60116-fix-button-wrapping.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add to white-space nowrap to all buttons
-merge_request: 27069
-author:
-type: fixed
diff --git a/changelogs/unreleased/60149-nameerror-uninitialized-constant-sentry-client-sentryerror.yml b/changelogs/unreleased/60149-nameerror-uninitialized-constant-sentry-client-sentryerror.yml
deleted file mode 100644
index 8c3a47cf62c..00000000000
--- a/changelogs/unreleased/60149-nameerror-uninitialized-constant-sentry-client-sentryerror.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Handle possible HTTP exception for Sentry client
-merge_request: 27080
-author:
-type: fixed
diff --git a/changelogs/unreleased/60241-merge-request-popover-doesn-t-go-away-on-mouse-leave.yml b/changelogs/unreleased/60241-merge-request-popover-doesn-t-go-away-on-mouse-leave.yml
deleted file mode 100644
index ce942777dca..00000000000
--- a/changelogs/unreleased/60241-merge-request-popover-doesn-t-go-away-on-mouse-leave.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix bug where MR popover doesn't go away on mouse leave
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/60304-long-file-names-in-mr-diffs-cause-horizontal-scrolling.yml b/changelogs/unreleased/60304-long-file-names-in-mr-diffs-cause-horizontal-scrolling.yml
deleted file mode 100644
index ec5e9e4703b..00000000000
--- a/changelogs/unreleased/60304-long-file-names-in-mr-diffs-cause-horizontal-scrolling.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix long file header names bug in diffs
-merge_request: 27233
-author:
-type: fixed
diff --git a/changelogs/unreleased/MaxWinterstein-master-patch-23232.yml b/changelogs/unreleased/MaxWinterstein-master-patch-23232.yml
deleted file mode 100644
index 8fb9f1057fe..00000000000
--- a/changelogs/unreleased/MaxWinterstein-master-patch-23232.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Unify behaviour of 'Copy commit SHA to clipboard' to use full commit SHA.
-merge_request: 25829
-author: Max Winterstein
-type: changed
diff --git a/changelogs/unreleased/_acet-related-mrs-widget-rewrite.yml b/changelogs/unreleased/_acet-related-mrs-widget-rewrite.yml
deleted file mode 100644
index b773eb2720c..00000000000
--- a/changelogs/unreleased/_acet-related-mrs-widget-rewrite.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Rewrite related MRs widget with Vue
-merge_request: 27027
-author:
-type: other
diff --git a/changelogs/unreleased/add-runner-access-level-registration.yml b/changelogs/unreleased/add-runner-access-level-registration.yml
new file mode 100644
index 00000000000..7ae95025abb
--- /dev/null
+++ b/changelogs/unreleased/add-runner-access-level-registration.yml
@@ -0,0 +1,5 @@
+---
+title: Add option to set access_level of runners upon registration
+merge_request: 27490
+author: Zelin L
+type: added
diff --git a/changelogs/unreleased/add_backtrace_to_kubernetes_log.yml b/changelogs/unreleased/add_backtrace_to_kubernetes_log.yml
deleted file mode 100644
index 26b8ac4b1ef..00000000000
--- a/changelogs/unreleased/add_backtrace_to_kubernetes_log.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Show error backtrace when logging errors to kubernetes.log
-merge_request: 25726
-author:
-type: other
diff --git a/changelogs/unreleased/allow-filtering-labels-by-a-single-character.yml b/changelogs/unreleased/allow-filtering-labels-by-a-single-character.yml
deleted file mode 100644
index 31165bbadb7..00000000000
--- a/changelogs/unreleased/allow-filtering-labels-by-a-single-character.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow filtering labels list by one or two characters
-merge_request: 26012
-author:
-type: changed
diff --git a/changelogs/unreleased/allow-ref-name-caching-projects-controller.yml b/changelogs/unreleased/allow-ref-name-caching-projects-controller.yml
deleted file mode 100644
index 61236b9b82b..00000000000
--- a/changelogs/unreleased/allow-ref-name-caching-projects-controller.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enable FindCommit caching for project and commits pages
-merge_request: 27048
-author:
-type: performance
diff --git a/changelogs/unreleased/an-use-labkit.yml b/changelogs/unreleased/an-use-labkit.yml
new file mode 100644
index 00000000000..ab293c15787
--- /dev/null
+++ b/changelogs/unreleased/an-use-labkit.yml
@@ -0,0 +1,5 @@
+---
+title: Migrate correlation and tracing code to LabKit
+merge_request: 25379
+author:
+type: other
diff --git a/changelogs/unreleased/avoid_es_loading_project_ci_status.yml b/changelogs/unreleased/avoid_es_loading_project_ci_status.yml
deleted file mode 100644
index 514909c730d..00000000000
--- a/changelogs/unreleased/avoid_es_loading_project_ci_status.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Avoid loading pipeline status in project search
-merge_request: 26342
-author:
-type: performance
diff --git a/changelogs/unreleased/ce-10725-restructure-project-merge-request-settings-page.yml b/changelogs/unreleased/ce-10725-restructure-project-merge-request-settings-page.yml
new file mode 100644
index 00000000000..7aa9204fe4e
--- /dev/null
+++ b/changelogs/unreleased/ce-10725-restructure-project-merge-request-settings-page.yml
@@ -0,0 +1,5 @@
+---
+title: Reorganize project merge request settings
+merge_request: 26834
+author:
+type: changed
diff --git a/changelogs/unreleased/ce-56153-error-tracking-counts.yml b/changelogs/unreleased/ce-56153-error-tracking-counts.yml
deleted file mode 100644
index fc3d8c01d7f..00000000000
--- a/changelogs/unreleased/ce-56153-error-tracking-counts.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add usage counts for error tracking feature
-merge_request: 25472
-author:
-type: added
diff --git a/changelogs/unreleased/ce-proj-settings-ok-avatar-only.yml b/changelogs/unreleased/ce-proj-settings-ok-avatar-only.yml
deleted file mode 100644
index 10475824a75..00000000000
--- a/changelogs/unreleased/ce-proj-settings-ok-avatar-only.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Change project avatar remove button to a link
-merge_request: 26589
-author:
-type: other
diff --git a/changelogs/unreleased/ce-proj-settings-ok-mr-settings-only.yml b/changelogs/unreleased/ce-proj-settings-ok-mr-settings-only.yml
deleted file mode 100644
index 4bbbc706e62..00000000000
--- a/changelogs/unreleased/ce-proj-settings-ok-mr-settings-only.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Improve project merge request settings
-merge_request: 26495
-author:
-type: other
diff --git a/changelogs/unreleased/check-mergeability-in-merge-to-ref-service.yml b/changelogs/unreleased/check-mergeability-in-merge-to-ref-service.yml
deleted file mode 100644
index 9f615bbb54a..00000000000
--- a/changelogs/unreleased/check-mergeability-in-merge-to-ref-service.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Check mergeability in MergeToRefService
-merge_request: 26757
-author:
-type: changed
diff --git a/changelogs/unreleased/create-label-and-list-checkbox.yml b/changelogs/unreleased/create-label-and-list-checkbox.yml
deleted file mode 100644
index 330372df1be..00000000000
--- a/changelogs/unreleased/create-label-and-list-checkbox.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Added "Add List" checkbox to create label dropdown to make creation of list optional'
-merge_request: 25716
-author: Tucker Chapman
-type: fixed
diff --git a/changelogs/unreleased/delete-release-when-delete-tag.yml b/changelogs/unreleased/delete-release-when-delete-tag.yml
deleted file mode 100644
index 58acd449bf1..00000000000
--- a/changelogs/unreleased/delete-release-when-delete-tag.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Releases will now be automatically deleted when deleting corresponding tag
-merge_request: 26530
-author:
-type: fixed
diff --git a/changelogs/unreleased/deploy-keys-ext.yml b/changelogs/unreleased/deploy-keys-ext.yml
deleted file mode 100644
index e1d2fe08425..00000000000
--- a/changelogs/unreleased/deploy-keys-ext.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Externalize admin deploy keys strings
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/disallow-guests-to-access-releases.yml b/changelogs/unreleased/disallow-guests-to-access-releases.yml
deleted file mode 100644
index f2d518108d2..00000000000
--- a/changelogs/unreleased/disallow-guests-to-access-releases.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Disallow guest users from accessing Releases
-merge_request:
-author:
-type: security
diff --git a/changelogs/unreleased/do-not-force-2fa.yml b/changelogs/unreleased/do-not-force-2fa.yml
deleted file mode 100644
index f9be40e8f37..00000000000
--- a/changelogs/unreleased/do-not-force-2fa.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Add link on two-factor authorization settings page to leave group that enforces
- two-factor authorization
-merge_request: 25731
-author:
-type: changed
diff --git a/changelogs/unreleased/drop-usage-of-leagcy-artifacts.yml b/changelogs/unreleased/drop-usage-of-leagcy-artifacts.yml
deleted file mode 100644
index d99187d8d41..00000000000
--- a/changelogs/unreleased/drop-usage-of-leagcy-artifacts.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Drop legacy artifacts usage as there are no leftovers
-merge_request: 24294
-author:
-type: performance
diff --git a/changelogs/unreleased/duplicate-related-mrs.yml b/changelogs/unreleased/duplicate-related-mrs.yml
deleted file mode 100644
index 0f5f6ede9f8..00000000000
--- a/changelogs/unreleased/duplicate-related-mrs.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove duplicates from issue related merge requests
-merge_request: 27067
-author:
-type: fixed
diff --git a/changelogs/unreleased/ekigbo-extend-timezone-dropdown.yml b/changelogs/unreleased/ekigbo-extend-timezone-dropdown.yml
deleted file mode 100644
index 42bc320a542..00000000000
--- a/changelogs/unreleased/ekigbo-extend-timezone-dropdown.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Extend timezone dropdown
-merge_request: 26311
-author:
-type: changed
diff --git a/changelogs/unreleased/expose-group-id-on-home-panel.yml b/changelogs/unreleased/expose-group-id-on-home-panel.yml
deleted file mode 100644
index 1efe15a6e1a..00000000000
--- a/changelogs/unreleased/expose-group-id-on-home-panel.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Expose group id on home panel
-merge_request: 25897
-author: Peter Marko
-type: added
diff --git a/changelogs/unreleased/extend-cte-optimisations-to-projects.yml b/changelogs/unreleased/extend-cte-optimisations-to-projects.yml
deleted file mode 100644
index e5407127b2f..00000000000
--- a/changelogs/unreleased/extend-cte-optimisations-to-projects.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Speed up filtering issues in a project when searching
-merge_request:
-author:
-type: performance
diff --git a/changelogs/unreleased/feature-gb-serverless-switch-to-gitlabktl.yml b/changelogs/unreleased/feature-gb-serverless-switch-to-gitlabktl.yml
deleted file mode 100644
index 81cf5cb810d..00000000000
--- a/changelogs/unreleased/feature-gb-serverless-switch-to-gitlabktl.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Use gitlabktl to build and deploy GitLab Serverless Functions
-merge_request: 26926
-author:
-type: added
diff --git a/changelogs/unreleased/feature-users-search-results.yml b/changelogs/unreleased/feature-users-search-results.yml
deleted file mode 100644
index 151d08bce12..00000000000
--- a/changelogs/unreleased/feature-users-search-results.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add users search results to global search
-merge_request: 21197
-author: Alexis Reigel
-type: added
diff --git a/changelogs/unreleased/feature-webide_escaping.yml b/changelogs/unreleased/feature-webide_escaping.yml
deleted file mode 100644
index 88fa1bd948e..00000000000
--- a/changelogs/unreleased/feature-webide_escaping.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed bug with hashes in urls in WebIDE
-merge_request: 54376
-author: Kieran Andrews
-type: fixed
diff --git a/changelogs/unreleased/filter-merge-requests-by-target-branch.yml b/changelogs/unreleased/filter-merge-requests-by-target-branch.yml
deleted file mode 100644
index d0aba631c96..00000000000
--- a/changelogs/unreleased/filter-merge-requests-by-target-branch.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add target branch filter to merge requests search bar
-merge_request: 24380
-author: Hiroyuki Sato
-type: added
diff --git a/changelogs/unreleased/fix-UI-links-to-route-map-info.yml b/changelogs/unreleased/fix-UI-links-to-route-map-info.yml
deleted file mode 100644
index bb506507080..00000000000
--- a/changelogs/unreleased/fix-UI-links-to-route-map-info.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix UI anchor links after docs refactor
-merge_request: 26890
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-container-scanning-on-k8s.yml b/changelogs/unreleased/fix-container-scanning-on-k8s.yml
deleted file mode 100644
index f4500370a0b..00000000000
--- a/changelogs/unreleased/fix-container-scanning-on-k8s.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix Container Scanning in Kubernetes Runners
-merge_request: 26793
-author:
-type: changed
diff --git a/changelogs/unreleased/fix-expand-full-file-on-image.yml b/changelogs/unreleased/fix-expand-full-file-on-image.yml
deleted file mode 100644
index a88d30cfa38..00000000000
--- a/changelogs/unreleased/fix-expand-full-file-on-image.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed expand full file button showing on images
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-hidden-statistics.yml b/changelogs/unreleased/fix-hidden-statistics.yml
deleted file mode 100644
index 4d99bd00136..00000000000
--- a/changelogs/unreleased/fix-hidden-statistics.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Show statistics also when repository is disabled
-merge_request: 26509
-author: Peter Marko
-type: fixed
diff --git a/changelogs/unreleased/fix-ide-web-worker-relative-url.yml b/changelogs/unreleased/fix-ide-web-worker-relative-url.yml
deleted file mode 100644
index 2accad68c4e..00000000000
--- a/changelogs/unreleased/fix-ide-web-worker-relative-url.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed Web IDE web workers not working with relative URLs
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-include-ci-yaml.yml b/changelogs/unreleased/fix-include-ci-yaml.yml
deleted file mode 100644
index 042413b89aa..00000000000
--- a/changelogs/unreleased/fix-include-ci-yaml.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix single string values for the 'include' keyword validation of gitlab-ci.yml.
-merge_request: 26998
-author: Paul Bonaud (@paulrbr)
-type: fixed
diff --git a/changelogs/unreleased/fix-issues-time-counter.yml b/changelogs/unreleased/fix-issues-time-counter.yml
deleted file mode 100644
index 76f17063db5..00000000000
--- a/changelogs/unreleased/fix-issues-time-counter.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Make time counters show 'just now' for everything under one minute
-merge_request: 25992
-author: Sergiu Marton
-type: changed
diff --git a/changelogs/unreleased/fix-merge-request-relations-with-pipeline-on-mwps.yml b/changelogs/unreleased/fix-merge-request-relations-with-pipeline-on-mwps.yml
deleted file mode 100644
index 9ccc79109d8..00000000000
--- a/changelogs/unreleased/fix-merge-request-relations-with-pipeline-on-mwps.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix MWPS does not work for merge request pipelines
-merge_request: 26906
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-new-merge-request-diff-headers-sticky-position.yml b/changelogs/unreleased/fix-new-merge-request-diff-headers-sticky-position.yml
deleted file mode 100644
index dadbd5c940f..00000000000
--- a/changelogs/unreleased/fix-new-merge-request-diff-headers-sticky-position.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed sticky headers in merge request creation diffs
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-pipeline-entity.yml b/changelogs/unreleased/fix-pipeline-entity.yml
deleted file mode 100644
index b429139402c..00000000000
--- a/changelogs/unreleased/fix-pipeline-entity.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add merge request pipeline flag to pipeline entity
-merge_request: 25846
-author:
-type: added
diff --git a/changelogs/unreleased/fix-review-app-env-url.yml b/changelogs/unreleased/fix-review-app-env-url.yml
deleted file mode 100644
index 963cd0c2992..00000000000
--- a/changelogs/unreleased/fix-review-app-env-url.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixes long review app subdomains
-merge_request: 25990
-author: walkafwalka
-type: fixed
diff --git a/changelogs/unreleased/fix-routes-n-plus-one-in-user-autocomplete.yml b/changelogs/unreleased/fix-routes-n-plus-one-in-user-autocomplete.yml
deleted file mode 100644
index ae097e859d9..00000000000
--- a/changelogs/unreleased/fix-routes-n-plus-one-in-user-autocomplete.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix some N+1s in loading routes and counting members for groups in @-autocomplete
-merge_request: 26491
-author:
-type: performance
diff --git a/changelogs/unreleased/fix-transfer-group-possibilities.yml b/changelogs/unreleased/fix-transfer-group-possibilities.yml
deleted file mode 100644
index ebefb47b3da..00000000000
--- a/changelogs/unreleased/fix-transfer-group-possibilities.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix group transfer selection possibilities
-merge_request: 26123
-author: Peter Marko
-type: fixed
diff --git a/changelogs/unreleased/fixed-duplicated-large-text-on-diffs.yml b/changelogs/unreleased/fixed-duplicated-large-text-on-diffs.yml
deleted file mode 100644
index 770186a64b0..00000000000
--- a/changelogs/unreleased/fixed-duplicated-large-text-on-diffs.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed duplicated diff too large error message
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/fixed-web-ide-merge-request-review.yml b/changelogs/unreleased/fixed-web-ide-merge-request-review.yml
deleted file mode 100644
index 2799f5ee38a..00000000000
--- a/changelogs/unreleased/fixed-web-ide-merge-request-review.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed Web IDE not loading merge request files
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/gitaly-version-v1.29.0.yml b/changelogs/unreleased/gitaly-version-v1.29.0.yml
deleted file mode 100644
index b6ce14c33a2..00000000000
--- a/changelogs/unreleased/gitaly-version-v1.29.0.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Upgrade to Gitaly v1.29.0
-merge_request: 26406
-author:
-type: changed
diff --git a/changelogs/unreleased/gitaly-version-v1.32.0.yml b/changelogs/unreleased/gitaly-version-v1.32.0.yml
deleted file mode 100644
index 8413f31278e..00000000000
--- a/changelogs/unreleased/gitaly-version-v1.32.0.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Upgrade to Gitaly v1.32.0
-merge_request: 26989
-author:
-type: changed
diff --git a/changelogs/unreleased/gitaly-version-v1.33.0.yml b/changelogs/unreleased/gitaly-version-v1.33.0.yml
deleted file mode 100644
index d21e521a0bb..00000000000
--- a/changelogs/unreleased/gitaly-version-v1.33.0.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Upgrade to Gitaly v1.33.0
-merge_request: 27065
-author:
-type: changed
diff --git a/changelogs/unreleased/gitlab-issue-54894.yml b/changelogs/unreleased/gitlab-issue-54894.yml
new file mode 100644
index 00000000000..513c0163c0e
--- /dev/null
+++ b/changelogs/unreleased/gitlab-issue-54894.yml
@@ -0,0 +1,6 @@
+---
+title: Fix some label links not appearing on group labels page and label title being
+ a link on project labels page
+merge_request: 24060
+author: Tanya Pazitny
+type: fixed
diff --git a/changelogs/unreleased/graphql-prometheus.yml b/changelogs/unreleased/graphql-prometheus.yml
deleted file mode 100644
index 180577f3aec..00000000000
--- a/changelogs/unreleased/graphql-prometheus.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Added prometheus monitoring to GraphQL
-merge_request:
-author:
-type: added
diff --git a/changelogs/unreleased/gt-externalize-app-views-projects-pipelines.yml b/changelogs/unreleased/gt-externalize-app-views-projects-pipelines.yml
deleted file mode 100644
index 094cd3ab751..00000000000
--- a/changelogs/unreleased/gt-externalize-app-views-projects-pipelines.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Externalize strings from `/app/views/projects/pipelines`
-merge_request: 26035
-author: George Tsiolis
-type: other
diff --git a/changelogs/unreleased/id-51433-sort-wiki-by-date.yml b/changelogs/unreleased/id-51433-sort-wiki-by-date.yml
deleted file mode 100644
index 86fcf195fa7..00000000000
--- a/changelogs/unreleased/id-51433-sort-wiki-by-date.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow to sort wiki pages by date and title
-merge_request: 25365
-author:
-type: added
diff --git a/changelogs/unreleased/ide-fix-detect-mr-from-fork.yml b/changelogs/unreleased/ide-fix-detect-mr-from-fork.yml
deleted file mode 100644
index 8f4f49896d7..00000000000
--- a/changelogs/unreleased/ide-fix-detect-mr-from-fork.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix IDE detection of MR from fork with same branch name
-merge_request: 26986
-author:
-type: fixed
diff --git a/changelogs/unreleased/issue_58547.yml b/changelogs/unreleased/issue_58547.yml
deleted file mode 100644
index 553c752e72d..00000000000
--- a/changelogs/unreleased/issue_58547.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add API access check to Graphql
-merge_request: 26570
-author:
-type: other
diff --git a/changelogs/unreleased/jc-guard-against-empty-dereferenced_target.yml b/changelogs/unreleased/jc-guard-against-empty-dereferenced_target.yml
deleted file mode 100644
index 94e5b4a81b7..00000000000
--- a/changelogs/unreleased/jc-guard-against-empty-dereferenced_target.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Guard against nil dereferenced_target
-merge_request: 27192
-author:
-type: fixed
diff --git a/changelogs/unreleased/jc-upgrade-gitaly-1-34-0.yml b/changelogs/unreleased/jc-upgrade-gitaly-1-34-0.yml
new file mode 100644
index 00000000000..c1669a484aa
--- /dev/null
+++ b/changelogs/unreleased/jc-upgrade-gitaly-1-34-0.yml
@@ -0,0 +1,5 @@
+---
+title: Upgrade Gitaly to 1.34.0
+merge_request: 27494
+author:
+type: fixed
diff --git a/changelogs/unreleased/k8s_new_deployment_labels.yml b/changelogs/unreleased/k8s_new_deployment_labels.yml
deleted file mode 100644
index e9ef3ee0082..00000000000
--- a/changelogs/unreleased/k8s_new_deployment_labels.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update deploy boards to additionally select on "app.gitlab.com" annotations
-merge_request: 25623
-author:
-type: changed
diff --git a/changelogs/unreleased/knative-prometheus.yml b/changelogs/unreleased/knative-prometheus.yml
deleted file mode 100644
index e24f53b7225..00000000000
--- a/changelogs/unreleased/knative-prometheus.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add Knative metrics to Prometheus
-merge_request: 24663
-author: Chris Baumbauer <cab@cabnetworks.net>
-type: added
diff --git a/changelogs/unreleased/knative-update.yml b/changelogs/unreleased/knative-update.yml
deleted file mode 100644
index e84940ae7e0..00000000000
--- a/changelogs/unreleased/knative-update.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Knative version bump 0.2.2 -> 0.3.0
-merge_request: 26459
-author: Chris Baumbauer
-type: changed
diff --git a/changelogs/unreleased/kube_helm_auto_devops_213.yml b/changelogs/unreleased/kube_helm_auto_devops_213.yml
deleted file mode 100644
index 3c718d4a22c..00000000000
--- a/changelogs/unreleased/kube_helm_auto_devops_213.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Bump kubectl to 1.11.9 and Helm to 2.13.1 in Auto-DevOps.gitlab-ci.yml
-merge_request: 26534
-author:
-type: other
diff --git a/changelogs/unreleased/limit-amount-of-created-pipelines.yml b/changelogs/unreleased/limit-amount-of-created-pipelines.yml
deleted file mode 100644
index 51fdbb4d7ff..00000000000
--- a/changelogs/unreleased/limit-amount-of-created-pipelines.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Process at most 4 pipelines during push
-merge_request: 27205
-author:
-type: performance
diff --git a/changelogs/unreleased/localize-notification-dropdown.yml b/changelogs/unreleased/localize-notification-dropdown.yml
deleted file mode 100644
index 9599aaf344b..00000000000
--- a/changelogs/unreleased/localize-notification-dropdown.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Localize notifications dropdown
-merge_request: 26844
-author:
-type: changed
diff --git a/changelogs/unreleased/markdown-autocomplete-escaping.yml b/changelogs/unreleased/markdown-autocomplete-escaping.yml
new file mode 100644
index 00000000000..0ea034b14ee
--- /dev/null
+++ b/changelogs/unreleased/markdown-autocomplete-escaping.yml
@@ -0,0 +1,5 @@
+---
+title: Only escape Markdown emphasis characters in autocomplete when necessary
+merge_request: 27457
+author:
+type: changed
diff --git a/changelogs/unreleased/minimized-multiple-queries-ce.yml b/changelogs/unreleased/minimized-multiple-queries-ce.yml
deleted file mode 100644
index d8c20d492d6..00000000000
--- a/changelogs/unreleased/minimized-multiple-queries-ce.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Support multiple queries per chart on metrics dash
-merge_request: 25758
-author:
-type: added
diff --git a/changelogs/unreleased/move-allow-developers-to-create-projects-in-groups-to-core.yml b/changelogs/unreleased/move-allow-developers-to-create-projects-in-groups-to-core.yml
deleted file mode 100644
index 34fd0c1b787..00000000000
--- a/changelogs/unreleased/move-allow-developers-to-create-projects-in-groups-to-core.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Move allow developers to create projects in groups to Core
-merge_request: 25975
-author:
-type: added
diff --git a/changelogs/unreleased/nfriend-css-updates-for-gitlab-design-system-compliance.yml b/changelogs/unreleased/nfriend-css-updates-for-gitlab-design-system-compliance.yml
deleted file mode 100644
index 8cde0958f7a..00000000000
--- a/changelogs/unreleased/nfriend-css-updates-for-gitlab-design-system-compliance.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update `border-radius` of form controls and remove extra space above page titles
-merge_request: 24497
-author:
-type: fixed
diff --git a/changelogs/unreleased/nfriend-update-job-detail-view-sidebar.yml b/changelogs/unreleased/nfriend-update-job-detail-view-sidebar.yml
deleted file mode 100644
index 5364d29710a..00000000000
--- a/changelogs/unreleased/nfriend-update-job-detail-view-sidebar.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update job detail sidebar to accommodate post-merge pipeline information
-merge_request: 25777
-author:
-type: added
diff --git a/changelogs/unreleased/nfriend-update-merge-request-widget-for-post-merge-pipelines.yml b/changelogs/unreleased/nfriend-update-merge-request-widget-for-post-merge-pipelines.yml
deleted file mode 100644
index 420c8f2923c..00000000000
--- a/changelogs/unreleased/nfriend-update-merge-request-widget-for-post-merge-pipelines.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add two new warning messages to the MR widget about merge request pipelines
-merge_request: 25983
-author:
-type: added
diff --git a/changelogs/unreleased/nfriend-update-merge-request-widget-pipeline-block.yml b/changelogs/unreleased/nfriend-update-merge-request-widget-pipeline-block.yml
deleted file mode 100644
index bd4120eb06f..00000000000
--- a/changelogs/unreleased/nfriend-update-merge-request-widget-pipeline-block.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Update pipeline block on merge request page to accommodate post-merge pipeline
- information
-merge_request: 25745
-author:
-type: added
diff --git a/changelogs/unreleased/nfriend-update-pipeline-detail-view.yml b/changelogs/unreleased/nfriend-update-pipeline-detail-view.yml
deleted file mode 100644
index a24325c4eb6..00000000000
--- a/changelogs/unreleased/nfriend-update-pipeline-detail-view.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update pipeline detail view to accommodate post-merge pipelines
-merge_request: 25775
-author:
-type: added
diff --git a/changelogs/unreleased/nfriend-update-pipeline-list-view.yml b/changelogs/unreleased/nfriend-update-pipeline-list-view.yml
deleted file mode 100644
index 34e43162b5c..00000000000
--- a/changelogs/unreleased/nfriend-update-pipeline-list-view.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update pipeline list view to accommodate post-merge pipeline information
-merge_request: 25690
-author:
-type: added
diff --git a/changelogs/unreleased/only-counted-active-milestones-as-started.yml b/changelogs/unreleased/only-counted-active-milestones-as-started.yml
deleted file mode 100644
index 1a9c4b9023b..00000000000
--- a/changelogs/unreleased/only-counted-active-milestones-as-started.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Only consider active milestones when using the special Started milestone filter
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/osw-multi-line-suggestions-creation-strategy.yml b/changelogs/unreleased/osw-multi-line-suggestions-creation-strategy.yml
deleted file mode 100644
index 01bd7ede270..00000000000
--- a/changelogs/unreleased/osw-multi-line-suggestions-creation-strategy.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Implements the creation strategy for multi-line suggestions
-merge_request: 26057
-author:
-type: changed
diff --git a/changelogs/unreleased/osw-multi-line-suggestions-parsing.yml b/changelogs/unreleased/osw-multi-line-suggestions-parsing.yml
deleted file mode 100644
index 985b01e9254..00000000000
--- a/changelogs/unreleased/osw-multi-line-suggestions-parsing.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Prepare multi-line suggestions for rendering in Markdown
-merge_request: 26107
-author:
-type: other
diff --git a/changelogs/unreleased/osw-support-multi-line-suggestions.yml b/changelogs/unreleased/osw-support-multi-line-suggestions.yml
deleted file mode 100644
index 8c8206c3822..00000000000
--- a/changelogs/unreleased/osw-support-multi-line-suggestions.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Support multi-line suggestions
-merge_request: 25211
-author:
-type: added
diff --git a/changelogs/unreleased/persist-fulll-ref-path-for-mr-pipelines.yml b/changelogs/unreleased/persist-fulll-ref-path-for-mr-pipelines.yml
deleted file mode 100644
index ca42a26e8ff..00000000000
--- a/changelogs/unreleased/persist-fulll-ref-path-for-mr-pipelines.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Create MR pipelines with `refs/merge-requests/:iid/head`
-merge_request: 25504
-author:
-type: changed
diff --git a/changelogs/unreleased/pravi-gitlab-ce-update-recaptcha.yml b/changelogs/unreleased/pravi-gitlab-ce-update-recaptcha.yml
deleted file mode 100644
index 95379fb2ec1..00000000000
--- a/changelogs/unreleased/pravi-gitlab-ce-update-recaptcha.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Apply recaptcha API change in 4.0
-merge_request: 25921
-author: Praveen Arimbrathodiyil
-type: other
diff --git a/changelogs/unreleased/prevent-running-mr-pipelines-when-target-updated.yml b/changelogs/unreleased/prevent-running-mr-pipelines-when-target-updated.yml
deleted file mode 100644
index d003ca55feb..00000000000
--- a/changelogs/unreleased/prevent-running-mr-pipelines-when-target-updated.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Create pipelines for merge requests only when source branch is updated
-merge_request: 26921
-author:
-type: fixed
diff --git a/changelogs/unreleased/related-mr-link-cutoff.yml b/changelogs/unreleased/related-mr-link-cutoff.yml
deleted file mode 100644
index 8cf77b6231a..00000000000
--- a/changelogs/unreleased/related-mr-link-cutoff.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Don't cutoff letters in MR and Issue links
-merge_request: 25910
-author: gfyoung
-type: fixed
diff --git a/changelogs/unreleased/remove-ci-charts-undescriptive-header.yml b/changelogs/unreleased/remove-ci-charts-undescriptive-header.yml
deleted file mode 100644
index 0e090592101..00000000000
--- a/changelogs/unreleased/remove-ci-charts-undescriptive-header.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Removes the undescriptive CI Charts header
-merge_request: !26869
-author:
-type: changed
diff --git a/changelogs/unreleased/rename_auto_deploy_app_links.yml b/changelogs/unreleased/rename_auto_deploy_app_links.yml
new file mode 100644
index 00000000000..c56b5fb5e5c
--- /dev/null
+++ b/changelogs/unreleased/rename_auto_deploy_app_links.yml
@@ -0,0 +1,5 @@
+---
+title: Move location of charts/auto-deploy-app -> gitlab-org/charts/auto-deploy-app
+merge_request: 27477
+author:
+type: changed
diff --git a/changelogs/unreleased/security-55503-fix-pdf-js-vulnerability.yml b/changelogs/unreleased/security-55503-fix-pdf-js-vulnerability.yml
deleted file mode 100644
index e5d0cd4fee1..00000000000
--- a/changelogs/unreleased/security-55503-fix-pdf-js-vulnerability.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix PDF.js vulnerability
-merge_request:
-author:
-type: security
diff --git a/changelogs/unreleased/security-56224.yml b/changelogs/unreleased/security-56224.yml
deleted file mode 100644
index a4e274e6ca5..00000000000
--- a/changelogs/unreleased/security-56224.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Hide "related branches" when user does not have permission
-merge_request:
-author:
-type: security
diff --git a/changelogs/unreleased/security-56927-xss-resolve-conflicts-branch-name.yml b/changelogs/unreleased/security-56927-xss-resolve-conflicts-branch-name.yml
deleted file mode 100644
index f92d2c0dcb1..00000000000
--- a/changelogs/unreleased/security-56927-xss-resolve-conflicts-branch-name.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix XSS in resolve conflicts form
-merge_request:
-author:
-type: security
diff --git a/changelogs/unreleased/security-exif-migration.yml b/changelogs/unreleased/security-exif-migration.yml
deleted file mode 100644
index cc529099df5..00000000000
--- a/changelogs/unreleased/security-exif-migration.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Added rake task for removing EXIF data from existing uploads.
-merge_request:
-author:
-type: security
diff --git a/changelogs/unreleased/security-id-potential-denial-languages.yml b/changelogs/unreleased/security-id-potential-denial-languages.yml
deleted file mode 100644
index 2194ecb97dc..00000000000
--- a/changelogs/unreleased/security-id-potential-denial-languages.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Return cached languages if they've been detected before
-merge_request:
-author:
-type: security
diff --git a/changelogs/unreleased/security-mass-assignment-on-project-update.yml b/changelogs/unreleased/security-mass-assignment-on-project-update.yml
deleted file mode 100644
index 93561cd91b3..00000000000
--- a/changelogs/unreleased/security-mass-assignment-on-project-update.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Disallow updating namespace when updating a project
-merge_request:
-author:
-type: security
diff --git a/changelogs/unreleased/sh-add-gitaly-duration-logs.yml b/changelogs/unreleased/sh-add-gitaly-duration-logs.yml
deleted file mode 100644
index eea50384278..00000000000
--- a/changelogs/unreleased/sh-add-gitaly-duration-logs.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Log Gitaly RPC duration to api_json.log and production_json.log
-merge_request: 26652
-author:
-type: other
diff --git a/changelogs/unreleased/sh-add-gitaly-ref-name-caching-tree-controller.yml b/changelogs/unreleased/sh-add-gitaly-ref-name-caching-tree-controller.yml
deleted file mode 100644
index a051c1f70a8..00000000000
--- a/changelogs/unreleased/sh-add-gitaly-ref-name-caching-tree-controller.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Enable Gitaly FindCommit caching for TreeController
-merge_request: 27100
-author:
-type: performance
diff --git a/changelogs/unreleased/sh-bump-ruby-required-version-check.yml b/changelogs/unreleased/sh-bump-ruby-required-version-check.yml
new file mode 100644
index 00000000000..b5b6eb87650
--- /dev/null
+++ b/changelogs/unreleased/sh-bump-ruby-required-version-check.yml
@@ -0,0 +1,5 @@
+---
+title: Bump required Ruby version check to 2.5.3
+merge_request: 27495
+author:
+type: other
diff --git a/changelogs/unreleased/sh-cache-pipeline-find-commits.yml b/changelogs/unreleased/sh-cache-pipeline-find-commits.yml
deleted file mode 100644
index 2acf180d6fa..00000000000
--- a/changelogs/unreleased/sh-cache-pipeline-find-commits.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Cache FindCommit results in pipelines view
-merge_request: 26776
-author:
-type: performance
diff --git a/changelogs/unreleased/sh-cache-root-ref-asymetrically.yml b/changelogs/unreleased/sh-cache-root-ref-asymetrically.yml
deleted file mode 100644
index 106d070cc05..00000000000
--- a/changelogs/unreleased/sh-cache-root-ref-asymetrically.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Cache Repository#root_ref within a request
-merge_request: 25903
-author:
-type: performance
diff --git a/changelogs/unreleased/sh-clear-pipeline-status-cache-upon-destroy.yml b/changelogs/unreleased/sh-clear-pipeline-status-cache-upon-destroy.yml
deleted file mode 100644
index 55779f0f9d3..00000000000
--- a/changelogs/unreleased/sh-clear-pipeline-status-cache-upon-destroy.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Clear pipeline status cache after destruction of pipeline
-merge_request: 26575
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-fix-gitaly-find-commit-caching.yml b/changelogs/unreleased/sh-fix-gitaly-find-commit-caching.yml
deleted file mode 100644
index 16d349c407c..00000000000
--- a/changelogs/unreleased/sh-fix-gitaly-find-commit-caching.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow ref name caching CommitService#find_commit
-merge_request: 26248
-author:
-type: performance
diff --git a/changelogs/unreleased/sh-fix-issue-59065.yml b/changelogs/unreleased/sh-fix-issue-59065.yml
deleted file mode 100644
index 41cd5ce0960..00000000000
--- a/changelogs/unreleased/sh-fix-issue-59065.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix Error 500 when user commits Wiki page with no commit message
-merge_request: 26247
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-fix-merge-requests-api-remove-branch-param.yml b/changelogs/unreleased/sh-fix-merge-requests-api-remove-branch-param.yml
deleted file mode 100644
index d13c972ccc9..00000000000
--- a/changelogs/unreleased/sh-fix-merge-requests-api-remove-branch-param.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix remove_source_branch merge request API handling
-merge_request: 27392
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-fix-realtime-changes-with-reserved-words.yml b/changelogs/unreleased/sh-fix-realtime-changes-with-reserved-words.yml
deleted file mode 100644
index 3d1501cd667..00000000000
--- a/changelogs/unreleased/sh-fix-realtime-changes-with-reserved-words.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix real-time updates for projects that contain a reserved word
-merge_request: 27060
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-fix-ref-name-caching.yml b/changelogs/unreleased/sh-fix-ref-name-caching.yml
deleted file mode 100644
index 6abd86688b4..00000000000
--- a/changelogs/unreleased/sh-fix-ref-name-caching.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix and expand Gitaly FindCommit caching
-merge_request: 27018
-author:
-type: performance
diff --git a/changelogs/unreleased/sh-git-gc-after-initial-fetch.yml b/changelogs/unreleased/sh-git-gc-after-initial-fetch.yml
deleted file mode 100644
index 867d7e6b9df..00000000000
--- a/changelogs/unreleased/sh-git-gc-after-initial-fetch.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'GitHub import: Run housekeeping after initial import'
-merge_request: 26600
-author:
-type: performance
diff --git a/changelogs/unreleased/sh-improve-find-commit-caching.yml b/changelogs/unreleased/sh-improve-find-commit-caching.yml
deleted file mode 100644
index 1b38684d018..00000000000
--- a/changelogs/unreleased/sh-improve-find-commit-caching.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Expand FindCommit caching to blob and refs
-merge_request: 27084
-author:
-type: performance
diff --git a/changelogs/unreleased/sh-reject-info-refs-head-requests.yml b/changelogs/unreleased/sh-reject-info-refs-head-requests.yml
deleted file mode 100644
index 0dca18e2fd8..00000000000
--- a/changelogs/unreleased/sh-reject-info-refs-head-requests.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Reject HEAD requests to info/refs endpoint
-merge_request: 26334
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-skip-sti-tables-reltuples.yml b/changelogs/unreleased/sh-skip-sti-tables-reltuples.yml
deleted file mode 100644
index 5bf0ccf3e9d..00000000000
--- a/changelogs/unreleased/sh-skip-sti-tables-reltuples.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix counting of groups in admin dashboard
-merge_request: 26009
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-update-rails-5-0-7-2.yml b/changelogs/unreleased/sh-update-rails-5-0-7-2.yml
deleted file mode 100644
index b0bc08d4760..00000000000
--- a/changelogs/unreleased/sh-update-rails-5-0-7-2.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update Rails to 5.0.7.2
-merge_request: 27022
-author:
-type: security
diff --git a/changelogs/unreleased/stop-signing-avatar-paths.yml b/changelogs/unreleased/stop-signing-avatar-paths.yml
deleted file mode 100644
index 2c2493f0f21..00000000000
--- a/changelogs/unreleased/stop-signing-avatar-paths.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Speed up generation of avatar URLs when using object storage
-merge_request:
-author:
-type: performance
diff --git a/changelogs/unreleased/tpresa-add-highest-role-to-user.yml b/changelogs/unreleased/tpresa-add-highest-role-to-user.yml
deleted file mode 100644
index 9714d8dcc99..00000000000
--- a/changelogs/unreleased/tpresa-add-highest-role-to-user.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Adding highest role property to admin's user details page
-merge_request:
-author:
-type: added
diff --git a/changelogs/unreleased/update-gitlab-runner-helm-chart-to-0-3-0.yml b/changelogs/unreleased/update-gitlab-runner-helm-chart-to-0-3-0.yml
deleted file mode 100644
index 2e1adb1e1e9..00000000000
--- a/changelogs/unreleased/update-gitlab-runner-helm-chart-to-0-3-0.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update GitLab Runner Helm Chart to 0.3.0/11.9.0
-merge_request: 26467
-author:
-type: other
diff --git a/changelogs/unreleased/update-gitlab-shell.yml b/changelogs/unreleased/update-gitlab-shell.yml
deleted file mode 100644
index 446a5fe1ea9..00000000000
--- a/changelogs/unreleased/update-gitlab-shell.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update GitLab Shell to v9.0.0
-merge_request: 27002
-author:
-type: other
diff --git a/changelogs/unreleased/update-rack-oauth2.yml b/changelogs/unreleased/update-rack-oauth2.yml
deleted file mode 100644
index dc2e7017695..00000000000
--- a/changelogs/unreleased/update-rack-oauth2.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update rack-oauth2 1.2.1 -> 1.9.3
-merge_request: 17868
-author:
-type: other
diff --git a/changelogs/unreleased/update-workhorse-8-5-1.yml b/changelogs/unreleased/update-workhorse-8-5-1.yml
deleted file mode 100644
index 18193701678..00000000000
--- a/changelogs/unreleased/update-workhorse-8-5-1.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update GitLab Workhorse to v8.5.1
-merge_request: 27217
-author:
-type: fixed
diff --git a/changelogs/unreleased/use-only-all-pipelines.yml b/changelogs/unreleased/use-only-all-pipelines.yml
deleted file mode 100644
index 68364d2a923..00000000000
--- a/changelogs/unreleased/use-only-all-pipelines.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Refactor all_pipelines in Merge request
-merge_request: 25676
-author:
-type: other
diff --git a/changelogs/unreleased/use-untrusted-regexp.yml b/changelogs/unreleased/use-untrusted-regexp.yml
deleted file mode 100644
index dd7f1bcaca1..00000000000
--- a/changelogs/unreleased/use-untrusted-regexp.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Use UntrustedRegexp for matching refs policy
-merge_request:
-author:
-type: security
diff --git a/changelogs/unreleased/winh-toggle-comment-draft.yml b/changelogs/unreleased/winh-toggle-comment-draft.yml
deleted file mode 100644
index 6b4aad55a05..00000000000
--- a/changelogs/unreleased/winh-toggle-comment-draft.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Display draft when toggling replies
-merge_request: 25563
-author:
-type: fixed
diff --git a/changelogs/unreleased/xanf-gitlab-ce-add-template-link.yml b/changelogs/unreleased/xanf-gitlab-ce-add-template-link.yml
new file mode 100644
index 00000000000..b868758dcd2
--- /dev/null
+++ b/changelogs/unreleased/xanf-gitlab-ce-add-template-link.yml
@@ -0,0 +1,5 @@
+---
+title: Add instructions on how to contribute a Built-In template for project
+merge_request: 26976
+author:
+type: other
diff --git a/changelogs/unreleased/xanf-gitlab-ce-move-project-tags.yml b/changelogs/unreleased/xanf-gitlab-ce-move-project-tags.yml
deleted file mode 100644
index 124584c9bd4..00000000000
--- a/changelogs/unreleased/xanf-gitlab-ce-move-project-tags.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Move project tags to separate line
-merge_request: 26797
-author:
-type: other
diff --git a/changelogs/unreleased/xanf-gitlab-ce-transfer-disables-js.yml b/changelogs/unreleased/xanf-gitlab-ce-transfer-disables-js.yml
deleted file mode 100644
index 57c9a1aaa48..00000000000
--- a/changelogs/unreleased/xanf-gitlab-ce-transfer-disables-js.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Group transfer now properly redirects to edit on failure
-merge_request: 26837
-author:
-type: fixed
diff --git a/config/initializers/lograge.rb b/config/initializers/lograge.rb
index 5e790a9eccb..1ad93e14f7e 100644
--- a/config/initializers/lograge.rb
+++ b/config/initializers/lograge.rb
@@ -35,7 +35,7 @@ unless Sidekiq.server?
end
payload[:response] = event.payload[:response] if event.payload[:response]
- payload[Gitlab::CorrelationId::LOG_KEY] = Gitlab::CorrelationId.current_id
+ payload[Labkit::Correlation::CorrelationId::LOG_KEY] = Labkit::Correlation::CorrelationId.current_id
payload
end
diff --git a/config/initializers/peek.rb b/config/initializers/peek.rb
index e051e5c68c4..eeb45fae753 100644
--- a/config/initializers/peek.rb
+++ b/config/initializers/peek.rb
@@ -19,7 +19,7 @@ Peek.into Peek::Views::Gitaly
Peek.into Peek::Views::Rblineprof
Peek.into Peek::Views::Redis
Peek.into Peek::Views::GC
-Peek.into Peek::Views::Tracing if Gitlab::Tracing.tracing_url_enabled?
+Peek.into Peek::Views::Tracing if Labkit::Tracing.tracing_url_enabled?
# rubocop:disable Naming/ClassAndModuleCamelCase
class PEEK_DB_CLIENT
diff --git a/config/initializers/tracing.rb b/config/initializers/tracing.rb
index ddd91150c90..3c8779f238f 100644
--- a/config/initializers/tracing.rb
+++ b/config/initializers/tracing.rb
@@ -1,16 +1,14 @@
# frozen_string_literal: true
-if Gitlab::Tracing.enabled?
- require 'opentracing'
-
+if Labkit::Tracing.enabled?
Rails.application.configure do |config|
- config.middleware.insert_after Gitlab::Middleware::CorrelationId, ::Gitlab::Tracing::RackMiddleware
+ config.middleware.insert_after Gitlab::Middleware::CorrelationId, ::Labkit::Tracing::RackMiddleware
end
# Instrument the Sidekiq client
Sidekiq.configure_client do |config|
config.client_middleware do |chain|
- chain.add Gitlab::Tracing::Sidekiq::ClientMiddleware
+ chain.add Labkit::Tracing::Sidekiq::ClientMiddleware
end
end
@@ -18,20 +16,20 @@ if Gitlab::Tracing.enabled?
if Sidekiq.server?
Sidekiq.configure_server do |config|
config.server_middleware do |chain|
- chain.add Gitlab::Tracing::Sidekiq::ServerMiddleware
+ chain.add Labkit::Tracing::Sidekiq::ServerMiddleware
end
end
end
# Instrument Rails
- Gitlab::Tracing::Rails::ActiveRecordSubscriber.instrument
- Gitlab::Tracing::Rails::ActionViewSubscriber.instrument
+ Labkit::Tracing::Rails::ActiveRecordSubscriber.instrument
+ Labkit::Tracing::Rails::ActionViewSubscriber.instrument
# In multi-processed clustered architectures (puma, unicorn) don't
# start tracing until the worker processes are spawned. This works
# around issues when the opentracing implementation spawns threads
Gitlab::Cluster::LifecycleEvents.on_worker_start do
- tracer = Gitlab::Tracing::Factory.create_tracer(Gitlab.process_name, Gitlab::Tracing.connection_string)
+ tracer = Labkit::Tracing::Factory.create_tracer(Gitlab.process_name, Labkit::Tracing.connection_string)
OpenTracing.global_tracer = tracer if tracer
end
end
diff --git a/config/prometheus/common_metrics.yml b/config/prometheus/common_metrics.yml
index 356f573c5e9..3c67ca36791 100644
--- a/config/prometheus/common_metrics.yml
+++ b/config/prometheus/common_metrics.yml
@@ -1,42 +1,33 @@
- # NGINX Ingress metrics for pre-0.16.0 versions
+dashboard: 'Environment metrics'
+priority: 1
+panel_groups:
+# NGINX Ingress metrics for pre-0.16.0 versions
- group: Response metrics (NGINX Ingress VTS)
priority: 10
- metrics:
+ panels:
- title: "Throughput"
+ type: "area-chart"
y_label: "Requests / Sec"
- required_metrics:
- - nginx_upstream_responses_total
weight: 1
- queries:
+ metrics:
- id: response_metrics_nginx_ingress_throughput_status_code
query_range: 'sum(rate(nginx_upstream_responses_total{upstream=~"%{kube_namespace}-%{ci_environment_slug}-.*"}[2m])) by (status_code)'
unit: req / sec
label: Status Code
- series:
- - label: status_code
- when:
- - value: 2xx
- color: green
- - value: 4xx
- color: orange
- - value: 5xx
- color: red
- title: "Latency"
+ type: "area-chart"
y_label: "Latency (ms)"
- required_metrics:
- - nginx_upstream_response_msecs_avg
weight: 1
- queries:
+ metrics:
- id: response_metrics_nginx_ingress_latency_pod_average
query_range: 'avg(nginx_upstream_response_msecs_avg{upstream=~"%{kube_namespace}-%{ci_environment_slug}-.*"})'
label: Pod average
unit: ms
- title: "HTTP Error Rate"
+ type: "area-chart"
y_label: "HTTP Errors"
- required_metrics:
- - nginx_upstream_responses_total
weight: 1
- queries:
+ metrics:
- id: response_metrics_nginx_ingress_http_error_rate
query_range: 'sum(rate(nginx_upstream_responses_total{status_code="5xx", upstream=~"%{kube_namespace}-%{ci_environment_slug}-.*"}[2m])) / sum(rate(nginx_upstream_responses_total{upstream=~"%{kube_namespace}-%{ci_environment_slug}-.*"}[2m])) * 100'
label: 5xx Errors
@@ -44,227 +35,179 @@
# NGINX Ingress metrics for post-0.16.0 versions
- group: Response metrics (NGINX Ingress)
priority: 10
- metrics:
+ panels:
- title: "Throughput"
+ type: "area-chart"
y_label: "Requests / Sec"
- required_metrics:
- - nginx_ingress_controller_requests
weight: 1
- queries:
+ metrics:
- id: response_metrics_nginx_ingress_16_throughput_status_code
query_range: 'sum(label_replace(rate(nginx_ingress_controller_requests{namespace="%{kube_namespace}",ingress=~".*%{ci_environment_slug}.*"}[2m]), "status_code", "${1}xx", "status", "(.)..")) by (status_code)'
unit: req / sec
label: Status Code
- series:
- - label: status_code
- when:
- - value: 2xx
- color: green
- - value: 3xx
- color: blue
- - value: 4xx
- color: orange
- - value: 5xx
- color: red
- title: "Latency"
+ type: "area-chart"
y_label: "Latency (ms)"
- required_metrics:
- - nginx_ingress_controller_ingress_upstream_latency_seconds_sum
weight: 1
- queries:
+ metrics:
- id: response_metrics_nginx_ingress_16_latency_pod_average
query_range: 'sum(rate(nginx_ingress_controller_ingress_upstream_latency_seconds_sum{namespace="%{kube_namespace}",ingress=~".*%{ci_environment_slug}.*"}[2m])) / sum(rate(nginx_ingress_controller_ingress_upstream_latency_seconds_count{namespace="%{kube_namespace}",ingress=~".*%{ci_environment_slug}.*"}[2m])) * 1000'
label: Pod average
unit: ms
- title: "HTTP Error Rate"
+ type: "area-chart"
y_label: "HTTP Errors"
- required_metrics:
- - nginx_ingress_controller_requests
weight: 1
- queries:
+ metrics:
- id: response_metrics_nginx_ingress_16_http_error_rate
query_range: 'sum(rate(nginx_ingress_controller_requests{status=~"5.*",namespace="%{kube_namespace}",ingress=~".*%{ci_environment_slug}.*"}[2m])) / sum(rate(nginx_ingress_controller_requests{namespace="%{kube_namespace}",ingress=~".*%{ci_environment_slug}.*"}[2m])) * 100'
label: 5xx Errors
unit: "%"
- group: Response metrics (HA Proxy)
priority: 10
- metrics:
+ panels:
- title: "Throughput"
+ type: "area-chart"
y_label: "Requests / Sec"
- required_metrics:
- - haproxy_frontend_http_requests_total
weight: 1
- queries:
+ metrics:
- id: response_metrics_ha_proxy_throughput_status_code
query_range: 'sum(rate(haproxy_frontend_http_requests_total{%{environment_filter}}[2m])) by (code)'
unit: req / sec
label: Status Code
- series:
- - label: status_code
- when:
- - value: 2xx
- color: green
- - value: 4xx
- color: yellow
- - value: 5xx
- color: red
- title: "HTTP Error Rate"
+ type: "area-chart"
y_label: "Error Rate (%)"
- required_metrics:
- - haproxy_frontend_http_responses_total
weight: 1
- queries:
+ metrics:
- id: response_metrics_ha_proxy_http_error_rate
query_range: 'sum(rate(haproxy_frontend_http_responses_total{code="5xx",%{environment_filter}}[2m])) / sum(rate(haproxy_frontend_http_responses_total{%{environment_filter}}[2m]))'
label: HTTP Errors
unit: "%"
- group: Response metrics (AWS ELB)
priority: 10
- metrics:
+ panels:
- title: "Throughput"
+ type: "area-chart"
y_label: "Requests / Sec"
- required_metrics:
- - aws_elb_request_count_sum
weight: 1
- queries:
+ metrics:
- id: response_metrics_aws_elb_throughput_requests
query_range: 'sum(aws_elb_request_count_sum{%{environment_filter}}) / 60'
label: Total
unit: req / sec
- title: "Latency"
+ type: "area-chart"
y_label: "Latency (ms)"
- required_metrics:
- - aws_elb_latency_average
weight: 1
- queries:
+ metrics:
- id: response_metrics_aws_elb_latency_average
query_range: 'avg(aws_elb_latency_average{%{environment_filter}}) * 1000'
label: Average
unit: ms
- title: "HTTP Error Rate"
+ type: "area-chart"
y_label: "Error Rate (%)"
- required_metrics:
- - aws_elb_request_count_sum
- - aws_elb_httpcode_backend_5_xx_sum
weight: 1
- queries:
+ metrics:
- id: response_metrics_aws_elb_http_error_rate
query_range: 'sum(aws_elb_httpcode_backend_5_xx_sum{%{environment_filter}}) / sum(aws_elb_request_count_sum{%{environment_filter}})'
label: HTTP Errors
unit: "%"
- group: Response metrics (NGINX)
priority: 10
- metrics:
+ panels:
- title: "Throughput"
+ type: "area-chart"
y_label: "Requests / Sec"
- required_metrics:
- - nginx_server_requests
weight: 1
- queries:
+ metrics:
- id: response_metrics_nginx_throughput_status_code
query_range: 'sum(rate(nginx_server_requests{server_zone!="*", server_zone!="_", %{environment_filter}}[2m])) by (code)'
unit: req / sec
label: Status Code
- series:
- - label: status_code
- when:
- - value: 2xx
- color: green
- - value: 4xx
- color: orange
- - value: 5xx
- color: red
- title: "Latency"
+ type: "area-chart"
y_label: "Latency (ms)"
- required_metrics:
- - nginx_server_requestMsec
weight: 1
- queries:
+ metrics:
- id: response_metrics_nginx_latency
query_range: 'avg(nginx_server_requestMsec{%{environment_filter}})'
label: Upstream
unit: ms
- title: "HTTP Error Rate"
+ type: "area-chart"
y_label: "HTTP 500 Errors / Sec"
- required_metrics:
- - nginx_server_requests
weight: 1
- queries:
+ metrics:
- id: response_metrics_nginx_http_error_rate
query_range: 'sum(rate(nginx_server_requests{code="5xx", %{environment_filter}}[2m]))'
label: HTTP Errors
unit: "errors / sec"
- group: System metrics (Kubernetes)
priority: 5
- metrics:
+ panels:
- title: "Memory Usage (Total)"
+ type: "area-chart"
y_label: "Total Memory Used"
- required_metrics:
- - container_memory_usage_bytes
weight: 4
- queries:
+ metrics:
- id: system_metrics_kubernetes_container_memory_total
query_range: 'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) /1024/1024/1024'
label: Total
unit: GB
- title: "Core Usage (Total)"
+ type: "area-chart"
y_label: "Total Cores"
- required_metrics:
- - container_cpu_usage_seconds_total
weight: 3
- queries:
+ metrics:
- id: system_metrics_kubernetes_container_cores_total
query_range: 'avg(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}[15m])) by (job)) without (job)'
label: Total
unit: "cores"
- title: "Memory Usage (Pod average)"
+ type: "area-chart"
y_label: "Memory Used per Pod"
- required_metrics:
- - container_memory_usage_bytes
weight: 2
- queries:
+ metrics:
- id: system_metrics_kubernetes_container_memory_average
query_range: 'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) / count(avg(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}) without (job)) /1024/1024'
label: Pod average
unit: MB
- title: "Canary: Memory Usage (Pod Average)"
+ type: "area-chart"
y_label: "Memory Used per Pod"
- required_metrics:
- - container_memory_usage_bytes
weight: 2
- queries:
+ metrics:
- id: system_metrics_kubernetes_container_memory_average_canary
query_range: 'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-canary-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) / count(avg(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-canary-(.*)",namespace="%{kube_namespace}"}) without (job)) /1024/1024'
label: Pod average
unit: MB
track: canary
- title: "Core Usage (Pod Average)"
+ type: "area-chart"
y_label: "Cores per Pod"
- required_metrics:
- - container_cpu_usage_seconds_total
weight: 1
- queries:
+ metrics:
- id: system_metrics_kubernetes_container_core_usage
query_range: 'avg(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}[15m])) by (job)) without (job) / count(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}[15m])) by (pod_name))'
label: Pod average
unit: "cores"
- title: "Canary: Core Usage (Pod Average)"
+ type: "area-chart"
y_label: "Cores per Pod"
- required_metrics:
- - container_cpu_usage_seconds_total
weight: 1
- queries:
+ metrics:
- id: system_metrics_kubernetes_container_core_usage_canary
query_range: 'avg(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-canary-(.*)",namespace="%{kube_namespace}"}[15m])) by (job)) without (job) / count(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-canary-(.*)",namespace="%{kube_namespace}"}[15m])) by (pod_name))'
label: Pod average
unit: "cores"
track: canary
- title: "Knative function invocations"
+ type: "area-chart"
y_label: "Invocations"
- required_metrics:
- - istio_revision_request_count
weight: 1
- queries:
+ metrics:
- id: system_metrics_knative_function_invocation_count
query_range: 'floor(sum(rate(istio_revision_request_count{destination_configuration="%{function_name}", destination_namespace="%{kube_namespace}"}[1m])/3))'
label: invocations / minute
diff --git a/db/importers/common_metrics_importer.rb b/db/importers/common_metrics_importer.rb
index deadd653ae9..195bde8f34a 100644
--- a/db/importers/common_metrics_importer.rb
+++ b/db/importers/common_metrics_importer.rb
@@ -53,7 +53,7 @@ module Importers
private
def process_content(&blk)
- content.map do |group|
+ content['panel_groups'].map do |group|
process_group(group, &blk)
end
end
@@ -63,28 +63,28 @@ module Importers
group: find_group_title_key(group['group'])
}
- group['metrics'].map do |metric|
- process_metric(metric, attributes, &blk)
+ group['panels'].map do |panel|
+ process_panel(panel, attributes, &blk)
end
end
- def process_metric(metric, attributes, &blk)
+ def process_panel(panel, attributes, &blk)
attributes = attributes.merge(
- title: metric['title'],
- y_label: metric['y_label'])
+ title: panel['title'],
+ y_label: panel['y_label'])
- metric['queries'].map do |query|
- process_metric_query(query, attributes, &blk)
+ panel['metrics'].map do |metric_details|
+ process_metric_details(metric_details, attributes, &blk)
end
end
- def process_metric_query(query, attributes, &blk)
+ def process_metric_details(metric_details, attributes, &blk)
attributes = attributes.merge(
- legend: query['label'],
- query: query['query_range'],
- unit: query['unit'])
+ legend: metric_details['label'],
+ query: metric_details['query_range'],
+ unit: metric_details['unit'])
- yield(query['id'], attributes)
+ yield(metric_details['id'], attributes)
end
def find_or_build_metric!(id)
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 0a950352ecf..951961e45ff 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -494,7 +494,9 @@ GET /projects/:id
"name": "Diaspora",
"path": "diaspora",
"kind": "group",
- "full_path": "diaspora"
+ "full_path": "diaspora",
+ "avatar_url": "http://localhost:3000/uploads/group/avatar/3/foo.jpg",
+ "web_url": "http://localhost:3000/groups/diaspora"
},
"import_status": "none",
"import_error": null,
@@ -561,6 +563,8 @@ GET /projects/:id
}
```
+**Note**: The `web_url` and `avatar_url` attributes on `namespace` were [introduced][ce-27427] in GitLab 11.11.
+
If the project is a fork, and you provide a valid token to authenticate, the
`forked_from_project` field will appear in the response.
@@ -1587,3 +1591,4 @@ GET /projects/:id/snapshot
[eep]: https://about.gitlab.com/pricing/ "Available only in GitLab Premium"
[ee-6137]: https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/6137
+[ce-27427]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/27427
diff --git a/doc/api/runners.md b/doc/api/runners.md
index 46f7b1d2a25..2d91428d1c1 100644
--- a/doc/api/runners.md
+++ b/doc/api/runners.md
@@ -486,6 +486,7 @@ POST /runners
| `locked` | boolean| no | Whether the Runner should be locked for current project |
| `run_untagged` | boolean | no | Whether the Runner should handle untagged jobs |
| `tag_list` | Array[String] | no | List of Runner's tags |
+| `access_level` | string | no | The access_level of the runner; `not_protected` or `ref_protected` |
| `maximum_timeout` | integer | no | Maximum timeout set when this Runner will handle the job |
```
diff --git a/doc/ci/examples/code_quality.md b/doc/ci/examples/code_quality.md
index 3e7d6e7e3f7..186d4527bb6 100644
--- a/doc/ci/examples/code_quality.md
+++ b/doc/ci/examples/code_quality.md
@@ -1,7 +1,7 @@
# Analyze your project's Code Quality
CAUTION: **Caution:**
-The job definition shown below is supported on GitLab 11.5 and later versions.
+The job definition shown below is supported on GitLab 11.11 and later versions.
It also requires the GitLab Runner 11.5 or later.
For earlier versions, use the [previous job definitions](#previous-job-definitions).
@@ -11,27 +11,11 @@ and Docker.
First, you need GitLab Runner with
[docker-in-docker executor](../docker/using_docker_build.md#use-docker-in-docker-executor).
-Once you set up the Runner, add a new job to `.gitlab-ci.yml` that
-generates the expected report:
+Once you set up the Runner, include the CodeQuality template in your CI config:
```yaml
-code_quality:
- image: docker:stable
- variables:
- DOCKER_DRIVER: overlay2
- allow_failure: true
- services:
- - docker:stable-dind
- script:
- - export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
- - docker run
- --env SOURCE_CODE="$PWD"
- --volume "$PWD":/code
- --volume /var/run/docker.sock:/var/run/docker.sock
- "registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
- artifacts:
- reports:
- codequality: gl-code-quality-report.json
+include:
+ - template: Code-Quality.gitlab-ci.yml
```
The above example will create a `code_quality` job in your CI/CD pipeline which
@@ -54,6 +38,28 @@ While these old job definitions are still maintained they have been deprecated
and may be removed in next major release, GitLab 12.0.
You are advised to update your current `.gitlab-ci.yml` configuration to reflect that change.
+For GitLab 11.5 and earlier, the job should look like:
+
+```yaml
+code_quality:
+ image: docker:stable
+ variables:
+ DOCKER_DRIVER: overlay2
+ allow_failure: true
+ services:
+ - docker:stable-dind
+ script:
+ - export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
+ - docker run
+ --env SOURCE_CODE="$PWD"
+ --volume "$PWD":/code
+ --volume /var/run/docker.sock:/var/run/docker.sock
+ "registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
+ artifacts:
+ reports:
+ codequality: gl-code-quality-report.json
+```
+
For GitLab 11.4 and earlier, the job should look like:
```yaml
diff --git a/doc/ci/merge_request_pipelines/index.md b/doc/ci/merge_request_pipelines/index.md
index 2de751c9e62..6a03ab910fc 100644
--- a/doc/ci/merge_request_pipelines/index.md
+++ b/doc/ci/merge_request_pipelines/index.md
@@ -69,7 +69,7 @@ when a merge request was created or updated. For example:
## Combined ref pipelines **[PREMIUM]**
-> [GitLab Premium](https://about.gitlab.com/pricing/) 11.10.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/7380) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.10.
It's possible for your source and target branches to diverge, which can result
in the scenario that source branch's pipeline was green, the target's pipeline was green,
diff --git a/doc/development/documentation/index.md b/doc/development/documentation/index.md
index 3a6f4bd8ed2..52a4bb27817 100644
--- a/doc/development/documentation/index.md
+++ b/doc/development/documentation/index.md
@@ -50,9 +50,7 @@ Adhere to the [Documentation Style Guide](styleguide.md). If a style standard is
## Folder structure and files
-Beyond the top-level directories under /doc, which mainly pertain to audiences (`user`, `administration`, `development`), we organize by product area and subject, not type.
-
-For complete details, see the [Content](styleguide.md#content) section of the [Documentation Style Guide](styleguide.md).
+See the [Structure](styleguide.md#structure) section of the [Documentation Style Guide](styleguide.md).
## Changing document location
diff --git a/doc/development/documentation/styleguide.md b/doc/development/documentation/styleguide.md
index d16a8243def..e36ad01d4f8 100644
--- a/doc/development/documentation/styleguide.md
+++ b/doc/development/documentation/styleguide.md
@@ -13,12 +13,9 @@ For programmatic help adhering to the guidelines, see [linting](index.md#linting
See the GitLab handbook for further [writing style guidelines](https://about.gitlab.com/handbook/communication/#writing-style-guidelines)
that apply to all GitLab content, not just documentation.
-## Content
+## Documentation is the single source of truth (SSOT)
-These guidelines help toward the goal of having every user's search of documentation
-yield a useful result, and ensuring content is consistent, helpful, and easy to consume.
-
-### Single source of truth (SSOT) on the GitLab product
+### Why a single source of truth
The documentation is the SSOT for all information related to the implementation, usage, and troubleshooting of GitLab products and features. It evolves continually, in keeping with new products and features, and with improvements for clarity, accuracy, and completeness.
@@ -26,31 +23,43 @@ This policy prevents information silos, ensuring that it remains easy to find in
It also informs decisions about the kinds of content we include in our documentation.
-### All helpful information
+The documentation is a continually evolving SSOT for all information related to the implementation, usage, and troubleshooting of GitLab products and features.
+
+### All information
Include problem-solving actions that may address rare cases or be considered 'risky', so long as proper context is provided in the form of fully detailed warnings and caveats. This kind of content should be included as it could be helpful to others and, when properly explained, its benefits outweigh the risks. If you think you have found an exception to this rule, contact the Technical Writing team.
-### All helpful media types and sources
+We will add all troubleshooting information to the documentation, no matter how unlikely a user is to encounter a situation.
+For the Troubleshooting sections, people in GitLab Support can merge additions themselves.
+
+### All media types
Include any media types/sources if the content is relevant to readers. You can freely include or link presentations, diagrams, videos, etc.; no matter who it was originally composed for, if it is helpful to any of our audiences, we can include it.
- If you use an image that has a separate source file (for example, a vector or diagram format), link the image to the source file so that it may be reused or updated by anyone.
- Do not copy and paste content from other sources unless it is a limited quotation with the source cited. Typically it is better to either rephrase relevant information in your own words or link out to the other source.
+
+### No special types
-### Markdown
+In the software industry, it is a best practice to organize documentatioin in different types. For example, [Divio recommends](https://www.divio.com/blog/documentation/):
-All GitLab documentation is written using [Markdown](https://en.wikipedia.org/wiki/Markdown).
+1. Tutorials
+2. How-to guides
+3. Explanation
+4. Reference (for example, a glossary)
-The [documentation website](https://docs.gitlab.com) uses GitLab Kramdown as its Markdown rendering engine. For a complete Kramdown reference, see the [GitLab Markdown Kramdown Guide](https://about.gitlab.com/handbook/product/technical-writing/markdown-guide/).
+At GitLab, we have so many product changes in our monthly releases that we can't afford to continually update multiple types of information.
+If we have multiple types, the information will become outdated. Therefore, we have a [single template](structure.md) for documentation.
-The [`gitlab-kramdown`](https://gitlab.com/gitlab-org/gitlab_kramdown)
-Ruby gem will support all [GFM markup](../../user/markdown.md) in the future. That is,
-all markup that is supported for display in the GitLab application itself. For now,
-use regular Markdown markup, following the rules in the linked style guide.
+We currently do not distinguish specific document types, although we are open to reconsidering this policy
+once the documentation has reached a future stage of maturity and quality. If you are reading this, then despite our
+continual improvement efforts, that point hasn't been reached.
-Note that Kramdown-specific markup (e.g., `{:.class}`) will not render properly on GitLab instances under [`/help`](index.md#gitlab-help).
+### Link instead of summarize
-## Structure
+There is a temptation to summarize the information on another page.
+This will cause the information to live in two places.
+Instead, link to the SSOT and explain why it is important to consume the information.
### Organize by topic, not by type
@@ -63,6 +72,40 @@ it difficult to browse for the information you need and difficult to maintain up
Instead, organize content by its subject (e.g. everything related to CI goes together)
and cross-link between any related content.
+### Docs-first methodology
+
+We employ a **docs-first methodology** to help ensure that the docs remain a complete and trusted resource, and to make communicating about the use of GitLab more efficient.
+
+* If the answer to a question exists in documentation, share the link to the docs instead of rephrasing the information.
+* When you encounter new information not available in GitLab’s documentation (for example, when working on a support case or testing a feature), your first step should be to create a merge request to add this information to the docs. You can then share the MR in order to communicate this information.
+
+New information that would be useful toward the future usage or troubleshooting of GitLab should not be written directly in a forum or other messaging system, but added to a docs MR and then referenced, as described above. Note that among any other doc changes, you can always add a Troubleshooting section to a doc if none exists, or un-comment and use the placeholder Troubleshooting section included as part of our [doc template](structure.md#template-for-new-docs), if present.
+
+The more we reflexively add useful information to the docs, the more (and more successfully) the docs will be used to efficiently accomplish tasks and solve problems.
+
+If you have questions when considering, authoring, or editing docs, ask the Technical Writing team on Slack in `#docs` or in GitLab by mentioning the writer for the applicable [DevOps stage](https://about.gitlab.com/handbook/product/categories/#devops-stages). Otherwise, forge ahead with your best effort. It does not need to be perfect; the team is happy to review and improve upon your content. Please review the [Documentation guidelines](index.md) before you begin your first documentation MR.
+
+Having a knowledge base is any form that is separate from the documentation would be against the docs-first methodology because the content would overlap with the documentation.
+
+## Markdown
+
+All GitLab documentation is written using [Markdown](https://en.wikipedia.org/wiki/Markdown).
+
+The [documentation website](https://docs.gitlab.com) uses GitLab Kramdown as its Markdown rendering engine. For a complete Kramdown reference, see the [GitLab Markdown Kramdown Guide](https://about.gitlab.com/handbook/product/technical-writing/markdown-guide/).
+
+The [`gitlab-kramdown`](https://gitlab.com/gitlab-org/gitlab_kramdown)
+Ruby gem will support all [GFM markup](../../user/markdown.md) in the future. That is,
+all markup that is supported for display in the GitLab application itself. For now,
+use regular Markdown markup, following the rules in the linked style guide.
+
+Note that Kramdown-specific markup (e.g., `{:.class}`) will not render properly on GitLab instances under [`/help`](index.md#gitlab-help).
+
+## Structure
+
+### Organize by topic, not by type
+
+Because we want documentation to be a SSOT, we should [organize by topic, not by type](#organize-by-topic-not-by-type).
+
### Folder structure overview
The documentation is separated by top-level audience folders [`user`](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/user),
@@ -133,7 +176,7 @@ changes, regardless, and can move content if there is a better place for it.
### Avoid duplication
-Do not include the same information in multiple places. Instead, choose one single-source-of-truth location and link from other relevant locations.
+Do not include the same information in multiple places. [Link to a SSOT instead.](#link-instead-of-summarize)
### References across documents
diff --git a/doc/topics/autodevops/index.md b/doc/topics/autodevops/index.md
index 1d517a65ce2..0ab9406c681 100644
--- a/doc/topics/autodevops/index.md
+++ b/doc/topics/autodevops/index.md
@@ -460,7 +460,7 @@ for example after the merge request is merged, the Review App will automatically
be deleted.
Review apps are deployed using the
-[auto-deploy-app](https://gitlab.com/charts/auto-deploy-app) chart with
+[auto-deploy-app](https://gitlab.com/gitlab-org/charts/auto-deploy-app) chart with
Helm. The app will be deployed into the [Kubernetes
namespace](../../user/project/clusters/index.md#deployment-variables)
for the environment.
@@ -528,7 +528,7 @@ You can make use of [environment variables](#environment-variables) to automatic
scale your pod replicas.
Apps are deployed using the
-[auto-deploy-app](https://gitlab.com/charts/auto-deploy-app) chart with
+[auto-deploy-app](https://gitlab.com/gitlab-org/charts/auto-deploy-app) chart with
Helm. The app will be deployed into the [Kubernetes
namespace](../../user/project/clusters/index.md#deployment-variables)
for the environment.
@@ -667,7 +667,7 @@ repo or by specifying a project variable:
- **Bundled chart** - If your project has a `./chart` directory with a `Chart.yaml`
file in it, Auto DevOps will detect the chart and use it instead of the [default
- one](https://gitlab.com/charts/auto-deploy-app).
+ one](https://gitlab.com/gitlab-org/charts/auto-deploy-app).
This can be a great way to control exactly how your application is deployed.
- **Project variable** - Create a [project variable](../../ci/variables/README.md#gitlab-cicd-environment-variables)
`AUTO_DEVOPS_CHART` with the URL of a custom chart to use or create two project variables `AUTO_DEVOPS_CHART_REPOSITORY` with the URL of a custom chart repository and `AUTO_DEVOPS_CHART` with the path to the chart.
@@ -735,7 +735,7 @@ also be customized, and you can easily use a [custom buildpack](#custom-buildpac
| **Variable** | **Description** |
| ------------ | --------------- |
| `AUTO_DEVOPS_DOMAIN` | The [Auto DevOps domain](#auto-devops-base-domain). By default, set automatically by the [Auto DevOps setting](#enablingdisabling-auto-devops). This variable is deprecated and [is scheduled to be removed](https://gitlab.com/gitlab-org/gitlab-ce/issues/56959). Use `KUBE_INGRESS_BASE_DOMAIN` instead. |
-| `AUTO_DEVOPS_CHART` | The Helm Chart used to deploy your apps; defaults to the one [provided by GitLab](https://gitlab.com/charts/auto-deploy-app). |
+| `AUTO_DEVOPS_CHART` | The Helm Chart used to deploy your apps; defaults to the one [provided by GitLab](https://gitlab.com/gitlab-org/charts/auto-deploy-app). |
| `AUTO_DEVOPS_CHART_REPOSITORY` | The Helm Chart repository used to search for charts; defaults to `https://charts.gitlab.io`. |
| `REPLICAS` | The number of replicas to deploy; defaults to 1. |
| `PRODUCTION_REPLICAS` | The number of replicas to deploy in the production environment. This takes precedence over `REPLICAS`; defaults to 1. |
diff --git a/doc/user/admin_area/settings/external_authorization.md b/doc/user/admin_area/settings/external_authorization.md
new file mode 100644
index 00000000000..72e76ac2a84
--- /dev/null
+++ b/doc/user/admin_area/settings/external_authorization.md
@@ -0,0 +1,112 @@
+# External authorization control
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/4216) in
+> [GitLab Premium](https://about.gitlab.com/pricing) 10.6.
+> [Moved](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/27056) to
+> [GitLab Core](https://about.gitlab.com/pricing/) in 11.10.
+
+In highly controlled environments, it may be necessary for access policy to be
+controlled by an external service that permits access based on project
+classification and user access. GitLab provides a way to check project
+authorization with your own defined service.
+
+## Overview
+
+Once the external service is configured and enabled, when a project is accessed,
+a request is made to the external service with the user information and project
+classification label assigned to the project. When the service replies with a
+known response, the result is cached for 6 hours.
+
+If the external authorization is enabled, GitLab will further block pages and
+functionality that render cross-project data. That includes:
+
+- most pages under Dashboard (Activity, Milestones, Snippets, Assigned merge
+ requests, Assigned issues, Todos)
+- under a specific group (Activity, Contribution analytics, Issues, Issue boards,
+ Labels, Milestones, Merge requests)
+- Global and Group search will be disabled
+
+This is to prevent performing to many requests at once to the external
+authorization service.
+
+Whenever access is granted or denied this is logged in a logfile called
+`external-policy-access-control.log`.
+Read more about logs GitLab keeps in the [omnibus documentation][omnibus-log-docs].
+
+## Configuration
+
+The external authorization service can be enabled by an admin on the GitLab's
+admin area under the settings page:
+
+![Enable external authorization service](img/external_authorization_service_settings.png)
+
+The available required properties are:
+
+- **Service URL**: The URL to make authorization requests to. When leaving the
+ URL blank, cross project features will remain available while still being able
+ to specify classification labels for projects.
+- **External authorization request timeout**: The timeout after which an
+ authorization request is aborted. When a request times out, access is denied
+ to the user.
+- **Client authentication certificate**: The certificate to use to authenticate
+ with the external authorization service.
+- **Client authentication key**: Private key for the certificate when
+ authentication is required for the external authorization service, this is
+ encrypted when stored.
+- **Client authentication key password**: Passphrase to use for the private key when authenticating with the external service this is encrypted when stored.
+- **Default classification label**: The classification label to use when
+ requesting authorization if no specific label is defined on the project
+
+When using TLS Authentication with a self signed certificate, the CA certificate
+needs to be trused by the openssl installation. When using GitLab installed using
+Omnibus, learn to install a custom CA in the
+[omnibus documentation][omnibus-ssl-docs]. Alternatively learn where to install
+custom certificates using `openssl version -d`.
+
+## How it works
+
+When GitLab requests access, it will send a JSON POST request to the external
+service with this body:
+
+```json
+{
+ "user_identifier": "jane@acme.org",
+ "project_classification_label": "project-label",
+ "user_ldap_dn": "CN=Jane Doe,CN=admin,DC=acme"
+}
+```
+
+The `user_ldap_dn` is optional and is only sent when the user is logged in
+through LDAP.
+
+When the external authorization service responds with a status code 200, the
+user is granted access. When the external service responds with a status code
+401 or 403, the user is denied access. In any case, the request is cached for 6 hours.
+
+When denying access, a `reason` can be optionally specified in the JSON body:
+
+```json
+{
+ "reason": "You are not allowed access to this project."
+}
+```
+
+Any other status code than 200, 401 or 403 will also deny access to the user, but the
+response will not be cached.
+
+If the service times out (after 500ms), a message "External Policy Server did
+not respond" will be displayed.
+
+## Classification labels
+
+You can use your own classification label in the project's
+**Settings > General > General project settings** page in the "Classification
+label" box. When no classification label is specified on a project, the default
+label defined in the [global settings](#configuration) will be used.
+
+The label will be shown on all project pages in the upper right corner.
+
+![classification label on project page](img/classification_label_on_project_page.png)
+
+[omnibus-ssl-docs]: https://docs.gitlab.com/omnibus/settings/ssl.html
+[omnibus-log-docs]: https://docs.gitlab.com/omnibus/settings/logs.html
diff --git a/doc/user/admin_area/settings/img/classification_label_on_project_page.png b/doc/user/admin_area/settings/img/classification_label_on_project_page.png
new file mode 100644
index 00000000000..4aedb332cec
--- /dev/null
+++ b/doc/user/admin_area/settings/img/classification_label_on_project_page.png
Binary files differ
diff --git a/doc/user/admin_area/settings/img/external_authorization_service_settings.png b/doc/user/admin_area/settings/img/external_authorization_service_settings.png
new file mode 100644
index 00000000000..9b8658fd1a1
--- /dev/null
+++ b/doc/user/admin_area/settings/img/external_authorization_service_settings.png
Binary files differ
diff --git a/doc/user/discussions/index.md b/doc/user/discussions/index.md
index bf41fdecd10..c7e8bb5b33b 100644
--- a/doc/user/discussions/index.md
+++ b/doc/user/discussions/index.md
@@ -348,19 +348,23 @@ Custom commit messages will be introduced by
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/53310) in GitLab 11.10.
-Reviewers can also suggest changes to
-multiple lines with a single suggestion within Merge Request diff discussions.
+Reviewers can also suggest changes to multiple lines with a single suggestion
+within Merge Request diff discussions by adjusting the range offsets. The
+offsets are relative to the position of the diff discussion, and specify the
+range to be replaced by the suggestion when it is applied.
![Multi-line suggestion syntax](img/multi-line-suggestion-syntax.png)
-In the example above, the suggestion covers three lines above and four lines below the commented diff line.
-It'd change from 3 lines _above_ to 4 lines _below_ the commented Diff line.
+In the example above, the suggestion covers three lines above and four lines
+below the commented line. When applied, it would replace from 3 lines _above_
+to 4 lines _below_ the commented line, with the suggested change.
![Multi-line suggestion preview](img/multi-line-suggestion-preview.png)
NOTE: **Note:**
-Suggestions covering multiple lines are limited to 100 lines _above_ and 100 lines _below_
-the commented diff line, allowing up to 200 changed lines per suggestion.
+Suggestions covering multiple lines are limited to 100 lines _above_ and 100
+lines _below_ the commented diff line, allowing up to 200 changed lines per
+suggestion.
## Start a discussion by replying to a standard comment
diff --git a/doc/user/profile/account/delete_account.md b/doc/user/profile/account/delete_account.md
index b497cc414af..0d7bbb0af79 100644
--- a/doc/user/profile/account/delete_account.md
+++ b/doc/user/profile/account/delete_account.md
@@ -14,7 +14,7 @@ Deleting a user will delete all projects in that user namespace.
[GitLab 9.1][ce-10273], and from the API in [GitLab 9.3][ce-11853].
When a user account is deleted, not all associated records are deleted with it.
-Here's a list of things that will not be deleted:
+Here's a list of things that will **not** be deleted:
- Issues that the user created
- Merge requests that the user created
diff --git a/doc/user/project/clusters/index.md b/doc/user/project/clusters/index.md
index ccd60b9761f..0db95e5a64c 100644
--- a/doc/user/project/clusters/index.md
+++ b/doc/user/project/clusters/index.md
@@ -124,26 +124,26 @@ To add an existing Kubernetes cluster to your project:
1. Create a file called `gitlab-admin-service-account.yaml` with contents:
- ```yaml
- apiVersion: v1
- kind: ServiceAccount
- metadata:
- name: gitlab-admin
- namespace: kube-system
- ---
- apiVersion: rbac.authorization.k8s.io/v1beta1
- kind: ClusterRoleBinding
- metadata:
- name: gitlab-admin
- roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: cluster-admin
- subjects:
- - kind: ServiceAccount
- name: gitlab-admin
- namespace: kube-system
- ```
+ ```yaml
+ apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: gitlab-admin
+ namespace: kube-system
+ ---
+ apiVersion: rbac.authorization.k8s.io/v1beta1
+ kind: ClusterRoleBinding
+ metadata:
+ name: gitlab-admin
+ roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: cluster-admin
+ subjects:
+ - kind: ServiceAccount
+ name: gitlab-admin
+ namespace: kube-system
+ ```
1. Apply the service account and cluster role binding to your cluster:
diff --git a/doc/user/project/clusters/serverless/index.md b/doc/user/project/clusters/serverless/index.md
index 5b7e9ef906f..dfbed0ec95f 100644
--- a/doc/user/project/clusters/serverless/index.md
+++ b/doc/user/project/clusters/serverless/index.md
@@ -158,21 +158,6 @@ Follow these steps to deploy a function using the Node.js runtime to your Knativ
description: "node.js runtime function"
environment:
MY_FUNCTION: echo-js
-
- echo-rb:
- handler: MyEcho.my_function
- source: ./echo-rb
- runtime: https://gitlab.com/gitlab-org/serverless/runtimes/ruby
- description: "Ruby runtime function"
- environment:
- MY_FUNCTION: echo-rb
-
- echo-docker:
- handler: echo-docker
- source: ./echo-docker
- description: "Dockerfile runtime function"
- environment:
- MY_FUNCTION: echo-docker
```
Explanation of the fields used above:
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 4bdac278add..ee8480122c4 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -922,7 +922,15 @@ module API
end
class NamespaceBasic < Grape::Entity
- expose :id, :name, :path, :kind, :full_path, :parent_id
+ expose :id, :name, :path, :kind, :full_path, :parent_id, :avatar_url
+
+ expose :web_url do |namespace|
+ if namespace.user?
+ Gitlab::Routing.url_helpers.user_url(namespace.owner)
+ else
+ namespace.web_url
+ end
+ end
end
class Namespace < NamespaceBasic
diff --git a/lib/api/runner.rb b/lib/api/runner.rb
index c60d25b88cb..ea36c24eca2 100644
--- a/lib/api/runner.rb
+++ b/lib/api/runner.rb
@@ -15,12 +15,14 @@ module API
optional :info, type: Hash, desc: %q(Runner's metadata)
optional :active, type: Boolean, desc: 'Should Runner be active'
optional :locked, type: Boolean, desc: 'Should Runner be locked for current project'
+ optional :access_level, type: String, values: Ci::Runner.access_levels.keys,
+ desc: 'The access_level of the runner'
optional :run_untagged, type: Boolean, desc: 'Should Runner handle untagged jobs'
optional :tag_list, type: Array[String], desc: %q(List of Runner's tags)
optional :maximum_timeout, type: Integer, desc: 'Maximum timeout set when this Runner will handle the job'
end
post '/' do
- attributes = attributes_for_keys([:description, :active, :locked, :run_untagged, :tag_list, :maximum_timeout])
+ attributes = attributes_for_keys([:description, :active, :locked, :run_untagged, :tag_list, :access_level, :maximum_timeout])
.merge(get_runner_details_from_request)
attributes =
diff --git a/lib/gitlab/gitaly_client.rb b/lib/gitlab/gitaly_client.rb
index 726c4d95da9..c432317eb24 100644
--- a/lib/gitlab/gitaly_client.rb
+++ b/lib/gitlab/gitaly_client.rb
@@ -52,9 +52,9 @@ module Gitlab
end
def self.interceptors
- return [] unless Gitlab::Tracing.enabled?
+ return [] unless Labkit::Tracing.enabled?
- [Gitlab::Tracing::GRPCInterceptor.instance]
+ [Labkit::Tracing::GRPCInterceptor.instance]
end
private_class_method :interceptors
@@ -218,7 +218,7 @@ module Gitlab
feature = feature_stack && feature_stack[0]
metadata['call_site'] = feature.to_s if feature
metadata['gitaly-servers'] = address_metadata(remote_storage) if remote_storage
- metadata['x-gitlab-correlation-id'] = Gitlab::CorrelationId.current_id if Gitlab::CorrelationId.current_id
+ metadata['x-gitlab-correlation-id'] = Labkit::Correlation::CorrelationId.current_id if Labkit::Correlation::CorrelationId.current_id
metadata.merge!(server_feature_flags)
diff --git a/lib/gitlab/grape_logging/loggers/correlation_id_logger.rb b/lib/gitlab/grape_logging/loggers/correlation_id_logger.rb
index fa4c5d86d44..bbe4b24c7d4 100644
--- a/lib/gitlab/grape_logging/loggers/correlation_id_logger.rb
+++ b/lib/gitlab/grape_logging/loggers/correlation_id_logger.rb
@@ -6,7 +6,7 @@ module Gitlab
module Loggers
class CorrelationIdLogger < ::GrapeLogging::Loggers::Base
def parameters(_, _)
- { Gitlab::CorrelationId::LOG_KEY => Gitlab::CorrelationId.current_id }
+ { Labkit::Correlation::CorrelationId::LOG_KEY => Labkit::Correlation::CorrelationId.current_id }
end
end
end
diff --git a/lib/gitlab/graphql/authorize.rb b/lib/gitlab/graphql/authorize.rb
index f62813db82c..f8d0208e275 100644
--- a/lib/gitlab/graphql/authorize.rb
+++ b/lib/gitlab/graphql/authorize.rb
@@ -8,7 +8,7 @@ module Gitlab
extend ActiveSupport::Concern
def self.use(schema_definition)
- schema_definition.instrument(:field, Instrumentation.new)
+ schema_definition.instrument(:field, Instrumentation.new, after_built_ins: true)
end
end
end
diff --git a/lib/gitlab/graphql/authorize/authorize_field_service.rb b/lib/gitlab/graphql/authorize/authorize_field_service.rb
index 8deff79fc84..03d6aabb0e3 100644
--- a/lib/gitlab/graphql/authorize/authorize_field_service.rb
+++ b/lib/gitlab/graphql/authorize/authorize_field_service.rb
@@ -15,15 +15,10 @@ module Gitlab
def authorized_resolve
proc do |parent_typed_object, args, ctx|
- resolved_obj = @old_resolve_proc.call(parent_typed_object, args, ctx)
- authorizing_obj = authorize_against(parent_typed_object)
- checker = build_checker(ctx[:current_user], authorizing_obj)
-
- if resolved_obj.respond_to?(:then)
- resolved_obj.then(&checker)
- else
- checker.call(resolved_obj)
- end
+ resolved_type = @old_resolve_proc.call(parent_typed_object, args, ctx)
+ authorizing_object = authorize_against(parent_typed_object, resolved_type)
+
+ filter_allowed(ctx[:current_user], resolved_type, authorizing_object)
end
end
@@ -38,7 +33,7 @@ module Gitlab
type = @field.type
# When the return type of @field is a collection, find the singular type
- if type.get_field('edges')
+ if @field.connection?
type = node_type_for_relay_connection(type)
elsif type.list?
type = node_type_for_basic_connection(type)
@@ -52,43 +47,60 @@ module Gitlab
Array.wrap(@field.metadata[:authorize])
end
- # If it's a built-in/scalar type, authorize using its parent object.
- # nil means authorize using the resolved object
- def authorize_against(parent_typed_object)
- parent_typed_object.object if built_in_type? && parent_typed_object.respond_to?(:object)
+ def authorize_against(parent_typed_object, resolved_type)
+ if built_in_type?
+ # The field is a built-in/scalar type, or a list of scalars
+ # authorize using the parent's object
+ parent_typed_object.object
+ elsif resolved_type.respond_to?(:object)
+ # The field is a type representing a single object, we'll authorize
+ # against the object directly
+ resolved_type.object
+ elsif @field.connection? || resolved_type.is_a?(Array)
+ # The field is a connection or a list of non-built-in types, we'll
+ # authorize each element when rendering
+ nil
+ else
+ # Resolved type is a single object that might not be loaded yet by
+ # the batchloader, we'll authorize that
+ resolved_type
+ end
end
- def build_checker(current_user, authorizing_obj)
- lambda do |resolved_obj|
- # Load the elements if they were not loaded by BatchLoader yet
- resolved_obj = resolved_obj.sync if resolved_obj.respond_to?(:sync)
-
- check = lambda do |object|
- authorizations.all? do |ability|
- Ability.allowed?(current_user, ability, authorizing_obj || object)
- end
+ def filter_allowed(current_user, resolved_type, authorizing_object)
+ if authorizing_object
+ # Authorizing fields representing scalars, or a simple field with an object
+ resolved_type if allowed_access?(current_user, authorizing_object)
+ elsif @field.connection?
+ # A connection with pagination, modify the visible nodes in on the
+ # connection type in place
+ resolved_type.edge_nodes.to_a.keep_if { |node| allowed_access?(current_user, node) }
+ resolved_type
+ elsif resolved_type.is_a? Array
+ # A simple list of rendered types each object being an object to authorize
+ resolved_type.select do |single_object_type|
+ allowed_access?(current_user, single_object_type.object)
end
+ elsif resolved_type.nil?
+ # We're not rendering anything, for example when a record was not found
+ # no need to do anything
+ else
+ raise "Can't authorize #{@field}"
+ end
+ end
- case resolved_obj
- when Array, ActiveRecord::Relation
- resolved_obj.select(&check)
- else
- resolved_obj if check.call(resolved_obj)
- end
+ def allowed_access?(current_user, object)
+ object = object.sync if object.respond_to?(:sync)
+
+ authorizations.all? do |ability|
+ Ability.allowed?(current_user, ability, object)
end
end
# Returns the singular type for relay connections.
# This will be the type class of edges.node
def node_type_for_relay_connection(type)
- type = type.get_field('edges').type.unwrap.get_field('node')&.type
-
- if type.nil?
- raise Gitlab::Graphql::Errors::ConnectionDefinitionError,
- 'Connection Type must conform to the Relay Cursor Connections Specification'
- end
-
- type
+ type.unwrap.get_field('edges').type.unwrap.get_field('node').type
end
# Returns the singular type for basic connections, for example `[Types::ProjectType]`
diff --git a/lib/gitlab/graphql/connections/keyset_connection.rb b/lib/gitlab/graphql/connections/keyset_connection.rb
index 851054c0393..715963a44c1 100644
--- a/lib/gitlab/graphql/connections/keyset_connection.rb
+++ b/lib/gitlab/graphql/connections/keyset_connection.rb
@@ -22,8 +22,17 @@ module Gitlab
end
# rubocop: enable CodeReuse/ActiveRecord
- # rubocop: disable CodeReuse/ActiveRecord
def paged_nodes
+ # These are the nodes that will be loaded into memory for rendering
+ # So we're ok loading them into memory here as that's bound to happen
+ # anyway. Having them ready means we can modify the result while
+ # rendering the fields.
+ @paged_nodes ||= load_paged_nodes.to_a
+ end
+
+ private
+
+ def load_paged_nodes
if first && last
raise Gitlab::Graphql::Errors::ArgumentError.new("Can only provide either `first` or `last`, not both")
end
@@ -31,12 +40,9 @@ module Gitlab
if last
sliced_nodes.last(limit_value)
else
- sliced_nodes.limit(limit_value)
+ sliced_nodes.limit(limit_value) # rubocop: disable CodeReuse/ActiveRecord
end
end
- # rubocop: enable CodeReuse/ActiveRecord
-
- private
def before_slice
if sort_direction == :asc
diff --git a/lib/gitlab/graphql/errors.rb b/lib/gitlab/graphql/errors.rb
index bcbba72e017..fe74549e322 100644
--- a/lib/gitlab/graphql/errors.rb
+++ b/lib/gitlab/graphql/errors.rb
@@ -6,7 +6,6 @@ module Gitlab
BaseError = Class.new(GraphQL::ExecutionError)
ArgumentError = Class.new(BaseError)
ResourceNotAvailable = Class.new(BaseError)
- ConnectionDefinitionError = Class.new(BaseError)
end
end
end
diff --git a/lib/gitlab/json_logger.rb b/lib/gitlab/json_logger.rb
index a5a5759cc89..ab34fb03158 100644
--- a/lib/gitlab/json_logger.rb
+++ b/lib/gitlab/json_logger.rb
@@ -10,7 +10,7 @@ module Gitlab
data = {}
data[:severity] = severity
data[:time] = timestamp.utc.iso8601(3)
- data[Gitlab::CorrelationId::LOG_KEY] = Gitlab::CorrelationId.current_id
+ data[Labkit::Correlation::CorrelationId::LOG_KEY] = Labkit::Correlation::CorrelationId.current_id
case message
when String
diff --git a/lib/gitlab/middleware/correlation_id.rb b/lib/gitlab/middleware/correlation_id.rb
index 80dddc41c12..fffd5da827f 100644
--- a/lib/gitlab/middleware/correlation_id.rb
+++ b/lib/gitlab/middleware/correlation_id.rb
@@ -12,7 +12,7 @@ module Gitlab
end
def call(env)
- ::Gitlab::CorrelationId.use_id(correlation_id(env)) do
+ ::Labkit::Correlation::CorrelationId.use_id(correlation_id(env)) do
@app.call(env)
end
end
diff --git a/lib/gitlab/sentry.rb b/lib/gitlab/sentry.rb
index 956c16117f5..356e6445e0e 100644
--- a/lib/gitlab/sentry.rb
+++ b/lib/gitlab/sentry.rb
@@ -45,7 +45,7 @@ module Gitlab
context # Make sure we've set everything we know in the context
tags = {
- Gitlab::CorrelationId::LOG_KEY.to_sym => Gitlab::CorrelationId.current_id
+ Labkit::Correlation::CorrelationId::LOG_KEY.to_sym => Labkit::Correlation::CorrelationId.current_id
}
Raven.capture_exception(exception, tags: tags, extra: extra)
diff --git a/lib/gitlab/sidekiq_middleware/correlation_injector.rb b/lib/gitlab/sidekiq_middleware/correlation_injector.rb
index b807b3a03ed..1539fd706ab 100644
--- a/lib/gitlab/sidekiq_middleware/correlation_injector.rb
+++ b/lib/gitlab/sidekiq_middleware/correlation_injector.rb
@@ -4,8 +4,8 @@ module Gitlab
module SidekiqMiddleware
class CorrelationInjector
def call(worker_class, job, queue, redis_pool)
- job[Gitlab::CorrelationId::LOG_KEY] ||=
- Gitlab::CorrelationId.current_or_new_id
+ job[Labkit::Correlation::CorrelationId::LOG_KEY] ||=
+ Labkit::Correlation::CorrelationId.current_or_new_id
yield
end
diff --git a/lib/gitlab/sidekiq_middleware/correlation_logger.rb b/lib/gitlab/sidekiq_middleware/correlation_logger.rb
index cb8ff4a6284..cffc4483573 100644
--- a/lib/gitlab/sidekiq_middleware/correlation_logger.rb
+++ b/lib/gitlab/sidekiq_middleware/correlation_logger.rb
@@ -4,9 +4,9 @@ module Gitlab
module SidekiqMiddleware
class CorrelationLogger
def call(worker, job, queue)
- correlation_id = job[Gitlab::CorrelationId::LOG_KEY]
+ correlation_id = job[Labkit::Correlation::CorrelationId::LOG_KEY]
- Gitlab::CorrelationId.use_id(correlation_id) do
+ Labkit::Correlation::CorrelationId.use_id(correlation_id) do
yield
end
end
diff --git a/lib/gitlab/tracing/common.rb b/lib/gitlab/tracing/common.rb
deleted file mode 100644
index 3a08ede8138..00000000000
--- a/lib/gitlab/tracing/common.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-# frozen_string_literal: true
-
-require 'opentracing'
-
-module Gitlab
- module Tracing
- module Common
- def tracer
- OpenTracing.global_tracer
- end
-
- # Convience method for running a block with a span
- def in_tracing_span(operation_name:, tags:, child_of: nil)
- scope = tracer.start_active_span(
- operation_name,
- child_of: child_of,
- tags: tags
- )
- span = scope.span
-
- # Add correlation details to the span if we have them
- correlation_id = Gitlab::CorrelationId.current_id
- if correlation_id
- span.set_tag('correlation_id', correlation_id)
- end
-
- begin
- yield span
- rescue => e
- log_exception_on_span(span, e)
- raise e
- ensure
- scope.close
- end
- end
-
- def postnotify_span(operation_name, start_time, end_time, tags: nil, child_of: nil, exception: nil)
- span = OpenTracing.start_span(operation_name, start_time: start_time, tags: tags, child_of: child_of)
-
- log_exception_on_span(span, exception) if exception
-
- span.finish(end_time: end_time)
- end
-
- def log_exception_on_span(span, exception)
- span.set_tag('error', true)
- span.log_kv(kv_tags_for_exception(exception))
- end
-
- def kv_tags_for_exception(exception)
- case exception
- when Exception
- {
- 'event': 'error',
- 'error.kind': exception.class.to_s,
- 'message': Gitlab::UrlSanitizer.sanitize(exception.message),
- 'stack': exception.backtrace&.join("\n")
- }
- else
- {
- 'event': 'error',
- 'error.kind': exception.class.to_s,
- 'error.object': Gitlab::UrlSanitizer.sanitize(exception.to_s)
- }
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/tracing/factory.rb b/lib/gitlab/tracing/factory.rb
deleted file mode 100644
index fc714164353..00000000000
--- a/lib/gitlab/tracing/factory.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-# frozen_string_literal: true
-
-require "cgi"
-
-module Gitlab
- module Tracing
- class Factory
- OPENTRACING_SCHEME = "opentracing"
-
- def self.create_tracer(service_name, connection_string)
- return unless connection_string.present?
-
- begin
- opentracing_details = parse_connection_string(connection_string)
- driver_name = opentracing_details[:driver_name]
-
- case driver_name
- when "jaeger"
- JaegerFactory.create_tracer(service_name, opentracing_details[:options])
- else
- raise "Unknown driver: #{driver_name}"
- end
- rescue => e
- # Can't create the tracer? Warn and continue sans tracer
- warn "Unable to instantiate tracer: #{e}"
- nil
- end
- end
-
- def self.parse_connection_string(connection_string)
- parsed = URI.parse(connection_string)
-
- unless valid_uri?(parsed)
- raise "Invalid tracing connection string"
- end
-
- {
- driver_name: parsed.host,
- options: parse_query(parsed.query)
- }
- end
- private_class_method :parse_connection_string
-
- def self.parse_query(query)
- return {} unless query
-
- CGI.parse(query).symbolize_keys.transform_values(&:first)
- end
- private_class_method :parse_query
-
- def self.valid_uri?(uri)
- return false unless uri
-
- uri.scheme == OPENTRACING_SCHEME &&
- uri.host.to_s =~ /^[a-z0-9_]+$/ &&
- uri.path.empty?
- end
- private_class_method :valid_uri?
- end
- end
-end
diff --git a/lib/gitlab/tracing/grpc_interceptor.rb b/lib/gitlab/tracing/grpc_interceptor.rb
deleted file mode 100644
index 6c2aab73125..00000000000
--- a/lib/gitlab/tracing/grpc_interceptor.rb
+++ /dev/null
@@ -1,54 +0,0 @@
-# frozen_string_literal: true
-
-require 'opentracing'
-require 'grpc'
-
-module Gitlab
- module Tracing
- class GRPCInterceptor < GRPC::ClientInterceptor
- include Common
- include Singleton
-
- def request_response(request:, call:, method:, metadata:)
- wrap_with_tracing(method, 'unary', metadata) do
- yield
- end
- end
-
- def client_streamer(requests:, call:, method:, metadata:)
- wrap_with_tracing(method, 'client_stream', metadata) do
- yield
- end
- end
-
- def server_streamer(request:, call:, method:, metadata:)
- wrap_with_tracing(method, 'server_stream', metadata) do
- yield
- end
- end
-
- def bidi_streamer(requests:, call:, method:, metadata:)
- wrap_with_tracing(method, 'bidi_stream', metadata) do
- yield
- end
- end
-
- private
-
- def wrap_with_tracing(method, grpc_type, metadata)
- tags = {
- 'component' => 'grpc',
- 'span.kind' => 'client',
- 'grpc.method' => method,
- 'grpc.type' => grpc_type
- }
-
- in_tracing_span(operation_name: "grpc:#{method}", tags: tags) do |span|
- OpenTracing.inject(span.context, OpenTracing::FORMAT_TEXT_MAP, metadata)
-
- yield
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/tracing/jaeger_factory.rb b/lib/gitlab/tracing/jaeger_factory.rb
deleted file mode 100644
index 93520d5667b..00000000000
--- a/lib/gitlab/tracing/jaeger_factory.rb
+++ /dev/null
@@ -1,97 +0,0 @@
-# frozen_string_literal: true
-
-require 'jaeger/client'
-
-module Gitlab
- module Tracing
- class JaegerFactory
- # When the probabilistic sampler is used, by default 0.1% of requests will be traced
- DEFAULT_PROBABILISTIC_RATE = 0.001
-
- # The default port for the Jaeger agent UDP listener
- DEFAULT_UDP_PORT = 6831
-
- # Reduce this from default of 10 seconds as the Ruby jaeger
- # client doesn't have overflow control, leading to very large
- # messages which fail to send over UDP (max packet = 64k)
- # Flush more often, with smaller packets
- FLUSH_INTERVAL = 5
-
- def self.create_tracer(service_name, options)
- kwargs = {
- service_name: service_name,
- sampler: get_sampler(options[:sampler], options[:sampler_param]),
- reporter: get_reporter(service_name, options[:http_endpoint], options[:udp_endpoint])
- }.compact
-
- extra_params = options.except(:sampler, :sampler_param, :http_endpoint, :udp_endpoint, :strict_parsing, :debug) # rubocop: disable CodeReuse/ActiveRecord
- if extra_params.present?
- message = "jaeger tracer: invalid option: #{extra_params.keys.join(", ")}"
-
- if options[:strict_parsing]
- raise message
- else
- warn message
- end
- end
-
- Jaeger::Client.build(kwargs)
- end
-
- def self.get_sampler(sampler_type, sampler_param)
- case sampler_type
- when "probabilistic"
- sampler_rate = sampler_param ? sampler_param.to_f : DEFAULT_PROBABILISTIC_RATE
- Jaeger::Samplers::Probabilistic.new(rate: sampler_rate)
- when "const"
- const_value = sampler_param == "1"
- Jaeger::Samplers::Const.new(const_value)
- else
- nil
- end
- end
- private_class_method :get_sampler
-
- def self.get_reporter(service_name, http_endpoint, udp_endpoint)
- encoder = Jaeger::Encoders::ThriftEncoder.new(service_name: service_name)
-
- if http_endpoint.present?
- sender = get_http_sender(encoder, http_endpoint)
- elsif udp_endpoint.present?
- sender = get_udp_sender(encoder, udp_endpoint)
- else
- return
- end
-
- Jaeger::Reporters::RemoteReporter.new(
- sender: sender,
- flush_interval: FLUSH_INTERVAL
- )
- end
- private_class_method :get_reporter
-
- def self.get_http_sender(encoder, address)
- Jaeger::HttpSender.new(
- url: address,
- encoder: encoder,
- logger: Logger.new(STDOUT)
- )
- end
- private_class_method :get_http_sender
-
- def self.get_udp_sender(encoder, address)
- pair = address.split(":", 2)
- host = pair[0]
- port = pair[1] ? pair[1].to_i : DEFAULT_UDP_PORT
-
- Jaeger::UdpSender.new(
- host: host,
- port: port,
- encoder: encoder,
- logger: Logger.new(STDOUT)
- )
- end
- private_class_method :get_udp_sender
- end
- end
-end
diff --git a/lib/gitlab/tracing/rack_middleware.rb b/lib/gitlab/tracing/rack_middleware.rb
deleted file mode 100644
index e6a31293f7b..00000000000
--- a/lib/gitlab/tracing/rack_middleware.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-
-require 'opentracing'
-
-module Gitlab
- module Tracing
- class RackMiddleware
- include Common
-
- REQUEST_METHOD = 'REQUEST_METHOD'
-
- def initialize(app)
- @app = app
- end
-
- def call(env)
- method = env[REQUEST_METHOD]
-
- context = tracer.extract(OpenTracing::FORMAT_RACK, env)
- tags = {
- 'component' => 'rack',
- 'span.kind' => 'server',
- 'http.method' => method,
- 'http.url' => self.class.build_sanitized_url_from_env(env)
- }
-
- in_tracing_span(operation_name: "http:#{method}", child_of: context, tags: tags) do |span|
- @app.call(env).tap do |status_code, _headers, _body|
- span.set_tag('http.status_code', status_code)
- end
- end
- end
-
- # Generate a sanitized (safe) request URL from the rack environment
- def self.build_sanitized_url_from_env(env)
- request = ActionDispatch::Request.new(env)
-
- original_url = request.original_url
- uri = URI.parse(original_url)
- uri.query = request.filtered_parameters.to_query if uri.query.present?
-
- uri.to_s
- end
- end
- end
-end
diff --git a/lib/gitlab/tracing/rails/action_view_subscriber.rb b/lib/gitlab/tracing/rails/action_view_subscriber.rb
deleted file mode 100644
index 88816e1fb32..00000000000
--- a/lib/gitlab/tracing/rails/action_view_subscriber.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Tracing
- module Rails
- class ActionViewSubscriber
- include RailsCommon
-
- COMPONENT_TAG = 'ActionView'
- RENDER_TEMPLATE_NOTIFICATION_TOPIC = 'render_template.action_view'
- RENDER_COLLECTION_NOTIFICATION_TOPIC = 'render_collection.action_view'
- RENDER_PARTIAL_NOTIFICATION_TOPIC = 'render_partial.action_view'
-
- # Instruments Rails ActionView events for opentracing.
- # Returns a lambda, which, when called will unsubscribe from the notifications
- def self.instrument
- subscriber = new
-
- subscriptions = [
- ActiveSupport::Notifications.subscribe(RENDER_TEMPLATE_NOTIFICATION_TOPIC) do |_, start, finish, _, payload|
- subscriber.notify_render_template(start, finish, payload)
- end,
- ActiveSupport::Notifications.subscribe(RENDER_COLLECTION_NOTIFICATION_TOPIC) do |_, start, finish, _, payload|
- subscriber.notify_render_collection(start, finish, payload)
- end,
- ActiveSupport::Notifications.subscribe(RENDER_PARTIAL_NOTIFICATION_TOPIC) do |_, start, finish, _, payload|
- subscriber.notify_render_partial(start, finish, payload)
- end
- ]
-
- create_unsubscriber subscriptions
- end
-
- # For more information on the payloads: https://guides.rubyonrails.org/active_support_instrumentation.html
- def notify_render_template(start, finish, payload)
- generate_span_for_notification("render_template", start, finish, payload, tags_for_render_template(payload))
- end
-
- def notify_render_collection(start, finish, payload)
- generate_span_for_notification("render_collection", start, finish, payload, tags_for_render_collection(payload))
- end
-
- def notify_render_partial(start, finish, payload)
- generate_span_for_notification("render_partial", start, finish, payload, tags_for_render_partial(payload))
- end
-
- private
-
- def tags_for_render_template(payload)
- {
- 'component' => COMPONENT_TAG,
- 'template.id' => payload[:identifier],
- 'template.layout' => payload[:layout]
- }
- end
-
- def tags_for_render_collection(payload)
- {
- 'component' => COMPONENT_TAG,
- 'template.id' => payload[:identifier],
- 'template.count' => payload[:count] || 0,
- 'template.cache.hits' => payload[:cache_hits] || 0
- }
- end
-
- def tags_for_render_partial(payload)
- {
- 'component' => COMPONENT_TAG,
- 'template.id' => payload[:identifier]
- }
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/tracing/rails/active_record_subscriber.rb b/lib/gitlab/tracing/rails/active_record_subscriber.rb
deleted file mode 100644
index 32f5658e57e..00000000000
--- a/lib/gitlab/tracing/rails/active_record_subscriber.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Tracing
- module Rails
- class ActiveRecordSubscriber
- include RailsCommon
-
- ACTIVE_RECORD_NOTIFICATION_TOPIC = 'sql.active_record'
- OPERATION_NAME_PREFIX = 'active_record:'
- DEFAULT_OPERATION_NAME = 'sqlquery'
-
- # Instruments Rails ActiveRecord events for opentracing.
- # Returns a lambda, which, when called will unsubscribe from the notifications
- def self.instrument
- subscriber = new
-
- subscription = ActiveSupport::Notifications.subscribe(ACTIVE_RECORD_NOTIFICATION_TOPIC) do |_, start, finish, _, payload|
- subscriber.notify(start, finish, payload)
- end
-
- create_unsubscriber [subscription]
- end
-
- # For more information on the payloads: https://guides.rubyonrails.org/active_support_instrumentation.html
- def notify(start, finish, payload)
- generate_span_for_notification(notification_name(payload), start, finish, payload, tags_for_notification(payload))
- end
-
- private
-
- def notification_name(payload)
- OPERATION_NAME_PREFIX + (payload[:name].presence || DEFAULT_OPERATION_NAME)
- end
-
- def tags_for_notification(payload)
- {
- 'component' => 'ActiveRecord',
- 'span.kind' => 'client',
- 'db.type' => 'sql',
- 'db.connection_id' => payload[:connection_id],
- 'db.cached' => payload[:cached] || false,
- 'db.statement' => payload[:sql]
- }
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/tracing/rails/rails_common.rb b/lib/gitlab/tracing/rails/rails_common.rb
deleted file mode 100644
index 88e914f62f8..00000000000
--- a/lib/gitlab/tracing/rails/rails_common.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Tracing
- module Rails
- module RailsCommon
- extend ActiveSupport::Concern
- include Gitlab::Tracing::Common
-
- class_methods do
- def create_unsubscriber(subscriptions)
- -> { subscriptions.each { |subscriber| ActiveSupport::Notifications.unsubscribe(subscriber) } }
- end
- end
-
- def generate_span_for_notification(operation_name, start, finish, payload, tags)
- exception = payload[:exception]
-
- postnotify_span(operation_name, start, finish, tags: tags, exception: exception)
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/tracing/sidekiq/client_middleware.rb b/lib/gitlab/tracing/sidekiq/client_middleware.rb
deleted file mode 100644
index 2b71c1ea21e..00000000000
--- a/lib/gitlab/tracing/sidekiq/client_middleware.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# frozen_string_literal: true
-
-require 'opentracing'
-
-module Gitlab
- module Tracing
- module Sidekiq
- class ClientMiddleware
- include SidekiqCommon
-
- SPAN_KIND = 'client'
-
- def call(worker_class, job, queue, redis_pool)
- in_tracing_span(
- operation_name: "sidekiq:#{job['class']}",
- tags: tags_from_job(job, SPAN_KIND)) do |span|
- # Inject the details directly into the job
- tracer.inject(span.context, OpenTracing::FORMAT_TEXT_MAP, job)
-
- yield
- end
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/tracing/sidekiq/server_middleware.rb b/lib/gitlab/tracing/sidekiq/server_middleware.rb
deleted file mode 100644
index 5b43c4310e6..00000000000
--- a/lib/gitlab/tracing/sidekiq/server_middleware.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# frozen_string_literal: true
-
-require 'opentracing'
-
-module Gitlab
- module Tracing
- module Sidekiq
- class ServerMiddleware
- include SidekiqCommon
-
- SPAN_KIND = 'server'
-
- def call(worker, job, queue)
- context = tracer.extract(OpenTracing::FORMAT_TEXT_MAP, job)
-
- in_tracing_span(
- operation_name: "sidekiq:#{job['class']}",
- child_of: context,
- tags: tags_from_job(job, SPAN_KIND)) do |span|
- yield
- end
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/tracing/sidekiq/sidekiq_common.rb b/lib/gitlab/tracing/sidekiq/sidekiq_common.rb
deleted file mode 100644
index a911a29d773..00000000000
--- a/lib/gitlab/tracing/sidekiq/sidekiq_common.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Tracing
- module Sidekiq
- module SidekiqCommon
- include Gitlab::Tracing::Common
-
- def tags_from_job(job, kind)
- {
- 'component' => 'sidekiq',
- 'span.kind' => kind,
- 'sidekiq.queue' => job['queue'],
- 'sidekiq.jid' => job['jid'],
- 'sidekiq.retry' => job['retry'].to_s,
- 'sidekiq.args' => job['args']&.join(", ")
- }
- end
- end
- end
- end
-end
diff --git a/lib/peek/views/tracing.rb b/lib/peek/views/tracing.rb
index 0de32a8fdda..94726a498ea 100644
--- a/lib/peek/views/tracing.rb
+++ b/lib/peek/views/tracing.rb
@@ -4,9 +4,9 @@ module Peek
module Views
class Tracing < View
def results
- {
- tracing_url: Gitlab::Tracing.tracing_url
- }
+ tracing_url = Labkit::Tracing.tracing_url(Gitlab.process_name)
+
+ { tracing_url: tracing_url }
end
end
end
diff --git a/lib/system_check/app/ruby_version_check.rb b/lib/system_check/app/ruby_version_check.rb
index 60e07718338..53da62df176 100644
--- a/lib/system_check/app/ruby_version_check.rb
+++ b/lib/system_check/app/ruby_version_check.rb
@@ -7,7 +7,7 @@ module SystemCheck
set_check_pass -> { "yes (#{self.current_version})" }
def self.required_version
- @required_version ||= Gitlab::VersionInfo.new(2, 3, 5)
+ @required_version ||= Gitlab::VersionInfo.new(2, 5, 3)
end
def self.current_version
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 0d6cb4c85b5..54c40e48084 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -375,12 +375,6 @@ msgstr ""
msgid "A member of GitLab's abuse team will review your report as soon as possible."
msgstr ""
-msgid "A merge commit is created for every merge, and merging is allowed as long as there are no conflicts."
-msgstr ""
-
-msgid "A merge commit is created for every merge, but merging is only allowed if fast-forward merge is possible. This way you could make sure that if this merge request would build, after merging to target branch it would also build."
-msgstr ""
-
msgid "A new branch will be created in your fork and a new merge request will be started."
msgstr ""
@@ -1173,9 +1167,6 @@ msgstr ""
msgid "Automatically marked as default internal user"
msgstr ""
-msgid "Automatically resolve merge request diff discussions when they become outdated"
-msgstr ""
-
msgid "Automatically resolved"
msgstr ""
@@ -1722,7 +1713,7 @@ msgstr ""
msgid "Choose visibility level, enable/disable project features (issues, repository, wiki, snippets) and set permissions."
msgstr ""
-msgid "Choose your merge method, set up a default merge request description template."
+msgid "Choose your merge method, options, checks, and set up a default merge request description template."
msgstr ""
msgid "CiStatusLabel|canceled"
@@ -4003,9 +3994,6 @@ msgstr ""
msgid "Failure"
msgstr ""
-msgid "Fast-forward merge"
-msgstr ""
-
msgid "Fast-forward merge without a merge commit"
msgstr ""
@@ -5260,6 +5248,9 @@ msgstr ""
msgid "Lead"
msgstr ""
+msgid "Learn how to %{link_start}contribute to the built-in templates%{link_end}"
+msgstr ""
+
msgid "Learn more"
msgstr ""
@@ -5505,15 +5496,9 @@ msgstr ""
msgid "Merge Requests"
msgstr ""
-msgid "Merge commit"
-msgstr ""
-
msgid "Merge commit message"
msgstr ""
-msgid "Merge commit with semi-linear history"
-msgstr ""
-
msgid "Merge events"
msgstr ""
@@ -5523,9 +5508,6 @@ msgstr ""
msgid "Merge in progress"
msgstr ""
-msgid "Merge method"
-msgstr ""
-
msgid "Merge request"
msgstr ""
@@ -5990,9 +5972,6 @@ msgstr ""
msgid "No license. All rights reserved"
msgstr ""
-msgid "No merge commits are created and all merges are fast-forwarded, which means that merging is only allowed if the branch could be fast-forwarded. When fast-forward merge is not possible, the user is given the option to rebase."
-msgstr ""
-
msgid "No merge requests found"
msgstr ""
@@ -6187,12 +6166,6 @@ msgstr ""
msgid "Only admins"
msgstr ""
-msgid "Only allow merge requests to be merged if all discussions are resolved"
-msgstr ""
-
-msgid "Only allow merge requests to be merged if the pipeline succeeds"
-msgstr ""
-
msgid "Only mirror protected branches"
msgstr ""
@@ -6457,9 +6430,6 @@ msgstr ""
msgid "Pipelines for last year"
msgstr ""
-msgid "Pipelines need to be configured to enable this feature."
-msgstr ""
-
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
@@ -7093,15 +7063,69 @@ msgstr ""
msgid "ProjectPage|Project ID: %{project_id}"
msgstr ""
+msgid "ProjectSettings|Additional merge request capabilities that influence how and when merges will be performed"
+msgstr ""
+
+msgid "ProjectSettings|All discussions must be resolved"
+msgstr ""
+
+msgid "ProjectSettings|Automatically resolve merge request diff discussions when they become outdated"
+msgstr ""
+
msgid "ProjectSettings|Badges"
msgstr ""
msgid "ProjectSettings|Customize your project badges."
msgstr ""
+msgid "ProjectSettings|Every merge creates a merge commit"
+msgstr ""
+
+msgid "ProjectSettings|Fast-forward merge"
+msgstr ""
+
+msgid "ProjectSettings|Fast-forward merges only"
+msgstr ""
+
msgid "ProjectSettings|Learn more about badges."
msgstr ""
+msgid "ProjectSettings|Merge checks"
+msgstr ""
+
+msgid "ProjectSettings|Merge commit"
+msgstr ""
+
+msgid "ProjectSettings|Merge commit with semi-linear history"
+msgstr ""
+
+msgid "ProjectSettings|Merge method"
+msgstr ""
+
+msgid "ProjectSettings|Merge options"
+msgstr ""
+
+msgid "ProjectSettings|No merge commits are created"
+msgstr ""
+
+msgid "ProjectSettings|Pipelines must succeed"
+msgstr ""
+
+msgid "ProjectSettings|Pipelines need to be configured to enable this feature."
+msgstr ""
+
+msgid "ProjectSettings|Show link to create/view merge request when pushing from the command line"
+msgstr ""
+
+msgid "ProjectSettings|These checks must pass before merge requests can be merged"
+msgstr ""
+
+msgid "ProjectSettings|This will dictate the commit history when you merge a merge request"
+msgstr ""
+
+msgid "ProjectSettings|When conflicts arise the user is given the option to rebase"
+msgstr ""
+
msgid "Projects"
msgstr ""
@@ -8144,9 +8168,6 @@ msgstr ""
msgid "Show latest version"
msgstr ""
-msgid "Show link to create/view merge request when pushing from the command line"
-msgstr ""
-
msgid "Show parent pages"
msgstr ""
@@ -10165,9 +10186,6 @@ msgstr ""
msgid "When enabled, users cannot use GitLab until the terms have been accepted."
msgstr ""
-msgid "When fast-forward merge is not possible, the user is given the option to rebase."
-msgstr ""
-
msgid "When leaving the URL blank, classification labels can still be specified without disabling cross project features or performing external authorization checks."
msgstr ""
diff --git a/qa/qa/page/component/note.rb b/qa/qa/page/component/note.rb
index f5add6bc9b5..07e191f1c9b 100644
--- a/qa/qa/page/component/note.rb
+++ b/qa/qa/page/component/note.rb
@@ -15,7 +15,7 @@ module QA
element :reply_comment_button
end
- base.view 'app/assets/javascripts/notes/components/noteable_discussion.vue' do
+ base.view 'app/assets/javascripts/notes/components/discussion_actions.vue' do
element :discussion_reply
end
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
index a5ecb475ce3..7296a4b4526 100644
--- a/spec/controllers/application_controller_spec.rb
+++ b/spec/controllers/application_controller_spec.rb
@@ -462,7 +462,7 @@ describe ApplicationController do
end
it 'does log correlation id' do
- Gitlab::CorrelationId.use_id('new-id') do
+ Labkit::Correlation::CorrelationId.use_id('new-id') do
get :index
end
diff --git a/spec/db/importers/common_metrics_importer_spec.rb b/spec/db/importers/common_metrics_importer_spec.rb
index 6133b17ac61..a717c8cd04d 100644
--- a/spec/db/importers/common_metrics_importer_spec.rb
+++ b/spec/db/importers/common_metrics_importer_spec.rb
@@ -23,10 +23,10 @@ describe Importers::CommonMetricsImporter do
subject { described_class.new }
context "does import common_metrics.yml" do
- let(:groups) { subject.content }
- let(:metrics) { groups.map { |group| group['metrics'] }.flatten }
- let(:queries) { metrics.map { |group| group['queries'] }.flatten }
- let(:query_ids) { queries.map { |query| query['id'] } }
+ let(:groups) { subject.content['panel_groups'] }
+ let(:panels) { groups.map { |group| group['panels'] }.flatten }
+ let(:metrics) { panels.map { |group| group['metrics'] }.flatten }
+ let(:metric_ids) { metrics.map { |metric| metric['id'] } }
before do
subject.execute
@@ -36,20 +36,20 @@ describe Importers::CommonMetricsImporter do
expect(PrometheusMetric.common.group(:group).count.count).to eq(groups.count)
end
- it "has the same amount of metrics" do
- expect(PrometheusMetric.common.group(:group, :title).count.count).to eq(metrics.count)
+ it "has the same amount of panels" do
+ expect(PrometheusMetric.common.group(:group, :title).count.count).to eq(panels.count)
end
- it "has the same amount of queries" do
- expect(PrometheusMetric.common.count).to eq(queries.count)
+ it "has the same amount of metrics" do
+ expect(PrometheusMetric.common.count).to eq(metrics.count)
end
it "does not have duplicate IDs" do
- expect(query_ids).to eq(query_ids.uniq)
+ expect(metric_ids).to eq(metric_ids.uniq)
end
it "imports all IDs" do
- expect(PrometheusMetric.common.pluck(:identifier)).to contain_exactly(*query_ids)
+ expect(PrometheusMetric.common.pluck(:identifier)).to contain_exactly(*metric_ids)
end
end
@@ -65,24 +65,26 @@ describe Importers::CommonMetricsImporter do
context 'does import properly all fields' do
let(:query_identifier) { 'response-metric' }
- let(:group) do
+ let(:dashboard) do
{
- group: 'Response metrics (NGINX Ingress)',
- metrics: [{
- title: "Throughput",
- y_label: "Requests / Sec",
- queries: [{
- id: query_identifier,
- query_range: 'my-query',
- unit: 'my-unit',
- label: 'status code'
+ panel_groups: [{
+ group: 'Response metrics (NGINX Ingress)',
+ panels: [{
+ title: "Throughput",
+ y_label: "Requests / Sec",
+ metrics: [{
+ id: query_identifier,
+ query_range: 'my-query',
+ unit: 'my-unit',
+ label: 'status code'
+ }]
}]
}]
}
end
before do
- expect(subject).to receive(:content) { [group.deep_stringify_keys] }
+ expect(subject).to receive(:content) { dashboard.deep_stringify_keys }
end
shared_examples 'stores metric' do
diff --git a/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb b/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb
index b1c2bab08c0..28d52f25f56 100644
--- a/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb
+++ b/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb
@@ -1,3 +1,4 @@
+# frozen_string_literal: true
require 'spec_helper'
describe 'Projects > Settings > User manages merge request settings' do
@@ -30,16 +31,16 @@ describe 'Projects > Settings > User manages merge request settings' do
context 'when Merge Request and Pipelines are initially enabled', :js do
context 'when Pipelines are initially enabled' do
it 'shows the Merge Requests settings' do
- expect(page).to have_content('Only allow merge requests to be merged if the pipeline succeeds')
- expect(page).to have_content('Only allow merge requests to be merged if all discussions are resolved')
+ expect(page).to have_content 'Pipelines must succeed'
+ expect(page).to have_content 'All discussions must be resolved'
within('.sharing-permissions-form') do
find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .project-feature-toggle').click
find('input[value="Save changes"]').send_keys(:return)
end
- expect(page).not_to have_content('Only allow merge requests to be merged if the pipeline succeeds')
- expect(page).not_to have_content('Only allow merge requests to be merged if all discussions are resolved')
+ expect(page).not_to have_content 'Pipelines must succeed'
+ expect(page).not_to have_content 'All discussions must be resolved'
end
end
@@ -50,16 +51,16 @@ describe 'Projects > Settings > User manages merge request settings' do
end
it 'shows the Merge Requests settings that do not depend on Builds feature' do
- expect(page).not_to have_content('Only allow merge requests to be merged if the pipeline succeeds')
- expect(page).to have_content('Only allow merge requests to be merged if all discussions are resolved')
+ expect(page).not_to have_content 'Pipelines must succeed'
+ expect(page).to have_content 'All discussions must be resolved'
within('.sharing-permissions-form') do
find('.project-feature-controls[data-for="project[project_feature_attributes][builds_access_level]"] .project-feature-toggle').click
find('input[value="Save changes"]').send_keys(:return)
end
- expect(page).to have_content('Only allow merge requests to be merged if the pipeline succeeds')
- expect(page).to have_content('Only allow merge requests to be merged if all discussions are resolved')
+ expect(page).to have_content 'Pipelines must succeed'
+ expect(page).to have_content 'All discussions must be resolved'
end
end
end
@@ -71,16 +72,16 @@ describe 'Projects > Settings > User manages merge request settings' do
end
it 'does not show the Merge Requests settings' do
- expect(page).not_to have_content('Only allow merge requests to be merged if the pipeline succeeds')
- expect(page).not_to have_content('Only allow merge requests to be merged if all discussions are resolved')
+ expect(page).not_to have_content 'Pipelines must succeed'
+ expect(page).not_to have_content 'All discussions must be resolved'
within('.sharing-permissions-form') do
find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .project-feature-toggle').click
find('input[value="Save changes"]').send_keys(:return)
end
- expect(page).to have_content('Only allow merge requests to be merged if the pipeline succeeds')
- expect(page).to have_content('Only allow merge requests to be merged if all discussions are resolved')
+ expect(page).to have_content 'Pipelines must succeed'
+ expect(page).to have_content 'All discussions must be resolved'
end
end
diff --git a/spec/frontend/clusters/components/application_row_spec.js b/spec/frontend/clusters/components/application_row_spec.js
index b28d0075d06..038d2be9e98 100644
--- a/spec/frontend/clusters/components/application_row_spec.js
+++ b/spec/frontend/clusters/components/application_row_spec.js
@@ -114,10 +114,12 @@ describe('Application Row', () => {
expect(vm.installButtonDisabled).toEqual(true);
});
- it('has disabled "Installed" when APPLICATION_STATUS.INSTALLED', () => {
+ it('has disabled "Installed" when application is installed and not uninstallable', () => {
vm = mountComponent(ApplicationRow, {
...DEFAULT_APPLICATION_STATE,
status: APPLICATION_STATUS.INSTALLED,
+ installed: true,
+ uninstallable: false,
});
expect(vm.installButtonLabel).toEqual('Installed');
@@ -125,15 +127,16 @@ describe('Application Row', () => {
expect(vm.installButtonDisabled).toEqual(true);
});
- it('has disabled "Installed" when APPLICATION_STATUS.UPDATING', () => {
+ it('hides when application is installed and uninstallable', () => {
vm = mountComponent(ApplicationRow, {
...DEFAULT_APPLICATION_STATE,
- status: APPLICATION_STATUS.UPDATING,
+ status: APPLICATION_STATUS.INSTALLED,
+ installed: true,
+ uninstallable: true,
});
+ const installBtn = vm.$el.querySelector('.js-cluster-application-install-button');
- expect(vm.installButtonLabel).toEqual('Installed');
- expect(vm.installButtonLoading).toEqual(false);
- expect(vm.installButtonDisabled).toEqual(true);
+ expect(installBtn).toBe(null);
});
it('has enabled "Install" when APPLICATION_STATUS.ERROR', () => {
@@ -208,6 +211,19 @@ describe('Application Row', () => {
});
});
+ describe('Uninstall button', () => {
+ it('displays button when app is installed and uninstallable', () => {
+ vm = mountComponent(ApplicationRow, {
+ ...DEFAULT_APPLICATION_STATE,
+ installed: true,
+ uninstallable: true,
+ });
+ const uninstallButton = vm.$el.querySelector('.js-cluster-application-uninstall-button');
+
+ expect(uninstallButton).toBeTruthy();
+ });
+ });
+
describe('Upgrade button', () => {
it('has indeterminate state on page load', () => {
vm = mountComponent(ApplicationRow, {
diff --git a/spec/frontend/clusters/stores/clusters_store_spec.js b/spec/frontend/clusters/stores/clusters_store_spec.js
index 161722ec571..c0e8b737ea2 100644
--- a/spec/frontend/clusters/stores/clusters_store_spec.js
+++ b/spec/frontend/clusters/stores/clusters_store_spec.js
@@ -1,5 +1,5 @@
import ClustersStore from '~/clusters/stores/clusters_store';
-import { APPLICATION_STATUS } from '~/clusters/constants';
+import { APPLICATION_INSTALLED_STATUSES, APPLICATION_STATUS, RUNNER } from '~/clusters/constants';
import { CLUSTERS_MOCK_DATA } from '../services/mock_data';
describe('Clusters Store', () => {
@@ -70,6 +70,7 @@ describe('Clusters Store', () => {
statusReason: mockResponseData.applications[0].status_reason,
requestStatus: null,
requestReason: null,
+ installed: false,
},
ingress: {
title: 'Ingress',
@@ -79,6 +80,7 @@ describe('Clusters Store', () => {
requestReason: null,
externalIp: null,
externalHostname: null,
+ installed: false,
},
runner: {
title: 'GitLab Runner',
@@ -89,6 +91,7 @@ describe('Clusters Store', () => {
version: mockResponseData.applications[2].version,
upgradeAvailable: mockResponseData.applications[2].update_available,
chartRepo: 'https://gitlab.com/charts/gitlab-runner',
+ installed: false,
},
prometheus: {
title: 'Prometheus',
@@ -96,6 +99,7 @@ describe('Clusters Store', () => {
statusReason: mockResponseData.applications[3].status_reason,
requestStatus: null,
requestReason: null,
+ installed: false,
},
jupyter: {
title: 'JupyterHub',
@@ -104,6 +108,7 @@ describe('Clusters Store', () => {
requestStatus: null,
requestReason: null,
hostname: '',
+ installed: false,
},
knative: {
title: 'Knative',
@@ -115,6 +120,7 @@ describe('Clusters Store', () => {
isEditingHostName: false,
externalIp: null,
externalHostname: null,
+ installed: false,
},
cert_manager: {
title: 'Cert-Manager',
@@ -123,11 +129,26 @@ describe('Clusters Store', () => {
requestStatus: null,
requestReason: null,
email: mockResponseData.applications[6].email,
+ installed: false,
},
},
});
});
+ describe.each(APPLICATION_INSTALLED_STATUSES)('given the current app status is %s', () => {
+ it('marks application as installed', () => {
+ const mockResponseData =
+ CLUSTERS_MOCK_DATA.GET['/gitlab-org/gitlab-shell/clusters/2/status.json'].data;
+ const runnerAppIndex = 2;
+
+ mockResponseData.applications[runnerAppIndex].status = APPLICATION_STATUS.INSTALLED;
+
+ store.updateStateFromServer(mockResponseData);
+
+ expect(store.state.applications[RUNNER].installed).toBe(true);
+ });
+ });
+
it('sets default hostname for jupyter when ingress has a ip address', () => {
const mockResponseData =
CLUSTERS_MOCK_DATA.GET['/gitlab-org/gitlab-shell/clusters/2/status.json'].data;
diff --git a/spec/frontend/gfm_auto_complete_spec.js b/spec/frontend/gfm_auto_complete_spec.js
index ed12af925f1..841aff0d7ff 100644
--- a/spec/frontend/gfm_auto_complete_spec.js
+++ b/spec/frontend/gfm_auto_complete_spec.js
@@ -94,7 +94,7 @@ describe('GfmAutoComplete', () => {
});
it('should quote if value contains any non-alphanumeric characters', () => {
- expect(beforeInsert(atwhoInstance, '~label-20')).toBe('~"label\\-20"');
+ expect(beforeInsert(atwhoInstance, '~label-20')).toBe('~"label-20"');
expect(beforeInsert(atwhoInstance, '~label 20')).toBe('~"label 20"');
});
@@ -102,12 +102,21 @@ describe('GfmAutoComplete', () => {
expect(beforeInsert(atwhoInstance, '~1234')).toBe('~"1234"');
});
- it('should escape Markdown emphasis characters, except in the first character', () => {
- expect(beforeInsert(atwhoInstance, '@_group')).toEqual('@\\_group');
- expect(beforeInsert(atwhoInstance, '~_bug')).toEqual('~\\_bug');
+ it('escapes Markdown strikethroughs when needed', () => {
+ expect(beforeInsert(atwhoInstance, '~a~bug')).toEqual('~"a~bug"');
+ expect(beforeInsert(atwhoInstance, '~a~~bug~~')).toEqual('~"a\\~~bug\\~~"');
+ });
+
+ it('escapes Markdown emphasis when needed', () => {
+ expect(beforeInsert(atwhoInstance, '~a_bug_')).toEqual('~a_bug\\_');
+ expect(beforeInsert(atwhoInstance, '~a _bug_')).toEqual('~"a \\_bug\\_"');
+ expect(beforeInsert(atwhoInstance, '~a*bug*')).toEqual('~"a\\*bug\\*"');
+ expect(beforeInsert(atwhoInstance, '~a *bug*')).toEqual('~"a \\*bug\\*"');
+ });
+
+ it('escapes Markdown code spans when needed', () => {
+ expect(beforeInsert(atwhoInstance, '~a`bug`')).toEqual('~"a\\`bug\\`"');
expect(beforeInsert(atwhoInstance, '~a `bug`')).toEqual('~"a \\`bug\\`"');
- expect(beforeInsert(atwhoInstance, '~a ~bug')).toEqual('~"a \\~bug"');
- expect(beforeInsert(atwhoInstance, '~a **bug')).toEqual('~"a \\*\\*bug"');
});
});
diff --git a/spec/frontend/notes/components/discussion_actions_spec.js b/spec/frontend/notes/components/discussion_actions_spec.js
new file mode 100644
index 00000000000..0a52c81571e
--- /dev/null
+++ b/spec/frontend/notes/components/discussion_actions_spec.js
@@ -0,0 +1,104 @@
+import createStore from '~/notes/stores';
+import { shallowMount, mount, createLocalVue } from '@vue/test-utils';
+import { discussionMock } from '../../../javascripts/notes/mock_data';
+import DiscussionActions from '~/notes/components/discussion_actions.vue';
+import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
+import ResolveDiscussionButton from '~/notes/components/discussion_resolve_button.vue';
+import ResolveWithIssueButton from '~/notes/components/discussion_resolve_with_issue_button.vue';
+import JumpToNextDiscussionButton from '~/notes/components/discussion_jump_to_next_button.vue';
+
+describe('DiscussionActions', () => {
+ let wrapper;
+ const createComponentFactory = (shallow = true) => props => {
+ const localVue = createLocalVue();
+ const store = createStore();
+ const mountFn = shallow ? shallowMount : mount;
+
+ wrapper = mountFn(DiscussionActions, {
+ localVue,
+ store,
+ propsData: {
+ discussion: discussionMock,
+ isResolving: false,
+ resolveButtonTitle: 'Resolve discussion',
+ resolveWithIssuePath: '/some/issue/path',
+ shouldShowJumpToNextDiscussion: true,
+ ...props,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('rendering', () => {
+ const createComponent = createComponentFactory();
+
+ it('renders reply placeholder, resolve discussion button, resolve with issue button and jump to next discussion button', () => {
+ createComponent();
+ expect(wrapper.find(ReplyPlaceholder).exists()).toBe(true);
+ expect(wrapper.find(ResolveDiscussionButton).exists()).toBe(true);
+ expect(wrapper.find(ResolveWithIssueButton).exists()).toBe(true);
+ expect(wrapper.find(JumpToNextDiscussionButton).exists()).toBe(true);
+ });
+
+ it('only renders reply placholder if disccusion is not resolvable', () => {
+ const discussion = { ...discussionMock };
+ discussion.resolvable = false;
+ createComponent({ discussion });
+
+ expect(wrapper.find(ReplyPlaceholder).exists()).toBe(true);
+ expect(wrapper.find(ResolveDiscussionButton).exists()).toBe(false);
+ expect(wrapper.find(ResolveWithIssueButton).exists()).toBe(false);
+ expect(wrapper.find(JumpToNextDiscussionButton).exists()).toBe(false);
+ });
+
+ it('does not render resolve with issue button if resolveWithIssuePath is falsy', () => {
+ createComponent({ resolveWithIssuePath: '' });
+
+ expect(wrapper.find(ResolveWithIssueButton).exists()).toBe(false);
+ });
+
+ it('does not render jump to next discussion button if shouldShowJumpToNextDiscussion is false', () => {
+ createComponent({ shouldShowJumpToNextDiscussion: false });
+
+ expect(wrapper.find(JumpToNextDiscussionButton).exists()).toBe(false);
+ });
+ });
+
+ describe('events handling', () => {
+ const createComponent = createComponentFactory(false);
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('emits showReplyForm event when clicking on reply placeholder', () => {
+ jest.spyOn(wrapper.vm, '$emit');
+ wrapper
+ .find(ReplyPlaceholder)
+ .find('button')
+ .trigger('click');
+ expect(wrapper.vm.$emit).toHaveBeenCalledWith('showReplyForm');
+ });
+
+ it('emits resolve event when clicking on resolve button', () => {
+ jest.spyOn(wrapper.vm, '$emit');
+ wrapper
+ .find(ResolveDiscussionButton)
+ .find('button')
+ .trigger('click');
+ expect(wrapper.vm.$emit).toHaveBeenCalledWith('resolve');
+ });
+
+ it('emits jumpToNextDiscussion event when clicking on jump to next discussion button', () => {
+ jest.spyOn(wrapper.vm, '$emit');
+ wrapper
+ .find(JumpToNextDiscussionButton)
+ .find('button')
+ .trigger('click');
+ expect(wrapper.vm.$emit).toHaveBeenCalledWith('jumpToNextDiscussion');
+ });
+ });
+});
diff --git a/spec/frontend/pages/admin/abuse_reports/abuse_reports_spec.js b/spec/frontend/pages/admin/abuse_reports/abuse_reports_spec.js
index 7e9aec84016..f163bdd9913 100644
--- a/spec/frontend/pages/admin/abuse_reports/abuse_reports_spec.js
+++ b/spec/frontend/pages/admin/abuse_reports/abuse_reports_spec.js
@@ -1,6 +1,9 @@
import $ from 'jquery';
import '~/lib/utils/text_utility';
import AbuseReports from '~/pages/admin/abuse_reports/abuse_reports';
+import { setTestTimeout } from 'helpers/timeout';
+
+setTestTimeout(500);
describe('Abuse Reports', () => {
const FIXTURE = 'abuse_reports/abuse_reports_list.html';
diff --git a/spec/graphql/features/authorization_spec.rb b/spec/graphql/features/authorization_spec.rb
index 00e31568a9e..f5eb628a982 100644
--- a/spec/graphql/features/authorization_spec.rb
+++ b/spec/graphql/features/authorization_spec.rb
@@ -177,6 +177,7 @@ describe 'Gitlab::Graphql::Authorization' do
describe 'type authorizations when applied to a relay connection' do
let(:query_string) { '{ object() { edges { node { name } } } }' }
+ let(:second_test_object) { double(name: 'Second thing') }
let(:type) do
type_factory do |type|
@@ -186,22 +187,41 @@ describe 'Gitlab::Graphql::Authorization' do
let(:query_type) do
query_factory do |query|
- query.field :object, type.connection_type, null: true, resolve: ->(obj, args, ctx) { [test_object] }
+ query.field :object, type.connection_type, null: true, resolve: ->(obj, args, ctx) { [test_object, second_test_object] }
end
end
subject { result.dig('object', 'edges') }
- it 'returns the protected field when user has permission' do
+ it 'returns only the elements visible to the user' do
permit(permission_single)
- expect(subject).not_to be_empty
+ expect(subject.size).to eq 1
expect(subject.first['node']).to eq('name' => test_object.name)
end
it 'returns nil when user is not authorized' do
expect(subject).to be_empty
end
+
+ describe 'limiting connections with multiple objects' do
+ let(:query_type) do
+ query_factory do |query|
+ query.field :object, type.connection_type, null: true, resolve: ->(obj, args, ctx) do
+ [test_object, second_test_object]
+ end
+ end
+ end
+
+ let(:query_string) { '{ object(first: 1) { edges { node { name } } } }' }
+
+ it 'only checks permissions for the first object' do
+ expect(Ability).to receive(:allowed?).with(user, permission_single, test_object) { true }
+ expect(Ability).not_to receive(:allowed?).with(user, permission_single, second_test_object)
+
+ expect(subject.size).to eq(1)
+ end
+ end
end
describe 'type authorizations when applied to a basic connection' do
@@ -222,28 +242,53 @@ describe 'Gitlab::Graphql::Authorization' do
include_examples 'authorization with a single permission'
end
- describe 'when connections do not follow the correct specification' do
- let(:query_string) { '{ object() { edges { node { name }} } }' }
+ describe 'Authorizations on active record relations' do
+ let!(:visible_project) { create(:project, :private) }
+ let!(:other_project) { create(:project, :private) }
+ let!(:visible_issues) { create_list(:issue, 2, project: visible_project) }
+ let!(:other_issues) { create_list(:issue, 2, project: other_project) }
+ let!(:user) { visible_project.owner }
- let(:type) do
- bad_node = type_factory do |type|
- type.graphql_name 'BadNode'
- type.field :bad_node, GraphQL::STRING_TYPE, null: true
+ let(:issue_type) do
+ type_factory do |type|
+ type.graphql_name 'FakeIssueType'
+ type.authorize :read_issue
+ type.field :id, GraphQL::ID_TYPE, null: false
end
-
+ end
+ let(:project_type) do |type|
type_factory do |type|
- type.field :edges, [bad_node], null: true
+ type.graphql_name 'FakeProjectType'
+ type.field :test_issues, issue_type.connection_type, null: false, resolve: -> (_, _, _) { Issue.where(project: [visible_project, other_project]) }
end
end
-
let(:query_type) do
query_factory do |query|
- query.field :object, type, null: true
+ query.field :test_project, project_type, null: false, resolve: -> (_, _, _) { visible_project }
end
end
+ let(:query_string) do
+ <<~QRY
+ { testProject { testIssues(first: 3) { edges { node { id } } } } }
+ QRY
+ end
+
+ before do
+ allow(Ability).to receive(:allowed?).and_call_original
+ end
+
+ it 'renders the issues the user has access to' do
+ issue_edges = result['testProject']['testIssues']['edges']
+ issue_ids = issue_edges.map { |issue_edge| issue_edge['node']&.fetch('id') }
+
+ expect(issue_edges.size).to eq(visible_issues.size)
+ expect(issue_ids).to eq(visible_issues.map { |i| i.id.to_s })
+ end
+
+ it 'does not check access on fields that will not be rendered' do
+ expect(Ability).not_to receive(:allowed?).with(user, :read_issue, other_issues.last)
- it 'throws an error' do
- expect { result }.to raise_error(Gitlab::Graphql::Errors::ConnectionDefinitionError)
+ result
end
end
@@ -276,6 +321,8 @@ describe 'Gitlab::Graphql::Authorization' do
def execute_query(query_type)
schema = Class.new(GraphQL::Schema) do
use Gitlab::Graphql::Authorize
+ use Gitlab::Graphql::Connections
+
query(query_type)
end
diff --git a/spec/graphql/gitlab_schema_spec.rb b/spec/graphql/gitlab_schema_spec.rb
index 74e93b2c4df..05f10fb40f0 100644
--- a/spec/graphql/gitlab_schema_spec.rb
+++ b/spec/graphql/gitlab_schema_spec.rb
@@ -74,6 +74,6 @@ describe GitlabSchema do
end
def field_instrumenters
- described_class.instrumenters[:field]
+ described_class.instrumenters[:field] + described_class.instrumenters[:field_after_built_ins]
end
end
diff --git a/spec/javascripts/boards/board_list_common_spec.js b/spec/javascripts/boards/board_list_common_spec.js
new file mode 100644
index 00000000000..cb337e4cc83
--- /dev/null
+++ b/spec/javascripts/boards/board_list_common_spec.js
@@ -0,0 +1,58 @@
+/* global List */
+/* global ListIssue */
+
+import MockAdapter from 'axios-mock-adapter';
+import Vue from 'vue';
+import axios from '~/lib/utils/axios_utils';
+import Sortable from 'sortablejs';
+import BoardList from '~/boards/components/board_list.vue';
+
+import '~/boards/models/issue';
+import '~/boards/models/list';
+import { listObj, boardsMockInterceptor, mockBoardService } from './mock_data';
+import boardsStore from '~/boards/stores/boards_store';
+
+window.Sortable = Sortable;
+
+export default function createComponent({ done, listIssueProps = {}, componentProps = {} }) {
+ const el = document.createElement('div');
+
+ document.body.appendChild(el);
+ const mock = new MockAdapter(axios);
+ mock.onAny().reply(boardsMockInterceptor);
+ gl.boardService = mockBoardService();
+ boardsStore.create();
+
+ const BoardListComp = Vue.extend(BoardList);
+ const list = new List(listObj);
+ const issue = new ListIssue({
+ title: 'Testing',
+ id: 1,
+ iid: 1,
+ confidential: false,
+ labels: [],
+ assignees: [],
+ ...listIssueProps,
+ });
+ list.issuesSize = 1;
+ list.issues.push(issue);
+
+ const component = new BoardListComp({
+ el,
+ propsData: {
+ disabled: false,
+ list,
+ issues: list.issues,
+ loading: false,
+ issueLinkBase: '/issues',
+ rootPath: '/',
+ ...componentProps,
+ },
+ }).$mount();
+
+ Vue.nextTick(() => {
+ done();
+ });
+
+ return { component, mock };
+}
diff --git a/spec/javascripts/boards/board_list_spec.js b/spec/javascripts/boards/board_list_spec.js
index 396fc823ef5..9c9b435d7fd 100644
--- a/spec/javascripts/boards/board_list_spec.js
+++ b/spec/javascripts/boards/board_list_spec.js
@@ -1,60 +1,13 @@
-/* global List */
-/* global ListIssue */
-
import Vue from 'vue';
-import MockAdapter from 'axios-mock-adapter';
-import axios from '~/lib/utils/axios_utils';
-import Sortable from 'sortablejs';
-import BoardList from '~/boards/components/board_list.vue';
import eventHub from '~/boards/eventhub';
-import '~/boards/models/issue';
-import '~/boards/models/list';
-import boardsStore from '~/boards/stores/boards_store';
-import { listObj, boardsMockInterceptor, mockBoardService } from './mock_data';
-
-window.Sortable = Sortable;
+import createComponent from './board_list_common_spec';
describe('Board list component', () => {
let mock;
let component;
beforeEach(done => {
- const el = document.createElement('div');
-
- document.body.appendChild(el);
- mock = new MockAdapter(axios);
- mock.onAny().reply(boardsMockInterceptor);
- gl.boardService = mockBoardService();
- boardsStore.create();
-
- const BoardListComp = Vue.extend(BoardList);
- const list = new List(listObj);
- const issue = new ListIssue({
- title: 'Testing',
- id: 1,
- iid: 1,
- confidential: false,
- labels: [],
- assignees: [],
- });
- list.issuesSize = 1;
- list.issues.push(issue);
-
- component = new BoardListComp({
- el,
- propsData: {
- disabled: false,
- list,
- issues: list.issues,
- loading: false,
- issueLinkBase: '/issues',
- rootPath: '/',
- },
- }).$mount();
-
- Vue.nextTick(() => {
- done();
- });
+ ({ mock, component } = createComponent({ done }));
});
afterEach(() => {
diff --git a/spec/javascripts/boards/issue_card_spec.js b/spec/javascripts/boards/issue_card_spec.js
index 6eda5047dd0..a5bf97bdcc2 100644
--- a/spec/javascripts/boards/issue_card_spec.js
+++ b/spec/javascripts/boards/issue_card_spec.js
@@ -285,4 +285,10 @@ describe('Issue card component', () => {
.catch(done.fail);
});
});
+
+ describe('weights', () => {
+ it('not shows weight component', () => {
+ expect(component.$el.querySelector('.board-card-weight')).toBeNull();
+ });
+ });
});
diff --git a/spec/javascripts/monitoring/monitoring_store_spec.js b/spec/javascripts/monitoring/monitoring_store_spec.js
index d8a980c874d..5bf6937c92e 100644
--- a/spec/javascripts/monitoring/monitoring_store_spec.js
+++ b/spec/javascripts/monitoring/monitoring_store_spec.js
@@ -32,4 +32,28 @@ describe('MonitoringStore', () => {
it('removes the data if all the values from a query are not defined', () => {
expect(store.groups[1].metrics[0].queries[0].result.length).toEqual(0);
});
+
+ it('assigns queries a metric id', () => {
+ expect(store.groups[1].metrics[0].queries[0].metricId).toEqual('100');
+ });
+
+ it('assigns metric id of null if metric has no id', () => {
+ const noId = MonitoringMock.data.map(group => ({
+ ...group,
+ ...{
+ metrics: group.metrics.map(metric => {
+ const { id, ...metricWithoutId } = metric;
+
+ return metricWithoutId;
+ }),
+ },
+ }));
+ store.storeMetrics(noId);
+
+ store.groups.forEach(group => {
+ group.metrics.forEach(metric => {
+ expect(metric.queries.every(query => query.metricId === null)).toBe(true);
+ });
+ });
+ });
});
diff --git a/spec/lib/gitlab/correlation_id_spec.rb b/spec/lib/gitlab/correlation_id_spec.rb
deleted file mode 100644
index 584d1f48386..00000000000
--- a/spec/lib/gitlab/correlation_id_spec.rb
+++ /dev/null
@@ -1,77 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-
-describe Gitlab::CorrelationId do
- describe '.use_id' do
- it 'yields when executed' do
- expect { |blk| described_class.use_id('id', &blk) }.to yield_control
- end
-
- it 'stacks correlation ids' do
- described_class.use_id('id1') do
- described_class.use_id('id2') do |current_id|
- expect(current_id).to eq('id2')
- end
- end
- end
-
- it 'for missing correlation id it generates random one' do
- described_class.use_id('id1') do
- described_class.use_id(nil) do |current_id|
- expect(current_id).not_to be_empty
- expect(current_id).not_to eq('id1')
- end
- end
- end
- end
-
- describe '.current_id' do
- subject { described_class.current_id }
-
- it 'returns last correlation id' do
- described_class.use_id('id1') do
- described_class.use_id('id2') do
- is_expected.to eq('id2')
- end
- end
- end
- end
-
- describe '.current_or_new_id' do
- subject { described_class.current_or_new_id }
-
- context 'when correlation id is set' do
- it 'returns last correlation id' do
- described_class.use_id('id1') do
- is_expected.to eq('id1')
- end
- end
- end
-
- context 'when correlation id is missing' do
- it 'returns a new correlation id' do
- expect(described_class).to receive(:new_id)
- .and_call_original
-
- is_expected.not_to be_empty
- end
- end
- end
-
- describe '.ids' do
- subject { described_class.send(:ids) }
-
- it 'returns empty list if not correlation is used' do
- is_expected.to be_empty
- end
-
- it 'returns list if correlation ids are used' do
- described_class.use_id('id1') do
- described_class.use_id('id2') do
- is_expected.to eq(%w(id1 id2))
- end
- end
- end
- end
-end
diff --git a/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb b/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb
index 6114aca0616..95a4eb296fb 100644
--- a/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb
+++ b/spec/lib/gitlab/graphql/authorize/authorize_field_service_spec.rb
@@ -5,92 +5,104 @@ require 'spec_helper'
# Also see spec/graphql/features/authorization_spec.rb for
# integration tests of AuthorizeFieldService
describe Gitlab::Graphql::Authorize::AuthorizeFieldService do
- describe '#build_checker' do
- let(:current_user) { double(:current_user) }
- let(:abilities) { [double(:first_ability), double(:last_ability)] }
-
- context 'when authorizing against the object' do
- let(:checker) do
- service = described_class.new(double(resolve_proc: proc {}))
- allow(service).to receive(:authorizations).and_return(abilities)
- service.__send__(:build_checker, current_user, nil)
- end
+ def type(type_authorizations = [])
+ Class.new(Types::BaseObject) do
+ graphql_name "TestType"
- it 'returns a checker which checks for a single object' do
- object = double(:object)
+ authorize type_authorizations
+ end
+ end
- abilities.each do |ability|
- spy_ability_check_for(ability, object, passed: true)
- end
+ def type_with_field(field_type, field_authorizations = [], resolved_value = "Resolved value")
+ Class.new(Types::BaseObject) do
+ graphql_name "TestTypeWithField"
+ field :test_field, field_type, null: true, authorize: field_authorizations, resolve: -> (_, _, _) { resolved_value}
+ end
+ end
- expect(checker.call(object)).to eq(object)
- end
+ let(:current_user) { double(:current_user) }
+ subject(:service) { described_class.new(field) }
- it 'returns a checker which checks for all objects' do
- objects = [double(:first), double(:last)]
+ describe "#authorized_resolve" do
+ let(:presented_object) { double("presented object") }
+ let(:presented_type) { double("parent type", object: presented_object) }
+ subject(:resolved) { service.authorized_resolve.call(presented_type, {}, { current_user: current_user }) }
- abilities.each do |ability|
- objects.each do |object|
- spy_ability_check_for(ability, object, passed: true)
+ context "scalar types" do
+ shared_examples "checking permissions on the presented object" do
+ it "checks the abilities on the object being presented and returns the value" do
+ expected_permissions.each do |permission|
+ spy_ability_check_for(permission, presented_object, passed: true)
end
+
+ expect(resolved).to eq("Resolved value")
end
- expect(checker.call(objects)).to eq(objects)
+ it "returns nil if the value wasn't authorized" do
+ allow(Ability).to receive(:allowed?).and_return false
+
+ expect(resolved).to be_nil
+ end
end
- context 'when some objects would not pass the check' do
- it 'returns nil when it is single object' do
- disallowed = double(:object)
+ context "when the field is a scalar type" do
+ let(:field) { type_with_field(GraphQL::STRING_TYPE, :read_field).fields["testField"].to_graphql }
+ let(:expected_permissions) { [:read_field] }
- spy_ability_check_for(abilities.first, disallowed, passed: false)
+ it_behaves_like "checking permissions on the presented object"
+ end
- expect(checker.call(disallowed)).to be_nil
- end
+ context "when the field is a list of scalar types" do
+ let(:field) { type_with_field([GraphQL::STRING_TYPE], :read_field).fields["testField"].to_graphql }
+ let(:expected_permissions) { [:read_field] }
- it 'returns only objects which passed when there are more than one' do
- allowed = double(:allowed)
- disallowed = double(:disallowed)
+ it_behaves_like "checking permissions on the presented object"
+ end
+ end
- spy_ability_check_for(abilities.first, disallowed, passed: false)
+ context "when the field is a specific type" do
+ let(:custom_type) { type(:read_type) }
+ let(:object_in_field) { double("presented in field") }
+ let(:field) { type_with_field(custom_type, :read_field, object_in_field).fields["testField"].to_graphql }
- abilities.each do |ability|
- spy_ability_check_for(ability, allowed, passed: true)
- end
+ it "checks both field & type permissions" do
+ spy_ability_check_for(:read_field, object_in_field, passed: true)
+ spy_ability_check_for(:read_type, object_in_field, passed: true)
- expect(checker.call([disallowed, allowed])).to contain_exactly(allowed)
- end
+ expect(resolved).to eq(object_in_field)
end
- end
- context 'when authorizing against another object' do
- let(:authorizing_obj) { double(:object) }
+ it "returns nil if viewing was not allowed" do
+ spy_ability_check_for(:read_field, object_in_field, passed: false)
+ spy_ability_check_for(:read_type, object_in_field, passed: true)
- let(:checker) do
- service = described_class.new(double(resolve_proc: proc {}))
- allow(service).to receive(:authorizations).and_return(abilities)
- service.__send__(:build_checker, current_user, authorizing_obj)
+ expect(resolved).to be_nil
end
- it 'returns a checker which checks for a single object' do
- object = double(:object)
+ context "when the field is a list" do
+ let(:object_1) { double("presented in field 1") }
+ let(:object_2) { double("presented in field 2") }
+ let(:presented_types) { [double(object: object_1), double(object: object_2)] }
+ let(:field) { type_with_field([custom_type], :read_field, presented_types).fields["testField"].to_graphql }
- abilities.each do |ability|
- spy_ability_check_for(ability, authorizing_obj, passed: true)
+ it "checks all permissions" do
+ allow(Ability).to receive(:allowed?) { true }
+
+ spy_ability_check_for(:read_field, object_1, passed: true)
+ spy_ability_check_for(:read_type, object_1, passed: true)
+ spy_ability_check_for(:read_field, object_2, passed: true)
+ spy_ability_check_for(:read_type, object_2, passed: true)
+
+ expect(resolved).to eq(presented_types)
end
- expect(checker.call(object)).to eq(object)
- end
+ it "filters out objects that the user cannot see" do
+ allow(Ability).to receive(:allowed?) { true }
- it 'returns a checker which checks for all objects' do
- objects = [double(:first), double(:last)]
+ spy_ability_check_for(:read_type, object_1, passed: false)
- abilities.each do |ability|
- objects.each do |object|
- spy_ability_check_for(ability, authorizing_obj, passed: true)
- end
+ expect(resolved.map(&:object)).to contain_exactly(object_2)
end
-
- expect(checker.call(objects)).to eq(objects)
end
end
end
diff --git a/spec/lib/gitlab/graphql/connections/keyset_connection_spec.rb b/spec/lib/gitlab/graphql/connections/keyset_connection_spec.rb
index 9bcc1e78a78..fefa2881b18 100644
--- a/spec/lib/gitlab/graphql/connections/keyset_connection_spec.rb
+++ b/spec/lib/gitlab/graphql/connections/keyset_connection_spec.rb
@@ -85,6 +85,11 @@ describe Gitlab::Graphql::Connections::KeysetConnection do
expect(subject.paged_nodes.size).to eq(3)
end
+ it 'is a loaded memoized array' do
+ expect(subject.paged_nodes).to be_an(Array)
+ expect(subject.paged_nodes.object_id).to eq(subject.paged_nodes.object_id)
+ end
+
context 'when `first` is passed' do
let(:arguments) { { first: 2 } }
diff --git a/spec/lib/gitlab/json_logger_spec.rb b/spec/lib/gitlab/json_logger_spec.rb
index cff7dd58c8c..d3d9fe9948a 100644
--- a/spec/lib/gitlab/json_logger_spec.rb
+++ b/spec/lib/gitlab/json_logger_spec.rb
@@ -8,7 +8,7 @@ describe Gitlab::JsonLogger do
describe '#format_message' do
before do
- allow(Gitlab::CorrelationId).to receive(:current_id).and_return('new-correlation-id')
+ allow(Labkit::Correlation::CorrelationId).to receive(:current_id).and_return('new-correlation-id')
end
it 'formats strings' do
diff --git a/spec/lib/gitlab/sentry_spec.rb b/spec/lib/gitlab/sentry_spec.rb
index 1128eaf8560..ae522a588ee 100644
--- a/spec/lib/gitlab/sentry_spec.rb
+++ b/spec/lib/gitlab/sentry_spec.rb
@@ -27,7 +27,7 @@ describe Gitlab::Sentry do
context 'when exceptions should not be raised' do
before do
allow(described_class).to receive(:should_raise_for_dev?).and_return(false)
- allow(Gitlab::CorrelationId).to receive(:current_id).and_return('cid')
+ allow(Labkit::Correlation::CorrelationId).to receive(:current_id).and_return('cid')
end
it 'logs the exception with all attributes passed' do
@@ -65,7 +65,7 @@ describe Gitlab::Sentry do
before do
allow(described_class).to receive(:enabled?).and_return(true)
- allow(Gitlab::CorrelationId).to receive(:current_id).and_return('cid')
+ allow(Labkit::Correlation::CorrelationId).to receive(:current_id).and_return('cid')
end
it 'calls Raven.capture_exception' do
diff --git a/spec/lib/gitlab/sidekiq_middleware/correlation_injector_spec.rb b/spec/lib/gitlab/sidekiq_middleware/correlation_injector_spec.rb
index a138ad7c910..0ff694d409b 100644
--- a/spec/lib/gitlab/sidekiq_middleware/correlation_injector_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware/correlation_injector_spec.rb
@@ -30,7 +30,7 @@ describe Gitlab::SidekiqMiddleware::CorrelationInjector do
it 'injects into payload the correlation id' do
expect_any_instance_of(described_class).to receive(:call).and_call_original
- Gitlab::CorrelationId.use_id('new-correlation-id') do
+ Labkit::Correlation::CorrelationId.use_id('new-correlation-id') do
TestWorker.perform_async(1234)
end
diff --git a/spec/lib/gitlab/sidekiq_middleware/correlation_logger_spec.rb b/spec/lib/gitlab/sidekiq_middleware/correlation_logger_spec.rb
index 94ae4ffa184..8410467ef1f 100644
--- a/spec/lib/gitlab/sidekiq_middleware/correlation_logger_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware/correlation_logger_spec.rb
@@ -23,7 +23,7 @@ describe Gitlab::SidekiqMiddleware::CorrelationLogger do
expect_any_instance_of(described_class).to receive(:call).and_call_original
expect_any_instance_of(TestWorker).to receive(:perform).with(1234) do
- expect(Gitlab::CorrelationId.current_id).to eq('new-correlation-id')
+ expect(Labkit::Correlation::CorrelationId.current_id).to eq('new-correlation-id')
end
Sidekiq::Client.push(
diff --git a/spec/lib/gitlab/tracing/factory_spec.rb b/spec/lib/gitlab/tracing/factory_spec.rb
deleted file mode 100644
index 945490f0988..00000000000
--- a/spec/lib/gitlab/tracing/factory_spec.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-
-describe Gitlab::Tracing::Factory do
- describe '.create_tracer' do
- let(:service_name) { 'rspec' }
-
- context "when tracing is not configured" do
- it 'ignores null connection strings' do
- expect(described_class.create_tracer(service_name, nil)).to be_nil
- end
-
- it 'ignores empty connection strings' do
- expect(described_class.create_tracer(service_name, '')).to be_nil
- end
-
- it 'ignores unknown implementations' do
- expect(described_class.create_tracer(service_name, 'opentracing://invalid_driver')).to be_nil
- end
-
- it 'ignores invalid connection strings' do
- expect(described_class.create_tracer(service_name, 'open?tracing')).to be_nil
- end
- end
-
- context "when tracing is configured with jaeger" do
- let(:mock_tracer) { double('tracer') }
-
- it 'processes default connections' do
- expect(Gitlab::Tracing::JaegerFactory).to receive(:create_tracer).with(service_name, {}).and_return(mock_tracer)
-
- expect(described_class.create_tracer(service_name, 'opentracing://jaeger')).to be(mock_tracer)
- end
-
- it 'processes connections with parameters' do
- expect(Gitlab::Tracing::JaegerFactory).to receive(:create_tracer).with(service_name, { a: '1', b: '2', c: '3' }).and_return(mock_tracer)
-
- expect(described_class.create_tracer(service_name, 'opentracing://jaeger?a=1&b=2&c=3')).to be(mock_tracer)
- end
- end
- end
-end
diff --git a/spec/lib/gitlab/tracing/grpc_interceptor_spec.rb b/spec/lib/gitlab/tracing/grpc_interceptor_spec.rb
deleted file mode 100644
index 7f5aecb7baa..00000000000
--- a/spec/lib/gitlab/tracing/grpc_interceptor_spec.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-
-describe Gitlab::Tracing::GRPCInterceptor do
- subject { described_class.instance }
-
- shared_examples_for "a grpc interceptor method" do
- let(:custom_error) { Class.new(StandardError) }
-
- it 'yields' do
- expect { |b| method.call(kwargs, &b) }.to yield_control
- end
-
- it 'propagates exceptions' do
- expect { method.call(kwargs) { raise custom_error } }.to raise_error(custom_error)
- end
- end
-
- describe '#request_response' do
- let(:method) { subject.method(:request_response) }
- let(:kwargs) { { request: {}, call: {}, method: 'grc_method', metadata: {} } }
-
- it_behaves_like 'a grpc interceptor method'
- end
-
- describe '#client_streamer' do
- let(:method) { subject.method(:client_streamer) }
- let(:kwargs) { { requests: [], call: {}, method: 'grc_method', metadata: {} } }
-
- it_behaves_like 'a grpc interceptor method'
- end
-
- describe '#server_streamer' do
- let(:method) { subject.method(:server_streamer) }
- let(:kwargs) { { request: {}, call: {}, method: 'grc_method', metadata: {} } }
-
- it_behaves_like 'a grpc interceptor method'
- end
-
- describe '#bidi_streamer' do
- let(:method) { subject.method(:bidi_streamer) }
- let(:kwargs) { { requests: [], call: {}, method: 'grc_method', metadata: {} } }
-
- it_behaves_like 'a grpc interceptor method'
- end
-end
diff --git a/spec/lib/gitlab/tracing/jaeger_factory_spec.rb b/spec/lib/gitlab/tracing/jaeger_factory_spec.rb
deleted file mode 100644
index 3d6a007cfd9..00000000000
--- a/spec/lib/gitlab/tracing/jaeger_factory_spec.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-
-describe Gitlab::Tracing::JaegerFactory do
- describe '.create_tracer' do
- let(:service_name) { 'rspec' }
-
- shared_examples_for 'a jaeger tracer' do
- it 'responds to active_span methods' do
- expect(tracer).to respond_to(:active_span)
- end
-
- it 'yields control' do
- expect { |b| tracer.start_active_span('operation_name', &b) }.to yield_control
- end
- end
-
- context 'processes default connections' do
- it_behaves_like 'a jaeger tracer' do
- let(:tracer) { described_class.create_tracer(service_name, {}) }
- end
- end
-
- context 'handles debug options' do
- it_behaves_like 'a jaeger tracer' do
- let(:tracer) { described_class.create_tracer(service_name, { debug: "1" }) }
- end
- end
-
- context 'handles const sampler' do
- it_behaves_like 'a jaeger tracer' do
- let(:tracer) { described_class.create_tracer(service_name, { sampler: "const", sampler_param: "1" }) }
- end
- end
-
- context 'handles probabilistic sampler' do
- it_behaves_like 'a jaeger tracer' do
- let(:tracer) { described_class.create_tracer(service_name, { sampler: "probabilistic", sampler_param: "0.5" }) }
- end
- end
-
- context 'handles http_endpoint configurations' do
- it_behaves_like 'a jaeger tracer' do
- let(:tracer) { described_class.create_tracer(service_name, { http_endpoint: "http://localhost:1234" }) }
- end
- end
-
- context 'handles udp_endpoint configurations' do
- it_behaves_like 'a jaeger tracer' do
- let(:tracer) { described_class.create_tracer(service_name, { udp_endpoint: "localhost:4321" }) }
- end
- end
-
- context 'ignores invalid parameters' do
- it_behaves_like 'a jaeger tracer' do
- let(:tracer) { described_class.create_tracer(service_name, { invalid: "true" }) }
- end
- end
-
- context 'accepts the debug parameter when strict_parser is set' do
- it_behaves_like 'a jaeger tracer' do
- let(:tracer) { described_class.create_tracer(service_name, { debug: "1", strict_parsing: "1" }) }
- end
- end
-
- it 'rejects invalid parameters when strict_parser is set' do
- expect { described_class.create_tracer(service_name, { invalid: "true", strict_parsing: "1" }) }.to raise_error(StandardError)
- end
- end
-end
diff --git a/spec/lib/gitlab/tracing/rack_middleware_spec.rb b/spec/lib/gitlab/tracing/rack_middleware_spec.rb
deleted file mode 100644
index 13d4d8a89f7..00000000000
--- a/spec/lib/gitlab/tracing/rack_middleware_spec.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe Gitlab::Tracing::RackMiddleware do
- using RSpec::Parameterized::TableSyntax
-
- describe '#call' do
- context 'for normal middleware flow' do
- let(:fake_app) { -> (env) { fake_app_response } }
- subject { described_class.new(fake_app) }
- let(:request) { }
-
- context 'for 200 responses' do
- let(:fake_app_response) { [200, { 'Content-Type': 'text/plain' }, ['OK']] }
-
- it 'delegates correctly' do
- expect(subject.call(Rack::MockRequest.env_for("/"))).to eq(fake_app_response)
- end
- end
-
- context 'for 500 responses' do
- let(:fake_app_response) { [500, { 'Content-Type': 'text/plain' }, ['Error']] }
-
- it 'delegates correctly' do
- expect(subject.call(Rack::MockRequest.env_for("/"))).to eq(fake_app_response)
- end
- end
- end
-
- context 'when an application is raising an exception' do
- let(:custom_error) { Class.new(StandardError) }
- let(:fake_app) { ->(env) { raise custom_error } }
-
- subject { described_class.new(fake_app) }
-
- it 'delegates propagates exceptions correctly' do
- expect { subject.call(Rack::MockRequest.env_for("/")) }.to raise_error(custom_error)
- end
- end
- end
-
- describe '.build_sanitized_url_from_env' do
- def env_for_url(url)
- env = Rack::MockRequest.env_for(input_url)
- env['action_dispatch.parameter_filter'] = [/token/]
-
- env
- end
-
- where(:input_url, :output_url) do
- '/gitlab-org/gitlab-ce' | 'http://example.org/gitlab-org/gitlab-ce'
- '/gitlab-org/gitlab-ce?safe=1' | 'http://example.org/gitlab-org/gitlab-ce?safe=1'
- '/gitlab-org/gitlab-ce?private_token=secret' | 'http://example.org/gitlab-org/gitlab-ce?private_token=%5BFILTERED%5D'
- '/gitlab-org/gitlab-ce?mixed=1&private_token=secret' | 'http://example.org/gitlab-org/gitlab-ce?mixed=1&private_token=%5BFILTERED%5D'
- end
-
- with_them do
- it { expect(described_class.build_sanitized_url_from_env(env_for_url(input_url))).to eq(output_url) }
- end
- end
-end
diff --git a/spec/lib/gitlab/tracing/rails/action_view_subscriber_spec.rb b/spec/lib/gitlab/tracing/rails/action_view_subscriber_spec.rb
deleted file mode 100644
index 0bbaf5968ed..00000000000
--- a/spec/lib/gitlab/tracing/rails/action_view_subscriber_spec.rb
+++ /dev/null
@@ -1,147 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-require 'rspec-parameterized'
-
-describe Gitlab::Tracing::Rails::ActionViewSubscriber do
- using RSpec::Parameterized::TableSyntax
-
- shared_examples 'an actionview notification' do
- it 'notifies the tracer when the hash contains null values' do
- expect(subject).to receive(:postnotify_span).with(notification_name, start, finish, tags: expected_tags, exception: exception)
-
- subject.public_send(notify_method, start, finish, payload)
- end
-
- it 'notifies the tracer when the payload is missing values' do
- expect(subject).to receive(:postnotify_span).with(notification_name, start, finish, tags: expected_tags, exception: exception)
-
- subject.public_send(notify_method, start, finish, payload.compact)
- end
-
- it 'does not throw exceptions when with the default tracer' do
- expect { subject.public_send(notify_method, start, finish, payload) }.not_to raise_error
- end
- end
-
- describe '.instrument' do
- it 'is unsubscribeable' do
- unsubscribe = described_class.instrument
-
- expect(unsubscribe).not_to be_nil
- expect { unsubscribe.call }.not_to raise_error
- end
- end
-
- describe '#notify_render_template' do
- subject { described_class.new }
- let(:start) { Time.now }
- let(:finish) { Time.now }
- let(:notification_name) { 'render_template' }
- let(:notify_method) { :notify_render_template }
-
- where(:identifier, :layout, :exception) do
- nil | nil | nil
- "" | nil | nil
- "show.haml" | nil | nil
- nil | "" | nil
- nil | "layout.haml" | nil
- nil | nil | StandardError.new
- end
-
- with_them do
- let(:payload) do
- {
- exception: exception,
- identifier: identifier,
- layout: layout
- }
- end
-
- let(:expected_tags) do
- {
- 'component' => 'ActionView',
- 'template.id' => identifier,
- 'template.layout' => layout
- }
- end
-
- it_behaves_like 'an actionview notification'
- end
- end
-
- describe '#notify_render_collection' do
- subject { described_class.new }
- let(:start) { Time.now }
- let(:finish) { Time.now }
- let(:notification_name) { 'render_collection' }
- let(:notify_method) { :notify_render_collection }
-
- where(
- :identifier, :count, :expected_count, :cache_hits, :expected_cache_hits, :exception) do
- nil | nil | 0 | nil | 0 | nil
- "" | nil | 0 | nil | 0 | nil
- "show.haml" | nil | 0 | nil | 0 | nil
- nil | 0 | 0 | nil | 0 | nil
- nil | 1 | 1 | nil | 0 | nil
- nil | nil | 0 | 0 | 0 | nil
- nil | nil | 0 | 1 | 1 | nil
- nil | nil | 0 | nil | 0 | StandardError.new
- end
-
- with_them do
- let(:payload) do
- {
- exception: exception,
- identifier: identifier,
- count: count,
- cache_hits: cache_hits
- }
- end
-
- let(:expected_tags) do
- {
- 'component' => 'ActionView',
- 'template.id' => identifier,
- 'template.count' => expected_count,
- 'template.cache.hits' => expected_cache_hits
- }
- end
-
- it_behaves_like 'an actionview notification'
- end
- end
-
- describe '#notify_render_partial' do
- subject { described_class.new }
- let(:start) { Time.now }
- let(:finish) { Time.now }
- let(:notification_name) { 'render_partial' }
- let(:notify_method) { :notify_render_partial }
-
- where(:identifier, :exception) do
- nil | nil
- "" | nil
- "show.haml" | nil
- nil | StandardError.new
- end
-
- with_them do
- let(:payload) do
- {
- exception: exception,
- identifier: identifier
- }
- end
-
- let(:expected_tags) do
- {
- 'component' => 'ActionView',
- 'template.id' => identifier
- }
- end
-
- it_behaves_like 'an actionview notification'
- end
- end
-end
diff --git a/spec/lib/gitlab/tracing/rails/active_record_subscriber_spec.rb b/spec/lib/gitlab/tracing/rails/active_record_subscriber_spec.rb
deleted file mode 100644
index 7bd0875fa68..00000000000
--- a/spec/lib/gitlab/tracing/rails/active_record_subscriber_spec.rb
+++ /dev/null
@@ -1,73 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-require 'rspec-parameterized'
-
-describe Gitlab::Tracing::Rails::ActiveRecordSubscriber do
- using RSpec::Parameterized::TableSyntax
-
- describe '.instrument' do
- it 'is unsubscribeable' do
- unsubscribe = described_class.instrument
-
- expect(unsubscribe).not_to be_nil
- expect { unsubscribe.call }.not_to raise_error
- end
- end
-
- describe '#notify' do
- subject { described_class.new }
- let(:start) { Time.now }
- let(:finish) { Time.now }
-
- where(:name, :operation_name, :exception, :connection_id, :cached, :cached_response, :sql) do
- nil | "active_record:sqlquery" | nil | nil | nil | false | nil
- "" | "active_record:sqlquery" | nil | nil | nil | false | nil
- "User Load" | "active_record:User Load" | nil | nil | nil | false | nil
- "Repo Load" | "active_record:Repo Load" | StandardError.new | nil | nil | false | nil
- nil | "active_record:sqlquery" | nil | 123 | nil | false | nil
- nil | "active_record:sqlquery" | nil | nil | false | false | nil
- nil | "active_record:sqlquery" | nil | nil | true | true | nil
- nil | "active_record:sqlquery" | nil | nil | true | true | "SELECT * FROM users"
- end
-
- with_them do
- def payload
- {
- name: name,
- exception: exception,
- connection_id: connection_id,
- cached: cached,
- sql: sql
- }
- end
-
- def expected_tags
- {
- "component" => "ActiveRecord",
- "span.kind" => "client",
- "db.type" => "sql",
- "db.connection_id" => connection_id,
- "db.cached" => cached_response,
- "db.statement" => sql
- }
- end
-
- it 'notifies the tracer when the hash contains null values' do
- expect(subject).to receive(:postnotify_span).with(operation_name, start, finish, tags: expected_tags, exception: exception)
-
- subject.notify(start, finish, payload)
- end
-
- it 'notifies the tracer when the payload is missing values' do
- expect(subject).to receive(:postnotify_span).with(operation_name, start, finish, tags: expected_tags, exception: exception)
-
- subject.notify(start, finish, payload.compact)
- end
-
- it 'does not throw exceptions when with the default tracer' do
- expect { subject.notify(start, finish, payload) }.not_to raise_error
- end
- end
- end
-end
diff --git a/spec/lib/gitlab/tracing/sidekiq/client_middleware_spec.rb b/spec/lib/gitlab/tracing/sidekiq/client_middleware_spec.rb
deleted file mode 100644
index 3755860b5ba..00000000000
--- a/spec/lib/gitlab/tracing/sidekiq/client_middleware_spec.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-
-describe Gitlab::Tracing::Sidekiq::ClientMiddleware do
- describe '#call' do
- let(:worker_class) { 'test_worker_class' }
- let(:job) do
- {
- 'class' => "jobclass",
- 'queue' => "jobqueue",
- 'retry' => 0,
- 'args' => %w{1 2 3}
- }
- end
- let(:queue) { 'test_queue' }
- let(:redis_pool) { double("redis_pool") }
- let(:custom_error) { Class.new(StandardError) }
- let(:span) { OpenTracing.start_span('test', ignore_active_scope: true) }
-
- subject { described_class.new }
-
- it 'yields' do
- expect(subject).to receive(:in_tracing_span).with(
- operation_name: "sidekiq:jobclass",
- tags: {
- "component" => "sidekiq",
- "span.kind" => "client",
- "sidekiq.queue" => "jobqueue",
- "sidekiq.jid" => nil,
- "sidekiq.retry" => "0",
- "sidekiq.args" => "1, 2, 3"
- }
- ).and_yield(span)
-
- expect { |b| subject.call(worker_class, job, queue, redis_pool, &b) }.to yield_control
- end
-
- it 'propagates exceptions' do
- expect { subject.call(worker_class, job, queue, redis_pool) { raise custom_error } }.to raise_error(custom_error)
- end
- end
-end
diff --git a/spec/lib/gitlab/tracing/sidekiq/server_middleware_spec.rb b/spec/lib/gitlab/tracing/sidekiq/server_middleware_spec.rb
deleted file mode 100644
index c3087de785a..00000000000
--- a/spec/lib/gitlab/tracing/sidekiq/server_middleware_spec.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-
-describe Gitlab::Tracing::Sidekiq::ServerMiddleware do
- describe '#call' do
- let(:worker_class) { 'test_worker_class' }
- let(:job) do
- {
- 'class' => "jobclass",
- 'queue' => "jobqueue",
- 'retry' => 0,
- 'args' => %w{1 2 3}
- }
- end
- let(:queue) { 'test_queue' }
- let(:custom_error) { Class.new(StandardError) }
- let(:span) { OpenTracing.start_span('test', ignore_active_scope: true) }
- subject { described_class.new }
-
- it 'yields' do
- expect(subject).to receive(:in_tracing_span).with(
- hash_including(
- operation_name: "sidekiq:jobclass",
- tags: {
- "component" => "sidekiq",
- "span.kind" => "server",
- "sidekiq.queue" => "jobqueue",
- "sidekiq.jid" => nil,
- "sidekiq.retry" => "0",
- "sidekiq.args" => "1, 2, 3"
- }
- )
- ).and_yield(span)
-
- expect { |b| subject.call(worker_class, job, queue, &b) }.to yield_control
- end
-
- it 'propagates exceptions' do
- expect { subject.call(worker_class, job, queue) { raise custom_error } }.to raise_error(custom_error)
- end
- end
-end
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index 66be192ab21..95b9bd4a4d9 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -31,6 +31,10 @@ describe Ci::Build do
it { is_expected.to be_a(ArtifactMigratable) }
+ it_behaves_like 'UpdateProjectStatistics' do
+ subject { FactoryBot.build(:ci_build, pipeline: pipeline, artifacts_size: 23) }
+ end
+
describe 'associations' do
it 'has a bidirectional relationship with projects' do
expect(described_class.reflect_on_association(:project).has_inverse?).to eq(:builds)
@@ -2119,54 +2123,6 @@ describe Ci::Build do
end
end
- context 'when updating the build' do
- let(:build) { create(:ci_build, artifacts_size: 23) }
-
- it 'updates project statistics' do
- build.artifacts_size = 42
-
- expect(build).to receive(:update_project_statistics_after_save).and_call_original
-
- expect { build.save! }
- .to change { build.project.statistics.reload.build_artifacts_size }
- .by(19)
- end
-
- context 'when the artifact size stays the same' do
- it 'does not update project statistics' do
- build.name = 'changed'
-
- expect(build).not_to receive(:update_project_statistics_after_save)
-
- build.save!
- end
- end
- end
-
- context 'when destroying the build' do
- let!(:build) { create(:ci_build, artifacts_size: 23) }
-
- it 'updates project statistics' do
- expect(ProjectStatistics)
- .to receive(:increment_statistic)
- .and_call_original
-
- expect { build.destroy! }
- .to change { build.project.statistics.reload.build_artifacts_size }
- .by(-23)
- end
-
- context 'when the build is destroyed due to the project being destroyed' do
- it 'does not update the project statistics' do
- expect(ProjectStatistics)
- .not_to receive(:increment_statistic)
-
- build.project.update(pending_delete: true)
- build.project.destroy!
- end
- end
- end
-
describe '#variables' do
let(:container_registry_enabled) { false }
diff --git a/spec/models/ci/job_artifact_spec.rb b/spec/models/ci/job_artifact_spec.rb
index d7abd54eec1..5964f66c398 100644
--- a/spec/models/ci/job_artifact_spec.rb
+++ b/spec/models/ci/job_artifact_spec.rb
@@ -5,6 +5,10 @@ require 'spec_helper'
describe Ci::JobArtifact do
let(:artifact) { create(:ci_job_artifact, :archive) }
+ it_behaves_like 'UpdateProjectStatistics' do
+ subject { build(:ci_job_artifact, :archive, size: 106365) }
+ end
+
describe "Associations" do
it { is_expected.to belong_to(:project) }
it { is_expected.to belong_to(:job) }
@@ -102,12 +106,6 @@ describe Ci::JobArtifact do
it 'sets the size from the file size' do
expect(artifact.size).to eq(106365)
end
-
- it 'updates the project statistics' do
- expect { artifact }
- .to change { project.statistics.reload.build_artifacts_size }
- .by(106365)
- end
end
context 'updating the artifact file' do
@@ -115,12 +113,6 @@ describe Ci::JobArtifact do
artifact.update!(file: fixture_file_upload('spec/fixtures/dk.png'))
expect(artifact.size).to eq(1062)
end
-
- it 'updates the project statistics' do
- expect { artifact.update!(file: fixture_file_upload('spec/fixtures/dk.png')) }
- .to change { artifact.project.statistics.reload.build_artifacts_size }
- .by(1062 - 106365)
- end
end
describe 'validates file format' do
@@ -259,34 +251,6 @@ describe Ci::JobArtifact do
end
end
- context 'when destroying the artifact' do
- let(:project) { create(:project, :repository) }
- let(:pipeline) { create(:ci_pipeline, project: project) }
- let!(:build) { create(:ci_build, :artifacts, pipeline: pipeline) }
-
- it 'updates the project statistics' do
- artifact = build.job_artifacts.first
-
- expect(ProjectStatistics)
- .to receive(:increment_statistic)
- .and_call_original
-
- expect { artifact.destroy }
- .to change { project.statistics.reload.build_artifacts_size }
- .by(-106365)
- end
-
- context 'when it is destroyed from the project level' do
- it 'does not update the project statistics' do
- expect(ProjectStatistics)
- .not_to receive(:increment_statistic)
-
- project.update(pending_delete: true)
- project.destroy!
- end
- end
- end
-
describe 'file is being stored' do
subject { create(:ci_job_artifact, :archive) }
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 387d1221c76..95a4b0f6d71 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -63,6 +63,11 @@ describe Namespace do
end
end
+ describe 'delegate' do
+ it { is_expected.to delegate_method(:name).to(:owner).with_prefix.with_arguments(allow_nil: true) }
+ it { is_expected.to delegate_method(:avatar_url).to(:owner).with_arguments(allow_nil: true) }
+ end
+
describe "Respond to" do
it { is_expected.to respond_to(:human_name) }
it { is_expected.to respond_to(:to_param) }
@@ -801,4 +806,21 @@ describe Namespace do
end
end
end
+
+ describe '#user?' do
+ subject { namespace.user? }
+
+ context 'when type is a user' do
+ let(:user) { create(:user) }
+ let(:namespace) { user.namespace }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when type is a group' do
+ let(:namespace) { create(:group) }
+
+ it { is_expected.to be_falsy }
+ end
+ end
end
diff --git a/spec/requests/api/graphql/project/issues_spec.rb b/spec/requests/api/graphql/project/issues_spec.rb
index c2934430821..4f9f916f22e 100644
--- a/spec/requests/api/graphql/project/issues_spec.rb
+++ b/spec/requests/api/graphql/project/issues_spec.rb
@@ -7,8 +7,8 @@ describe 'getting an issue list for a project' do
let(:current_user) { create(:user) }
let(:issues_data) { graphql_data['project']['issues']['edges'] }
let!(:issues) do
- create(:issue, project: project, discussion_locked: true)
- create(:issue, project: project)
+ [create(:issue, project: project, discussion_locked: true),
+ create(:issue, project: project)]
end
let(:fields) do
<<~QUERY
@@ -47,6 +47,30 @@ describe 'getting an issue list for a project' do
expect(issues_data[1]['node']['discussionLocked']).to eq true
end
+ context 'when limiting the number of results' do
+ let(:query) do
+ graphql_query_for(
+ 'project',
+ { 'fullPath' => project.full_path },
+ "issues(first: 1) { #{fields} }"
+ )
+ end
+
+ it_behaves_like 'a working graphql query' do
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+ end
+
+ it "is expected to check permissions on the first issue only" do
+ allow(Ability).to receive(:allowed?).and_call_original
+ # Newest first, we only want to see the newest checked
+ expect(Ability).not_to receive(:allowed?).with(current_user, :read_issue, issues.first)
+
+ post_graphql(query, current_user: current_user)
+ end
+ end
+
context 'when the user does not have access to the issue' do
it 'returns nil' do
project.project_feature.update!(issues_access_level: ProjectFeature::PRIVATE)
diff --git a/spec/requests/api/helpers_spec.rb b/spec/requests/api/helpers_spec.rb
index a0c64d295c0..25a312cb734 100644
--- a/spec/requests/api/helpers_spec.rb
+++ b/spec/requests/api/helpers_spec.rb
@@ -251,7 +251,7 @@ describe API::Helpers do
correlation_id: 'new-correlation-id'
}, extra: {})
- Gitlab::CorrelationId.use_id('new-correlation-id') do
+ Labkit::Correlation::CorrelationId.use_id('new-correlation-id') do
handle_api_exception(exception)
end
end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 352ea448c00..577f61ae8d0 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -1047,7 +1047,6 @@ describe API::Projects do
expect(json_response['http_url_to_repo']).to be_present
expect(json_response['web_url']).to be_present
expect(json_response['owner']).to be_a Hash
- expect(json_response['owner']).to be_a Hash
expect(json_response['name']).to eq(project.name)
expect(json_response['path']).to be_present
expect(json_response['issues_enabled']).to be_present
@@ -1135,7 +1134,9 @@ describe API::Projects do
'path' => user.namespace.path,
'kind' => user.namespace.kind,
'full_path' => user.namespace.full_path,
- 'parent_id' => nil
+ 'parent_id' => nil,
+ 'avatar_url' => user.avatar_url,
+ 'web_url' => Gitlab::Routing.url_helpers.user_url(user)
})
end
@@ -1337,6 +1338,37 @@ describe API::Projects do
end
end
end
+
+ context 'when project belongs to a group namespace' do
+ let(:group) { create(:group, :with_avatar) }
+ let(:project) { create(:project, namespace: group) }
+ let!(:project_member) { create(:project_member, :developer, user: user, project: project) }
+
+ it 'returns group web_url and avatar_url' do
+ get api("/projects/#{project.id}", user)
+
+ expect(response).to have_gitlab_http_status(200)
+
+ group_data = json_response['namespace']
+ expect(group_data['web_url']).to eq(group.web_url)
+ expect(group_data['avatar_url']).to eq(group.avatar_url)
+ end
+ end
+
+ context 'when project belongs to a user namespace' do
+ let(:user) { create(:user) }
+ let(:project) { create(:project, namespace: user.namespace) }
+
+ it 'returns user web_url and avatar_url' do
+ get api("/projects/#{project.id}", user)
+
+ expect(response).to have_gitlab_http_status(200)
+
+ user_data = json_response['namespace']
+ expect(user_data['web_url']).to eq("http://localhost/#{user.username}")
+ expect(user_data['avatar_url']).to eq(user.avatar_url)
+ end
+ end
end
context 'with external authorization' do
diff --git a/spec/requests/api/runner_spec.rb b/spec/requests/api/runner_spec.rb
index 3585a827838..29515709a74 100644
--- a/spec/requests/api/runner_spec.rb
+++ b/spec/requests/api/runner_spec.rb
@@ -168,6 +168,32 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
end
end
+ context 'when access_level is provided for Runner' do
+ context 'when access_level is set to ref_protected' do
+ it 'creates runner' do
+ post api('/runners'), params: {
+ token: registration_token,
+ access_level: 'ref_protected'
+ }
+
+ expect(response).to have_gitlab_http_status 201
+ expect(Ci::Runner.first.ref_protected?).to be true
+ end
+ end
+
+ context 'when access_level is set to not_protected' do
+ it 'creates runner' do
+ post api('/runners'), params: {
+ token: registration_token,
+ access_level: 'not_protected'
+ }
+
+ expect(response).to have_gitlab_http_status 201
+ expect(Ci::Runner.first.ref_protected?).to be false
+ end
+ end
+ end
+
context 'when maximum job timeout is specified' do
it 'creates runner' do
post api('/runners'), params: {
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 60db3e1bc46..8ca4c172707 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -83,6 +83,7 @@ RSpec.configure do |config|
config.include Devise::Test::IntegrationHelpers, type: :feature
config.include LoginHelpers, type: :feature
config.include SearchHelpers, type: :feature
+ config.include WaitHelpers, type: :feature
config.include EmailHelpers, :mailer, type: :mailer
config.include Warden::Test::Helpers, type: :request
config.include Gitlab::Routing, type: :routing
diff --git a/spec/support/helpers/wait_for_requests.rb b/spec/support/helpers/wait_for_requests.rb
index c7f878b7371..45b9faa0fea 100644
--- a/spec/support/helpers/wait_for_requests.rb
+++ b/spec/support/helpers/wait_for_requests.rb
@@ -50,20 +50,6 @@ module WaitForRequests
finished_all_vue_resource_requests?
end
- # Waits until the passed block returns true
- def wait_for(condition_name, max_wait_time: Capybara.default_max_wait_time, polling_interval: 0.01)
- wait_until = Time.now + max_wait_time.seconds
- loop do
- break if yield
-
- if Time.now > wait_until
- raise "Condition not met: #{condition_name}"
- else
- sleep(polling_interval)
- end
- end
- end
-
def finished_all_vue_resource_requests?
Capybara.page.evaluate_script('window.activeVueResources || 0').zero?
end
diff --git a/spec/support/helpers/wait_helpers.rb b/spec/support/helpers/wait_helpers.rb
new file mode 100644
index 00000000000..7e8e25798e8
--- /dev/null
+++ b/spec/support/helpers/wait_helpers.rb
@@ -0,0 +1,20 @@
+module WaitHelpers
+ extend self
+
+ # Waits until the passed block returns true
+ def wait_for(condition_name, max_wait_time: Capybara.default_max_wait_time, polling_interval: 0.01, reload: false)
+ wait_until = Time.now + max_wait_time.seconds
+ loop do
+ result = yield
+ break if result
+
+ page.refresh if reload
+
+ if Time.now > wait_until
+ raise "Condition not met: #{condition_name}"
+ else
+ sleep(polling_interval)
+ end
+ end
+ end
+end
diff --git a/spec/support/shared_examples/models/update_project_statistics_spec.rb b/spec/support/shared_examples/models/update_project_statistics_spec.rb
new file mode 100644
index 00000000000..7a04e940ee5
--- /dev/null
+++ b/spec/support/shared_examples/models/update_project_statistics_spec.rb
@@ -0,0 +1,76 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+shared_examples_for 'UpdateProjectStatistics' do
+ let(:project) { subject.project }
+ let(:stat) { described_class.statistic_name }
+ let(:attribute) { described_class.statistic_attribute }
+
+ def reload_stat
+ project.statistics.reload.send(stat).to_i
+ end
+
+ def read_attribute
+ subject.read_attribute(attribute).to_i
+ end
+
+ it { is_expected.to be_new_record }
+
+ context 'when creating' do
+ it 'updates the project statistics' do
+ delta = read_attribute
+
+ expect { subject.save! }
+ .to change { reload_stat }
+ .by(delta)
+ end
+ end
+
+ context 'when updating' do
+ before do
+ subject.save!
+ end
+
+ it 'updates project statistics' do
+ delta = 42
+
+ expect(ProjectStatistics)
+ .to receive(:increment_statistic)
+ .and_call_original
+
+ subject.write_attribute(attribute, read_attribute + delta)
+ expect { subject.save! }
+ .to change { reload_stat }
+ .by(delta)
+ end
+ end
+
+ context 'when destroying' do
+ before do
+ subject.save!
+ end
+
+ it 'updates the project statistics' do
+ delta = -read_attribute
+
+ expect(ProjectStatistics)
+ .to receive(:increment_statistic)
+ .and_call_original
+
+ expect { subject.destroy }
+ .to change { reload_stat }
+ .by(delta)
+ end
+
+ context 'when it is destroyed from the project level' do
+ it 'does not update the project statistics' do
+ expect(ProjectStatistics)
+ .not_to receive(:increment_statistic)
+
+ project.update(pending_delete: true)
+ project.destroy!
+ end
+ end
+ end
+end
diff --git a/spec/views/shared/_label_row.html.haml.rb b/spec/views/shared/_label_row.html.haml.rb
new file mode 100644
index 00000000000..a58d5efc1e3
--- /dev/null
+++ b/spec/views/shared/_label_row.html.haml.rb
@@ -0,0 +1,32 @@
+require 'spec_helper'
+
+describe 'shared/_label_row.html.haml' do
+ label_types = {
+ 'project label': :label,
+ 'group label': :group_label
+ }
+
+ label_types.each do |label_type, label_factory|
+ let!(:label) { create(label_factory) }
+
+ context "for a #{label_type}" do
+ it 'has a non-linked label title' do
+ render 'shared/label_row', label: label
+
+ expect(rendered).not_to have_css('a', text: label.title)
+ end
+
+ it "has Issues link for #{label_type}" do
+ render 'shared/label_row', label: label
+
+ expect(rendered).to have_css('a', text: 'Issues')
+ end
+
+ it "has Merge request link for #{label_type}" do
+ render 'shared/label_row', label: label
+
+ expect(rendered).to have_css('a', text: 'Merge requests')
+ end
+ end
+ end
+end