Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md97
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--Gemfile5
-rw-r--r--Gemfile.lock15
-rw-r--r--app/assets/javascripts/monitoring/components/charts/area.vue2
-rw-r--r--app/assets/javascripts/monitoring/components/charts/time_series.vue10
-rw-r--r--app/assets/javascripts/monitoring/components/embed.vue6
-rw-r--r--app/assets/javascripts/monitoring/components/panel_type.vue8
-rw-r--r--app/assets/javascripts/projects/tree/components/commit_pipeline_status_component.vue4
-rw-r--r--app/assets/javascripts/test_utils/simulate_drag.js6
-rw-r--r--app/assets/javascripts/visual_review_toolbar/components/comment.js39
-rw-r--r--app/assets/javascripts/visual_review_toolbar/components/comment_mr_note.js31
-rw-r--r--app/assets/javascripts/visual_review_toolbar/components/comment_post.js145
-rw-r--r--app/assets/javascripts/visual_review_toolbar/components/comment_storage.js20
-rw-r--r--app/assets/javascripts/visual_review_toolbar/components/form_elements.js17
-rw-r--r--app/assets/javascripts/visual_review_toolbar/components/index.js23
-rw-r--r--app/assets/javascripts/visual_review_toolbar/components/login.js47
-rw-r--r--app/assets/javascripts/visual_review_toolbar/components/mr_id.js63
-rw-r--r--app/assets/javascripts/visual_review_toolbar/components/note.js35
-rw-r--r--app/assets/javascripts/visual_review_toolbar/components/utils.js51
-rw-r--r--app/assets/javascripts/visual_review_toolbar/components/wrapper.js79
-rw-r--r--app/assets/javascripts/visual_review_toolbar/components/wrapper_icons.js15
-rw-r--r--app/assets/javascripts/visual_review_toolbar/index.js51
-rw-r--r--app/assets/javascripts/visual_review_toolbar/shared/constants.js56
-rw-r--r--app/assets/javascripts/visual_review_toolbar/shared/index.js55
-rw-r--r--app/assets/javascripts/visual_review_toolbar/shared/storage_utils.js42
-rw-r--r--app/assets/javascripts/visual_review_toolbar/store/events.js73
-rw-r--r--app/assets/javascripts/visual_review_toolbar/store/index.js11
-rw-r--r--app/assets/javascripts/visual_review_toolbar/store/state.js95
-rw-r--r--app/assets/javascripts/visual_review_toolbar/store/utils.js15
-rw-r--r--app/assets/javascripts/visual_review_toolbar/styles/toolbar.css188
-rw-r--r--app/assets/stylesheets/framework/variables.scss1
-rw-r--r--app/assets/stylesheets/pages/boards.scss3
-rw-r--r--app/assets/stylesheets/pages/wiki.scss29
-rw-r--r--app/controllers/jwt_controller.rb1
-rw-r--r--app/controllers/projects/pipelines_controller.rb2
-rw-r--r--app/helpers/ci_status_helper.rb3
-rw-r--r--app/helpers/notifications_helper.rb4
-rw-r--r--app/models/analytics/cycle_analytics/project_stage.rb5
-rw-r--r--app/models/concerns/analytics/cycle_analytics/stage.rb68
-rw-r--r--app/models/concerns/issuable.rb19
-rw-r--r--app/models/concerns/sortable.rb6
-rw-r--r--app/models/deployment.rb8
-rw-r--r--app/models/issue.rb9
-rw-r--r--app/serializers/deployment_entity.rb2
-rw-r--r--app/services/self_monitoring/project/create_service.rb219
-rw-r--r--app/views/ci/status/_icon.html.haml3
-rw-r--r--app/views/projects/deployments/_deployment.html.haml4
-rw-r--r--app/views/projects/serverless/functions/index.html.haml2
-rw-r--r--app/views/projects/wikis/_sidebar.html.haml6
-rw-r--r--app/views/projects/wikis/edit.html.haml4
-rw-r--r--app/views/projects/wikis/git_access.html.haml12
-rw-r--r--app/views/projects/wikis/history.html.haml2
-rw-r--r--app/views/projects/wikis/pages.html.haml4
-rw-r--r--app/views/projects/wikis/show.html.haml4
-rw-r--r--app/views/shared/boards/components/_board.html.haml2
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml4
-rw-r--r--app/views/shared/projects/_project.html.haml2
-rw-r--r--app/workers/git_garbage_collect_worker.rb2
-rw-r--r--changelogs/unreleased/55360-redundant-index-in-the-releases-table_v2.yml5
-rw-r--r--changelogs/unreleased/55999-misleading-pipeline-tooltip-messages-and-misleading-ci-status-icons.yml5
-rw-r--r--changelogs/unreleased/56883-migration.yml5
-rw-r--r--changelogs/unreleased/57402-upate-issues-list-sort-options.yml5
-rw-r--r--changelogs/unreleased/62322-add-optional-id-to-label-api-put-delete-pd.yml5
-rw-r--r--changelogs/unreleased/64269-pipeline-api-fails-with-401.yml5
-rw-r--r--changelogs/unreleased/64385-charts-scroll-handle-icon-has-disappeared.yml5
-rw-r--r--changelogs/unreleased/64764-fix-serverless-layout.yml5
-rw-r--r--changelogs/unreleased/66022-git-clone-url-box-on-wiki-git-access-page-is-broken.yml5
-rw-r--r--changelogs/unreleased/66037-deployment-user.yml5
-rw-r--r--changelogs/unreleased/66073-use-time-series-chart-instead-of-area-chart-in-panel_types.yml5
-rw-r--r--changelogs/unreleased/66402-use-visual-review-tools-npm-package.yml5
-rw-r--r--changelogs/unreleased/fe-fix-issuable-sidebar-icon-of-notification-disabled.yml5
-rw-r--r--changelogs/unreleased/labkit-cache-tracing.yml5
-rw-r--r--changelogs/unreleased/security-gitaly-1-61-0.yml5
-rw-r--r--changelogs/unreleased/sh-eliminate-gitaly-nplus-one-notes.yml5
-rw-r--r--changelogs/unreleased/sh-fix-issues-api-gitaly-nplusone.yml5
-rw-r--r--changelogs/unreleased/sh-revert-redis-cache-store.yml5
-rw-r--r--changelogs/unreleased/tr-param-undefined-fix.yml5
-rw-r--r--changelogs/unreleased/winh-deduplicate-board-headers.yml5
-rw-r--r--config/initializers/tracing.rb4
-rw-r--r--config/webpack.config.js7
-rw-r--r--config/webpack.config.review_toolbar.js58
-rw-r--r--db/migrate/20171230123729_init_schema.rb2
-rw-r--r--db/migrate/20180101160629_create_prometheus_metrics.rb2
-rw-r--r--db/migrate/20180122162010_add_auto_devops_domain_to_application_settings.rb2
-rw-r--r--db/migrate/20180129193323_add_uploads_builder_context.rb2
-rw-r--r--db/migrate/20180212030105_add_external_ip_to_clusters_applications_ingress.rb2
-rw-r--r--db/migrate/20180214093516_create_badges.rb2
-rw-r--r--db/migrate/20180214155405_create_clusters_applications_runners.rb2
-rw-r--r--db/migrate/20180216120000_add_pages_domain_verification.rb2
-rw-r--r--db/migrate/20180222043024_add_ip_address_to_runner.rb2
-rw-r--r--db/migrate/20180308125206_add_user_internal_regex_to_application_setting.rb2
-rw-r--r--db/migrate/20180315160435_add_external_auth_mutual_tls_fields_to_project_settings.rb2
-rw-r--r--db/migrate/20180319190020_create_deploy_tokens.rb2
-rw-r--r--db/migrate/20180502122856_create_project_mirror_data.rb2
-rw-r--r--db/migrate/20180503131624_create_remote_mirrors.rb2
-rw-r--r--db/migrate/20180503175053_ensure_missing_columns_to_project_mirror_data.rb4
-rw-r--r--db/migrate/20180511131058_create_clusters_applications_jupyter.rb6
-rw-r--r--db/migrate/20180515121227_create_notes_diff_files.rb2
-rw-r--r--db/migrate/20180529093006_ensure_remote_mirror_columns.rb2
-rw-r--r--db/migrate/20180531185349_add_repository_languages.rb2
-rw-r--r--db/migrate/20180613081317_create_ci_builds_runner_session.rb2
-rw-r--r--db/migrate/20180713092803_create_user_statuses.rb2
-rw-r--r--db/migrate/20180814153625_add_commit_email_to_users.rb2
-rw-r--r--db/migrate/20180831164908_add_identifier_to_prometheus_metric.rb2
-rw-r--r--db/migrate/20180910115836_add_attr_encrypted_columns_to_web_hook.rb2
-rw-r--r--db/migrate/20180910153412_add_token_digest_to_personal_access_tokens.rb2
-rw-r--r--db/migrate/20180912111628_add_knative_application.rb2
-rw-r--r--db/migrate/20181009190428_create_clusters_kubernetes_namespaces.rb2
-rw-r--r--db/migrate/20181019032400_add_shards_table.rb2
-rw-r--r--db/migrate/20181019032408_add_repositories_table.rb2
-rw-r--r--db/migrate/20181025115728_add_private_commit_email_hostname_to_application_settings.rb2
-rw-r--r--db/migrate/20181031190559_drop_gcp_clusters_table.rb2
-rw-r--r--db/migrate/20181101191341_create_clusters_applications_cert_manager.rb2
-rw-r--r--db/migrate/20181115140140_add_encrypted_runners_token_to_settings.rb2
-rw-r--r--db/migrate/20181116050532_knative_external_ip.rb2
-rw-r--r--db/migrate/20181116141415_add_encrypted_runners_token_to_namespaces.rb2
-rw-r--r--db/migrate/20181116141504_add_encrypted_runners_token_to_projects.rb2
-rw-r--r--db/migrate/20181120151656_add_token_encrypted_to_ci_runners.rb2
-rw-r--r--db/migrate/20181122160027_create_project_repositories.rb2
-rw-r--r--db/migrate/20181123144235_create_suggestions.rb2
-rw-r--r--db/migrate/20181128123704_add_state_to_pool_repository.rb2
-rw-r--r--db/migrate/20181129104854_add_token_encrypted_to_ci_builds.rb2
-rw-r--r--db/migrate/20181203002526_add_project_bfg_object_map_column.rb2
-rw-r--r--db/migrate/20181211092510_add_name_author_id_and_sha_to_releases.rb4
-rw-r--r--db/migrate/20181212171634_create_error_tracking_settings.rb2
-rw-r--r--db/migrate/20181228175414_create_releases_link_table.rb2
-rw-r--r--db/migrate/20190109153125_add_merge_request_external_diffs.rb2
-rw-r--r--db/migrate/20190114172110_add_domain_to_cluster.rb2
-rw-r--r--db/migrate/20190115092821_add_columns_project_error_tracking_settings.rb4
-rw-r--r--db/migrate/20190116234221_add_sorting_fields_to_user_preference.rb4
-rw-r--r--db/migrate/20190301182457_add_external_hostname_to_ingress_and_knative.rb4
-rw-r--r--db/migrate/20190320174702_add_lets_encrypt_notification_email_to_application_settings.rb2
-rw-r--r--db/migrate/20190325105715_add_fields_to_user_preferences.rb2
-rw-r--r--db/migrate/20190327163904_add_notification_email_to_notification_settings.rb2
-rw-r--r--db/migrate/20190402150158_backport_enterprise_schema.rb2
-rw-r--r--db/migrate/20190409224933_add_name_to_geo_nodes.rb2
-rw-r--r--db/migrate/20190422082247_create_project_metrics_settings.rb2
-rw-r--r--db/migrate/20190429082448_create_pages_domain_acme_orders.rb2
-rw-r--r--db/migrate/20190430131225_create_issue_tracker_data.rb2
-rw-r--r--db/migrate/20190430142025_create_jira_tracker_data.rb2
-rw-r--r--db/migrate/20190514105711_create_ip_restriction.rb2
-rw-r--r--db/migrate/20190527011309_add_required_template_name_to_application_settings.rb2
-rw-r--r--db/migrate/20190606054742_add_token_encrypted_to_operations_feature_flags_clients.rb2
-rw-r--r--db/migrate/20190613044655_add_username_to_deploy_tokens.rb2
-rw-r--r--db/migrate/20190613073003_create_project_aliases.rb2
-rw-r--r--db/migrate/20190621151636_add_merge_request_rebase_jid.rb2
-rw-r--r--db/migrate/20190624123615_add_grafana_url_to_settings.rb2
-rw-r--r--db/migrate/20190711124721_create_job_variables.rb2
-rw-r--r--db/migrate/20190726101050_rename_allow_local_requests_from_hooks_and_services_application_setting.rb2
-rw-r--r--db/migrate/20190805140353_remove_rendundant_index_from_releases.rb21
-rw-r--r--db/post_migrate/20181013005024_remove_koding_from_application_settings.rb2
-rw-r--r--db/post_migrate/20190404231137_remove_alternate_url_from_geo_nodes.rb2
-rw-r--r--db/post_migrate/20190625184066_remove_sentry_from_application_settings.rb2
-rw-r--r--db/post_migrate/20190801072937_add_gitlab_instance_administration_project.rb16
-rw-r--r--db/post_migrate/20190801114109_cleanup_allow_local_requests_from_hooks_and_services_application_setting_rename.rb2
-rw-r--r--db/post_migrate/20190809072552_set_self_monitoring_project_alerting_token.rb73
-rw-r--r--db/schema.rb1
-rw-r--r--doc/administration/monitoring/prometheus/gitlab_metrics.md143
-rw-r--r--doc/api/dependencies.md16
-rw-r--r--doc/api/issues.md6
-rw-r--r--doc/api/labels.md8
-rw-r--r--doc/development/README.md1
-rw-r--r--doc/development/documentation/feature-change-workflow.md2
-rw-r--r--doc/development/file_storage.md2
-rw-r--r--doc/development/uploads.md271
-rw-r--r--doc/user/admin_area/monitoring/health_check.md82
-rw-r--r--lib/api/helpers/issues_helpers.rb9
-rw-r--r--lib/api/helpers/label_helpers.rb32
-rw-r--r--lib/api/helpers/notes_helpers.rb2
-rw-r--r--lib/api/issues.rb2
-rw-r--r--lib/api/labels.rb8
-rw-r--r--lib/api/notes.rb13
-rw-r--r--lib/api/pipelines.rb3
-rw-r--r--lib/feature/gitaly.rb1
-rw-r--r--lib/gitlab/analytics/cycle_analytics/default_stages.rb98
-rw-r--r--lib/gitlab/analytics/cycle_analytics/stage_events.rb71
-rw-r--r--lib/gitlab/analytics/cycle_analytics/stage_events/code_stage_start.rb23
-rw-r--r--lib/gitlab/analytics/cycle_analytics/stage_events/issue_created.rb23
-rw-r--r--lib/gitlab/analytics/cycle_analytics/stage_events/issue_first_mentioned_in_commit.rb23
-rw-r--r--lib/gitlab/analytics/cycle_analytics/stage_events/issue_stage_end.rb23
-rw-r--r--lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_created.rb23
-rw-r--r--lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_first_deployed_to_production.rb23
-rw-r--r--lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_finished.rb23
-rw-r--r--lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_started.rb23
-rw-r--r--lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_merged.rb23
-rw-r--r--lib/gitlab/analytics/cycle_analytics/stage_events/plan_stage_start.rb23
-rw-r--r--lib/gitlab/analytics/cycle_analytics/stage_events/simple_stage_event.rb13
-rw-r--r--lib/gitlab/analytics/cycle_analytics/stage_events/stage_event.rb28
-rw-r--r--lib/gitlab/database/migration_helpers.rb46
-rw-r--r--lib/gitlab/database_importers/self_monitoring/project/create_service.rb251
-rw-r--r--lib/gitlab/gitaly_client.rb3
-rw-r--r--lib/gitlab/profiler.rb2
-rw-r--r--lib/gitlab/quick_actions/substitution_definition.rb3
-rw-r--r--lib/tasks/gitlab/assets.rake6
-rw-r--r--locale/gitlab.pot59
-rw-r--r--package.json6
-rw-r--r--qa/qa/runtime/api/request.rb4
-rw-r--r--qa/qa/runtime/fixtures.rb13
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb3
-rw-r--r--rubocop/cop/migration/add_limit_to_string_columns.rb59
-rw-r--r--rubocop/rubocop.rb1
-rw-r--r--spec/factories/ci/job_artifacts.rb4
-rw-r--r--spec/features/boards/boards_spec.rb14
-rw-r--r--spec/features/dashboard/projects_spec.rb4
-rw-r--r--spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb2
-rw-r--r--spec/frontend/monitoring/embed/embed_spec.js8
-rw-r--r--spec/helpers/ci_status_helper_spec.rb76
-rw-r--r--spec/javascripts/monitoring/charts/area_spec.js8
-rw-r--r--spec/javascripts/monitoring/panel_type_spec.js7
-rw-r--r--spec/lib/api/helpers/label_helpers_spec.rb33
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event_spec.rb10
-rw-r--r--spec/lib/gitlab/database/migration_helpers_spec.rb114
-rw-r--r--spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb (renamed from spec/services/self_monitoring/project/create_service_spec.rb)123
-rw-r--r--spec/lib/gitlab/gitaly_client_spec.rb10
-rw-r--r--spec/lib/gitlab/legacy_github_import/release_formatter_spec.rb2
-rw-r--r--spec/lib/gitlab/legacy_github_import/user_formatter_spec.rb2
-rw-r--r--spec/lib/gitlab/legacy_github_import/wiki_formatter_spec.rb2
-rw-r--r--spec/lib/gitlab/loop_helpers_spec.rb2
-rw-r--r--spec/lib/gitlab/manifest_import/manifest_spec.rb2
-rw-r--r--spec/lib/gitlab/manifest_import/project_creator_spec.rb2
-rw-r--r--spec/lib/gitlab/markup_helper_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/background_transaction_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/delta_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/instrumentation_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/method_call_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/methods_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/metric_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/prometheus_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/rack_middleware_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/samplers/influx_sampler_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/samplers/unicorn_sampler_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/sidekiq_metrics_exporter_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/subscribers/action_view_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/subscribers/active_record_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/system_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/web_transaction_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics_spec.rb2
-rw-r--r--spec/lib/gitlab/middleware/basic_health_check_spec.rb2
-rw-r--r--spec/lib/gitlab/middleware/multipart_spec.rb2
-rw-r--r--spec/lib/gitlab/middleware/rails_queue_duration_spec.rb2
-rw-r--r--spec/lib/gitlab/middleware/read_only_spec.rb2
-rw-r--r--spec/lib/gitlab/middleware/release_env_spec.rb2
-rw-r--r--spec/lib/gitlab/multi_collection_paginator_spec.rb2
-rw-r--r--spec/lib/gitlab/object_hierarchy_spec.rb2
-rw-r--r--spec/lib/gitlab/octokit/middleware_spec.rb2
-rw-r--r--spec/lib/gitlab/omniauth_initializer_spec.rb2
-rw-r--r--spec/lib/gitlab/optimistic_locking_spec.rb2
-rw-r--r--spec/lib/gitlab/other_markup_spec.rb2
-rw-r--r--spec/lib/gitlab/otp_key_rotator_spec.rb2
-rw-r--r--spec/lib/gitlab/pages_client_spec.rb2
-rw-r--r--spec/lib/gitlab/path_regex_spec.rb2
-rw-r--r--spec/lib/gitlab/performance_bar_spec.rb2
-rw-r--r--spec/lib/gitlab/phabricator_import/importer_spec.rb2
-rw-r--r--spec/lib/gitlab/phabricator_import/user_finder_spec.rb2
-rw-r--r--spec/lib/gitlab/phabricator_import/worker_state_spec.rb2
-rw-r--r--spec/lib/gitlab/plugin_spec.rb2
-rw-r--r--spec/lib/gitlab/polling_interval_spec.rb2
-rw-r--r--spec/lib/gitlab/popen/runner_spec.rb2
-rw-r--r--spec/lib/gitlab/popen_spec.rb2
-rw-r--r--spec/lib/gitlab/profiler_spec.rb2
-rw-r--r--spec/lib/gitlab/project_authorizations_spec.rb2
-rw-r--r--spec/lib/gitlab/project_search_results_spec.rb2
-rw-r--r--spec/lib/gitlab/project_template_spec.rb2
-rw-r--r--spec/lib/gitlab/project_transfer_spec.rb2
-rw-r--r--spec/lib/gitlab/prometheus/additional_metrics_parser_spec.rb2
-rw-r--r--spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb2
-rw-r--r--spec/lib/gitlab/prometheus/queries/additional_metrics_environment_query_spec.rb2
-rw-r--r--spec/lib/gitlab/prometheus/queries/deployment_query_spec.rb2
-rw-r--r--spec/lib/gitlab/prometheus/queries/matched_metric_query_spec.rb2
-rw-r--r--spec/lib/gitlab/prometheus_client_spec.rb2
-rw-r--r--spec/lib/gitlab/query_limiting/active_support_subscriber_spec.rb2
-rw-r--r--spec/lib/gitlab/query_limiting/middleware_spec.rb2
-rw-r--r--spec/lib/gitlab/query_limiting/transaction_spec.rb2
-rw-r--r--spec/lib/gitlab/query_limiting_spec.rb2
-rw-r--r--spec/lib/gitlab/quick_actions/command_definition_spec.rb2
-rw-r--r--spec/lib/gitlab/quick_actions/dsl_spec.rb2
-rw-r--r--spec/lib/gitlab/quick_actions/extractor_spec.rb2
-rw-r--r--spec/lib/gitlab/quick_actions/spend_time_and_date_separator_spec.rb2
-rw-r--r--spec/lib/gitlab/quick_actions/substitution_definition_spec.rb2
-rw-r--r--spec/lib/gitlab/redis/cache_spec.rb2
-rw-r--r--spec/lib/gitlab/redis/queues_spec.rb2
-rw-r--r--spec/lib/gitlab/redis/shared_state_spec.rb2
-rw-r--r--spec/lib/gitlab/redis/wrapper_spec.rb2
-rw-r--r--spec/lib/gitlab/reference_counter_spec.rb2
-rw-r--r--spec/lib/gitlab/regex_spec.rb2
-rw-r--r--spec/lib/gitlab/repo_path_spec.rb2
-rw-r--r--spec/lib/gitlab/repository_cache_adapter_spec.rb2
-rw-r--r--spec/lib/gitlab/repository_cache_spec.rb2
-rw-r--r--spec/lib/gitlab/repository_set_cache_spec.rb2
-rw-r--r--spec/lib/gitlab/request_context_spec.rb2
-rw-r--r--spec/lib/gitlab/request_forgery_protection_spec.rb2
-rw-r--r--spec/lib/gitlab/request_profiler/profile_spec.rb2
-rw-r--r--spec/lib/gitlab/request_profiler_spec.rb2
-rw-r--r--spec/lib/gitlab/route_map_spec.rb2
-rw-r--r--spec/lib/gitlab/routing_spec.rb2
-rw-r--r--spec/lib/gitlab/sanitizers/exif_spec.rb2
-rw-r--r--spec/lib/gitlab/sanitizers/svg_spec.rb2
-rw-r--r--spec/lib/gitlab/search/found_blob_spec.rb3
-rw-r--r--spec/lib/gitlab/search/query_spec.rb2
-rw-r--r--spec/lib/gitlab/search_results_spec.rb2
-rw-r--r--spec/lib/gitlab/sentry_spec.rb2
-rw-r--r--spec/lib/gitlab/serializer/ci/variables_spec.rb2
-rw-r--r--spec/lib/gitlab/serializer/pagination_spec.rb2
-rw-r--r--spec/lib/gitlab/shard_health_cache_spec.rb2
-rw-r--r--spec/lib/gitlab/shell_spec.rb2
-rw-r--r--spec/lib/gitlab/sherlock/collection_spec.rb2
-rw-r--r--spec/lib/gitlab/sherlock/file_sample_spec.rb2
-rw-r--r--spec/lib/gitlab/sherlock/line_profiler_spec.rb2
-rw-r--r--spec/lib/gitlab/sherlock/line_sample_spec.rb2
-rw-r--r--spec/lib/gitlab/sherlock/location_spec.rb2
-rw-r--r--spec/lib/gitlab/sherlock/middleware_spec.rb2
-rw-r--r--spec/lib/gitlab/sherlock/query_spec.rb2
-rw-r--r--spec/lib/gitlab/sherlock/transaction_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_config_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_logging/json_formatter_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/memory_killer_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_signals_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_status_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_versioning/manager_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_versioning_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/command_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/deploy_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/issue_move_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/issue_new_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/issue_search_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/issue_show_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/access_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/issue_move_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/issue_new_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/issue_search_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb2
-rw-r--r--spec/lib/gitlab/snippet_search_results_spec.rb2
-rw-r--r--spec/lib/gitlab/sql/cte_spec.rb2
-rw-r--r--spec/lib/gitlab/sql/glob_spec.rb2
-rw-r--r--spec/lib/gitlab/sql/pattern_spec.rb2
-rw-r--r--spec/lib/gitlab/sql/recursive_cte_spec.rb2
-rw-r--r--spec/lib/gitlab/sql/union_spec.rb2
-rw-r--r--spec/lib/gitlab/ssh_public_key_spec.rb2
-rw-r--r--spec/lib/gitlab/string_placeholder_replacer_spec.rb2
-rw-r--r--spec/lib/gitlab/string_range_marker_spec.rb2
-rw-r--r--spec/lib/gitlab/string_regex_marker_spec.rb2
-rw-r--r--spec/lib/gitlab/tcp_checker_spec.rb2
-rw-r--r--spec/lib/gitlab/template/finders/global_template_finder_spec.rb2
-rw-r--r--spec/lib/gitlab/template/finders/repo_template_finders_spec.rb2
-rw-r--r--spec/lib/gitlab/template/gitignore_template_spec.rb2
-rw-r--r--spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb2
-rw-r--r--spec/lib/gitlab/template/issue_template_spec.rb2
-rw-r--r--spec/lib/gitlab/template/merge_request_template_spec.rb2
-rw-r--r--spec/lib/gitlab/themes_spec.rb2
-rw-r--r--spec/lib/gitlab/tree_summary_spec.rb2
-rw-r--r--spec/lib/gitlab/untrusted_regexp/ruby_syntax_spec.rb2
-rw-r--r--spec/lib/gitlab/untrusted_regexp_spec.rb2
-rw-r--r--spec/lib/gitlab/uploads_transfer_spec.rb2
-rw-r--r--spec/lib/gitlab/url_blocker_spec.rb2
-rw-r--r--spec/lib/gitlab/url_builder_spec.rb2
-rw-r--r--spec/lib/gitlab/url_sanitizer_spec.rb2
-rw-r--r--spec/lib/gitlab/user_access_spec.rb2
-rw-r--r--spec/lib/gitlab/utils/deep_size_spec.rb2
-rw-r--r--spec/lib/gitlab/utils/merge_hash_spec.rb2
-rw-r--r--spec/lib/gitlab/utils/override_spec.rb2
-rw-r--r--spec/lib/gitlab/utils/sanitize_node_link_spec.rb2
-rw-r--r--spec/lib/gitlab/utils/strong_memoize_spec.rb2
-rw-r--r--spec/lib/gitlab/utils_spec.rb2
-rw-r--r--spec/lib/gitlab/verify/job_artifacts_spec.rb2
-rw-r--r--spec/lib/gitlab/verify/lfs_objects_spec.rb2
-rw-r--r--spec/lib/gitlab/verify/uploads_spec.rb2
-rw-r--r--spec/lib/gitlab/version_info_spec.rb2
-rw-r--r--spec/lib/gitlab/view/presenter/base_spec.rb2
-rw-r--r--spec/lib/gitlab/view/presenter/delegated_spec.rb2
-rw-r--r--spec/lib/gitlab/view/presenter/factory_spec.rb2
-rw-r--r--spec/lib/gitlab/view/presenter/simple_spec.rb2
-rw-r--r--spec/lib/gitlab/visibility_level_spec.rb2
-rw-r--r--spec/lib/gitlab/wiki_file_finder_spec.rb2
-rw-r--r--spec/lib/gitlab/workhorse_spec.rb2
-rw-r--r--spec/lib/gitlab_spec.rb2
-rw-r--r--spec/lib/google_api/auth_spec.rb2
-rw-r--r--spec/lib/google_api/cloud_platform/client_spec.rb2
-rw-r--r--spec/lib/json_web_token/rsa_token_spec.rb2
-rw-r--r--spec/lib/json_web_token/token_spec.rb2
-rw-r--r--spec/lib/mattermost/client_spec.rb2
-rw-r--r--spec/lib/mattermost/command_spec.rb2
-rw-r--r--spec/lib/mattermost/session_spec.rb2
-rw-r--r--spec/lib/mattermost/team_spec.rb2
-rw-r--r--spec/lib/microsoft_teams/activity_spec.rb2
-rw-r--r--spec/lib/microsoft_teams/notifier_spec.rb2
-rw-r--r--spec/lib/milestone_array_spec.rb2
-rw-r--r--spec/lib/object_storage/direct_upload_spec.rb2
-rw-r--r--spec/lib/omni_auth/strategies/jwt_spec.rb2
-rw-r--r--spec/lib/rspec_flaky/config_spec.rb2
-rw-r--r--spec/lib/rspec_flaky/example_spec.rb2
-rw-r--r--spec/lib/rspec_flaky/flaky_example_spec.rb2
-rw-r--r--spec/lib/rspec_flaky/flaky_examples_collection_spec.rb2
-rw-r--r--spec/lib/rspec_flaky/listener_spec.rb2
-rw-r--r--spec/lib/rspec_flaky/report_spec.rb2
-rw-r--r--spec/lib/safe_zip/entry_spec.rb2
-rw-r--r--spec/lib/safe_zip/extract_params_spec.rb2
-rw-r--r--spec/lib/safe_zip/extract_spec.rb2
-rw-r--r--spec/lib/serializers/json_spec.rb2
-rw-r--r--spec/lib/system_check/app/git_user_default_ssh_config_check_spec.rb2
-rw-r--r--spec/lib/system_check/base_check_spec.rb2
-rw-r--r--spec/lib/system_check/orphans/namespace_check_spec.rb2
-rw-r--r--spec/lib/system_check/orphans/repository_check_spec.rb2
-rw-r--r--spec/lib/system_check/simple_executor_spec.rb2
-rw-r--r--spec/lib/system_check_spec.rb2
-rw-r--r--spec/lib/uploaded_file_spec.rb2
-rw-r--r--spec/migrations/add_gitlab_instance_administration_project_spec.rb252
-rw-r--r--spec/models/analytics/cycle_analytics/project_stage_spec.rb14
-rw-r--r--spec/models/deployment_spec.rb26
-rw-r--r--spec/requests/api/discussions_spec.rb54
-rw-r--r--spec/requests/api/issues/issues_spec.rb16
-rw-r--r--spec/requests/api/labels_spec.rb336
-rw-r--r--spec/requests/api/notes_spec.rb7
-rw-r--r--spec/requests/api/pipelines_spec.rb11
-rw-r--r--spec/requests/jwt_controller_spec.rb8
-rw-r--r--spec/rubocop/cop/migration/add_limit_to_string_columns_spec.rb268
-rw-r--r--spec/support/helpers/drag_to_helper.rb19
-rw-r--r--spec/support/helpers/stub_configuration.rb4
-rw-r--r--spec/support/shared_examples/cycle_analytics_stage_examples.rb74
-rw-r--r--spec/support/shared_examples/requests/api/discussions.rb54
-rw-r--r--spec/support/shared_examples/requests/api/pipelines/visibility_table_examples.rb235
-rw-r--r--yarn.lock13
430 files changed, 3953 insertions, 1921 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a6c8eccf0b2..8e343c4fd39 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,75 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
+## 12.2.3
+
+### Security (22 changes)
+
+- Ensure only authorised users can create notes on Merge Requests and Issues.
+- Gitaly: ignore git redirects.
+- Add :login_recaptcha_protection_enabled setting to prevent bots from brute-force attacks.
+- Speed up regexp in namespace format by failing fast after reaching maximum namespace depth.
+- Limit the size of issuable description and comments.
+- Send TODOs for comments on commits correctly.
+- Restrict MergeRequests#test_reports to authenticated users with read-access on Builds.
+- Added image proxy to mitigate potential stealing of IP addresses.
+- Filter out old system notes for epics in notes api endpoint response.
+- Avoid exposing unaccessible repo data upon GFM post processing.
+- Fix HTML injection for label description.
+- Make sure HTML text is always escaped when replacing label/milestone references.
+- Prevent DNS rebind on JIRA service integration.
+- Use admin_group authorization in Groups::RunnersController.
+- Prevent disclosure of merge request ID via email.
+- Show cross-referenced MR-id in issues' activities only to authorized users.
+- Enforce max chars and max render time in markdown math.
+- Check permissions before responding in MergeController#pipeline_status.
+- Remove EXIF from users/personal snippet uploads.
+- Fix project import restricted visibility bypass via API.
+- Fix weak session management by clearing password reset tokens after login (username/email) are updated.
+- Fix SSRF via DNS rebinding in Kubernetes Integration.
+
+
+## 12.2.2
+
+### Security (22 changes)
+
+- Ensure only authorised users can create notes on Merge Requests and Issues.
+- Gitaly: ignore git redirects.
+- Add :login_recaptcha_protection_enabled setting to prevent bots from brute-force attacks.
+- Speed up regexp in namespace format by failing fast after reaching maximum namespace depth.
+- Limit the size of issuable description and comments.
+- Send TODOs for comments on commits correctly.
+- Restrict MergeRequests#test_reports to authenticated users with read-access on Builds.
+- Added image proxy to mitigate potential stealing of IP addresses.
+- Filter out old system notes for epics in notes api endpoint response.
+- Avoid exposing unaccessible repo data upon GFM post processing.
+- Fix HTML injection for label description.
+- Make sure HTML text is always escaped when replacing label/milestone references.
+- Prevent DNS rebind on JIRA service integration.
+- Use admin_group authorization in Groups::RunnersController.
+- Prevent disclosure of merge request ID via email.
+- Show cross-referenced MR-id in issues' activities only to authorized users.
+- Enforce max chars and max render time in markdown math.
+- Check permissions before responding in MergeController#pipeline_status.
+- Remove EXIF from users/personal snippet uploads.
+- Fix project import restricted visibility bypass via API.
+- Fix weak session management by clearing password reset tokens after login (username/email) are updated.
+- Fix SSRF via DNS rebinding in Kubernetes Integration.
+
+
+## 12.2.1
+
+### Fixed (3 changes)
+
+- Fix for embedded metrics undefined params. !31975
+- Fix "ERR value is not an integer or out of range" errors. !32126
+- Prevent duplicated trigger action button.
+
+### Performance (1 change)
+
+- Fix Gitaly N+1 calls with listing issues/MRs via API. !31938
+
+
## 12.2.0
### Security (4 changes, 1 of them is from the community)
@@ -578,6 +647,34 @@ entry.
- Removes EE differences for app/views/admin/users/show.html.haml.
+## 12.0.7
+
+### Security (22 changes)
+
+- Ensure only authorised users can create notes on Merge Requests and Issues.
+- Add :login_recaptcha_protection_enabled setting to prevent bots from brute-force attacks.
+- Queries for Upload should be scoped by model.
+- Speed up regexp in namespace format by failing fast after reaching maximum namespace depth.
+- Limit the size of issuable description and comments.
+- Send TODOs for comments on commits correctly.
+- Restrict MergeRequests#test_reports to authenticated users with read-access on Builds.
+- Added image proxy to mitigate potential stealing of IP addresses.
+- Filter out old system notes for epics in notes api endpoint response.
+- Avoid exposing unaccessible repo data upon GFM post processing.
+- Fix HTML injection for label description.
+- Make sure HTML text is always escaped when replacing label/milestone references.
+- Prevent DNS rebind on JIRA service integration.
+- Use admin_group authorization in Groups::RunnersController.
+- Prevent disclosure of merge request ID via email.
+- Show cross-referenced MR-id in issues' activities only to authorized users.
+- Enforce max chars and max render time in markdown math.
+- Check permissions before responding in MergeController#pipeline_status.
+- Remove EXIF from users/personal snippet uploads.
+- Fix project import restricted visibility bypass via API.
+- Fix weak session management by clearing password reset tokens after login (username/email) are updated.
+- Fix SSRF via DNS rebinding in Kubernetes Integration.
+
+
## 12.0.6
- No changes.
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 4d5fde5bd16..91951fd8ad7 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-1.60.0
+1.61.0
diff --git a/Gemfile b/Gemfile
index 116c94bdaf8..751f5169b0c 100644
--- a/Gemfile
+++ b/Gemfile
@@ -283,7 +283,7 @@ gem 'sentry-raven', '~> 2.9'
gem 'premailer-rails', '~> 1.9.7'
# LabKit: Tracing and Correlation
-gem 'gitlab-labkit', '~> 0.4.2'
+gem 'gitlab-labkit', '~> 0.5'
# I18n
gem 'ruby_parser', '~> 3.8', require: false
@@ -399,7 +399,7 @@ gem 'mail_room', '~> 0.9.1'
gem 'email_reply_trimmer', '~> 0.1'
gem 'html2text'
-gem 'ruby-prof', '~> 0.17.0'
+gem 'ruby-prof', '~> 1.0.0'
gem 'rbtrace', '~> 0.4', require: false
gem 'memory_profiler', '~> 0.9', require: false
gem 'benchmark-memory', '~> 0.1', require: false
@@ -438,6 +438,7 @@ gem 'toml-rb', '~> 1.0.0', require: false
gem 'flipper', '~> 0.13.0'
gem 'flipper-active_record', '~> 0.13.0'
gem 'flipper-active_support_cache_store', '~> 0.13.0'
+gem 'unleash', '~> 0.1.5'
# Structured logging
gem 'lograge', '~> 0.5'
diff --git a/Gemfile.lock b/Gemfile.lock
index 0ecf3aa2840..a6a44cc6960 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -311,12 +311,13 @@ GEM
gitaly (1.58.0)
grpc (~> 1.0)
github-markup (1.7.0)
- gitlab-labkit (0.4.2)
+ gitlab-labkit (0.5.2)
actionpack (~> 5)
activesupport (~> 5)
grpc (~> 1.19)
jaeger-client (~> 0.10)
opentracing (~> 0.4)
+ redis (> 3.0.0, < 5.0.0)
gitlab-markup (1.7.0)
gitlab-sidekiq-fetcher (0.5.1)
sidekiq (~> 5)
@@ -534,6 +535,7 @@ GEM
multi_json (1.13.1)
multi_xml (0.6.0)
multipart-post (2.0.0)
+ murmurhash3 (0.1.6)
mustermann (1.0.3)
mustermann-grape (1.0.0)
mustermann (~> 1.0.0)
@@ -712,7 +714,7 @@ GEM
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
- rails-html-sanitizer (1.0.4)
+ rails-html-sanitizer (1.2.0)
loofah (~> 2.2, >= 2.2.2)
rails-i18n (5.1.1)
i18n (>= 0.7, < 2)
@@ -835,7 +837,7 @@ GEM
i18n
ruby-fogbugz (0.2.1)
crack (~> 0.4)
- ruby-prof (0.17.0)
+ ruby-prof (1.0.0)
ruby-progressbar (1.10.1)
ruby-saml (1.7.2)
nokogiri (>= 1.5.10)
@@ -971,6 +973,8 @@ GEM
get_process_mem (~> 0)
unicorn (>= 4, < 6)
uniform_notifier (1.10.0)
+ unleash (0.1.5)
+ murmurhash3 (~> 0.1.6)
unparser (0.4.5)
abstract_type (~> 0.0.7)
adamantium (~> 0.2.0)
@@ -1100,7 +1104,7 @@ DEPENDENCIES
gettext_i18n_rails_js (~> 1.3)
gitaly (~> 1.58.0)
github-markup (~> 1.7.0)
- gitlab-labkit (~> 0.4.2)
+ gitlab-labkit (~> 0.5)
gitlab-markup (~> 1.7.0)
gitlab-sidekiq-fetcher (= 0.5.1)
gitlab-styles (~> 2.7)
@@ -1214,7 +1218,7 @@ DEPENDENCIES
rubocop-performance (~> 1.1.0)
rubocop-rspec (~> 1.22.1)
ruby-fogbugz (~> 0.2.1)
- ruby-prof (~> 0.17.0)
+ ruby-prof (~> 1.0.0)
ruby-progressbar
ruby_parser (~> 3.8)
rubyzip (~> 1.2.2)
@@ -1250,6 +1254,7 @@ DEPENDENCIES
unf (~> 0.1.4)
unicorn (~> 5.4.1)
unicorn-worker-killer (~> 0.4.4)
+ unleash (~> 0.1.5)
validates_hostname (~> 1.0.6)
version_sorter (~> 2.2.4)
vmstat (~> 2.3.0)
diff --git a/app/assets/javascripts/monitoring/components/charts/area.vue b/app/assets/javascripts/monitoring/components/charts/area.vue
index 78d97a3c122..cac10474d06 100644
--- a/app/assets/javascripts/monitoring/components/charts/area.vue
+++ b/app/assets/javascripts/monitoring/components/charts/area.vue
@@ -126,7 +126,7 @@ export default {
},
},
series: this.scatterSeries,
- dataZoom: this.dataZoomConfig,
+ dataZoom: [this.dataZoomConfig],
};
},
dataZoomConfig() {
diff --git a/app/assets/javascripts/monitoring/components/charts/time_series.vue b/app/assets/javascripts/monitoring/components/charts/time_series.vue
index 2fdc75f63ca..02e7a7ba0a6 100644
--- a/app/assets/javascripts/monitoring/components/charts/time_series.vue
+++ b/app/assets/javascripts/monitoring/components/charts/time_series.vue
@@ -48,6 +48,11 @@ export default {
required: false,
default: false,
},
+ singleEmbed: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
thresholds: {
type: Array,
required: false,
@@ -267,7 +272,10 @@ export default {
</script>
<template>
- <div class="prometheus-graph col-12 col-lg-6" :class="[showBorder ? 'p-2' : 'p-0']">
+ <div
+ class="prometheus-graph col-12"
+ :class="[showBorder ? 'p-2' : 'p-0', { 'col-lg-6': !singleEmbed }]"
+ >
<div :class="{ 'prometheus-graph-embed w-100 p-3': showBorder }">
<div class="prometheus-graph-header">
<h5 class="prometheus-graph-title js-graph-title">{{ graphData.title }}</h5>
diff --git a/app/assets/javascripts/monitoring/components/embed.vue b/app/assets/javascripts/monitoring/components/embed.vue
index e3256147618..b516a82c170 100644
--- a/app/assets/javascripts/monitoring/components/embed.vue
+++ b/app/assets/javascripts/monitoring/components/embed.vue
@@ -2,7 +2,7 @@
import { mapActions, mapState } from 'vuex';
import { getParameterValues, removeParams } from '~/lib/utils/url_utility';
import GraphGroup from './graph_group.vue';
-import MonitorAreaChart from './charts/area.vue';
+import MonitorTimeSeriesChart from './charts/time_series.vue';
import { sidebarAnimationDuration } from '../constants';
import { getTimeDiff } from '../utils';
@@ -11,7 +11,7 @@ let sidebarMutationObserver;
export default {
components: {
GraphGroup,
- MonitorAreaChart,
+ MonitorTimeSeriesChart,
},
props: {
dashboardUrl: {
@@ -92,7 +92,7 @@ export default {
<template>
<div class="metrics-embed" :class="{ 'd-inline-flex col-lg-6 p-0': isSingleChart }">
<div v-if="charts.length" class="row w-100 m-n2 pb-4">
- <monitor-area-chart
+ <monitor-time-series-chart
v-for="graphData in charts"
:key="graphData.title"
:graph-data="graphData"
diff --git a/app/assets/javascripts/monitoring/components/panel_type.vue b/app/assets/javascripts/monitoring/components/panel_type.vue
index 96f62bc85ee..73ff651d510 100644
--- a/app/assets/javascripts/monitoring/components/panel_type.vue
+++ b/app/assets/javascripts/monitoring/components/panel_type.vue
@@ -10,14 +10,14 @@ import {
GlTooltipDirective,
} from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
-import MonitorAreaChart from './charts/area.vue';
+import MonitorTimeSeriesChart from './charts/time_series.vue';
import MonitorSingleStatChart from './charts/single_stat.vue';
import MonitorEmptyChart from './charts/empty_chart.vue';
export default {
components: {
- MonitorAreaChart,
MonitorSingleStatChart,
+ MonitorTimeSeriesChart,
MonitorEmptyChart,
Icon,
GlDropdown,
@@ -92,7 +92,7 @@ export default {
v-if="isPanelType('single-stat') && graphDataHasMetrics"
:graph-data="graphData"
/>
- <monitor-area-chart
+ <monitor-time-series-chart
v-else-if="graphDataHasMetrics"
:graph-data="graphData"
:deployment-data="deploymentData"
@@ -136,6 +136,6 @@ export default {
</gl-dropdown-item>
</gl-dropdown>
</div>
- </monitor-area-chart>
+ </monitor-time-series-chart>
<monitor-empty-chart v-else :graph-title="graphData.title" />
</template>
diff --git a/app/assets/javascripts/projects/tree/components/commit_pipeline_status_component.vue b/app/assets/javascripts/projects/tree/components/commit_pipeline_status_component.vue
index 03281aa1317..12ee1ce2f0c 100644
--- a/app/assets/javascripts/projects/tree/components/commit_pipeline_status_component.vue
+++ b/app/assets/javascripts/projects/tree/components/commit_pipeline_status_component.vue
@@ -38,7 +38,9 @@ export default {
},
computed: {
statusTitle() {
- return sprintf(s__('Commits|Commit: %{commitText}'), { commitText: this.ciStatus.text });
+ return sprintf(s__('PipelineStatusTooltip|Pipeline: %{ciStatus}'), {
+ ciStatus: this.ciStatus.text,
+ });
},
},
mounted() {
diff --git a/app/assets/javascripts/test_utils/simulate_drag.js b/app/assets/javascripts/test_utils/simulate_drag.js
index be9ebc81c6b..c9bf234fcce 100644
--- a/app/assets/javascripts/test_utils/simulate_drag.js
+++ b/app/assets/javascripts/test_utils/simulate_drag.js
@@ -153,7 +153,11 @@ export default function simulateDrag(options) {
if (progress >= 1) {
if (options.ondragend) options.ondragend();
- simulateEvent(toEl, 'mouseup');
+
+ if (options.performDrop) {
+ simulateEvent(toEl, 'mouseup');
+ }
+
clearInterval(dragInterval);
window.SIMULATE_DRAG_ACTIVE = 0;
}
diff --git a/app/assets/javascripts/visual_review_toolbar/components/comment.js b/app/assets/javascripts/visual_review_toolbar/components/comment.js
deleted file mode 100644
index a03dc14b319..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/components/comment.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import { nextView } from '../store';
-import { localStorage, COMMENT_BOX, LOGOUT, STORAGE_MR_ID, STORAGE_TOKEN } from '../shared';
-import { clearNote } from './note';
-import { buttonClearStyles } from './utils';
-import { addForm } from './wrapper';
-import { changeSelectedMr, selectedMrNote } from './comment_mr_note';
-import postComment from './comment_post';
-import { saveComment, getSavedComment } from './comment_storage';
-
-const comment = state => {
- const savedComment = getSavedComment();
-
- return `
- <div>
- <textarea id="${COMMENT_BOX}" name="${COMMENT_BOX}" rows="3" placeholder="Enter your feedback or idea" class="gitlab-input" aria-required="true">${savedComment}</textarea>
- ${selectedMrNote(state)}
- <p class="gitlab-metadata-note">Additional metadata will be included: browser, OS, current page, user agent, and viewport dimensions.</p>
- </div>
- <div class="gitlab-button-wrapper">
- <button class="gitlab-button gitlab-button-success" style="${buttonClearStyles}" type="button" id="gitlab-comment-button"> Send feedback </button>
- <button class="gitlab-button gitlab-button-secondary" style="${buttonClearStyles}" type="button" id="${LOGOUT}"> Log out </button>
- </div>
- `;
-};
-
-// This function is here becaause it is called only from the comment view
-// If we reach a design where we can logout from multiple views, promote this
-// to it's own package
-const logoutUser = state => {
- localStorage.removeItem(STORAGE_TOKEN);
- localStorage.removeItem(STORAGE_MR_ID);
- state.token = '';
- state.mergeRequestId = '';
-
- clearNote();
- addForm(nextView(state, COMMENT_BOX));
-};
-
-export { changeSelectedMr, comment, logoutUser, postComment, saveComment };
diff --git a/app/assets/javascripts/visual_review_toolbar/components/comment_mr_note.js b/app/assets/javascripts/visual_review_toolbar/components/comment_mr_note.js
deleted file mode 100644
index da67763261c..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/components/comment_mr_note.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import { nextView } from '../store';
-import { localStorage, CHANGE_MR_ID_BUTTON, COMMENT_BOX, STORAGE_MR_ID } from '../shared';
-import { clearNote } from './note';
-import { buttonClearStyles } from './utils';
-import { addForm } from './wrapper';
-
-const selectedMrNote = state => {
- const { mrUrl, projectPath, mergeRequestId } = state;
-
- const mrLink = `${mrUrl}/${projectPath}/merge_requests/${mergeRequestId}`;
-
- return `
- <p class="gitlab-metadata-note">
- This posts to merge request <a class="gitlab-link" href="${mrLink}">!${mergeRequestId}</a>.
- <button style="${buttonClearStyles}" type="button" id="${CHANGE_MR_ID_BUTTON}" class="gitlab-link gitlab-link-button">Change</button>
- </p>
- `;
-};
-
-const clearMrId = state => {
- localStorage.removeItem(STORAGE_MR_ID);
- state.mergeRequestId = '';
-};
-
-const changeSelectedMr = state => {
- clearMrId(state);
- clearNote();
- addForm(nextView(state, COMMENT_BOX));
-};
-
-export { changeSelectedMr, selectedMrNote };
diff --git a/app/assets/javascripts/visual_review_toolbar/components/comment_post.js b/app/assets/javascripts/visual_review_toolbar/components/comment_post.js
deleted file mode 100644
index ee5f2b62425..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/components/comment_post.js
+++ /dev/null
@@ -1,145 +0,0 @@
-import { BLACK, COMMENT_BOX, MUTED } from '../shared';
-import { clearSavedComment } from './comment_storage';
-import { clearNote, postError } from './note';
-import { selectCommentBox, selectCommentButton, selectNote, selectNoteContainer } from './utils';
-
-const resetCommentButton = () => {
- const commentButton = selectCommentButton();
-
- /* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
- commentButton.innerText = 'Send feedback';
- commentButton.classList.replace('gitlab-button-secondary', 'gitlab-button-success');
- commentButton.style.opacity = 1;
-};
-
-const resetCommentBox = () => {
- const commentBox = selectCommentBox();
- commentBox.style.pointerEvents = 'auto';
- commentBox.style.color = BLACK;
-};
-
-const resetCommentText = () => {
- const commentBox = selectCommentBox();
- commentBox.value = '';
- clearSavedComment();
-};
-
-const resetComment = () => {
- resetCommentButton();
- resetCommentBox();
- resetCommentText();
-};
-
-const confirmAndClear = feedbackInfo => {
- const commentButton = selectCommentButton();
- const currentNote = selectNote();
- const noteContainer = selectNoteContainer();
-
- /* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
- commentButton.innerText = 'Feedback sent';
- noteContainer.style.visibility = 'visible';
- currentNote.insertAdjacentHTML('beforeend', feedbackInfo);
-
- setTimeout(resetComment, 1000);
- setTimeout(clearNote, 6000);
-};
-
-const setInProgressState = () => {
- const commentButton = selectCommentButton();
- const commentBox = selectCommentBox();
-
- /* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
- commentButton.innerText = 'Sending feedback';
- commentButton.classList.replace('gitlab-button-success', 'gitlab-button-secondary');
- commentButton.style.opacity = 0.5;
- commentBox.style.color = MUTED;
- commentBox.style.pointerEvents = 'none';
-};
-
-const commentErrors = error => {
- switch (error.status) {
- case 401:
- /* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
- return 'Unauthorized. You may have entered an incorrect authentication token.';
- case 404:
- /* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
- return 'Not found. You may have entered an incorrect merge request ID.';
- default:
- /* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
- return `Your comment could not be sent. Please try again. Error: ${error.message}`;
- }
-};
-
-const postComment = ({
- platform,
- browser,
- userAgent,
- innerWidth,
- innerHeight,
- projectId,
- projectPath,
- mergeRequestId,
- mrUrl,
- token,
-}) => {
- // Clear any old errors
- clearNote(COMMENT_BOX);
-
- setInProgressState();
-
- const commentText = selectCommentBox().value.trim();
- // Get the href at the last moment to support SPAs
- const { href } = window.location;
-
- if (!commentText) {
- /* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
- postError('Your comment appears to be empty.', COMMENT_BOX);
- resetCommentBox();
- resetCommentButton();
- return;
- }
-
- const detailText = `
- \n
-<details>
- <summary>Metadata</summary>
- Posted from ${href} | ${platform} | ${browser} | ${innerWidth} x ${innerHeight}.
- <br /><br />
- <em>User agent: ${userAgent}</em>
-</details>
- `;
-
- const url = `
- ${mrUrl}/api/v4/projects/${projectId}/merge_requests/${mergeRequestId}/discussions`;
-
- const body = `${commentText} ${detailText}`;
-
- fetch(url, {
- method: 'POST',
- headers: {
- 'PRIVATE-TOKEN': token,
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({ body }),
- })
- .then(response => {
- if (response.ok) {
- return response.json();
- }
-
- throw response;
- })
- .then(data => {
- const commentId = data.notes[0].id;
- const feedbackLink = `${mrUrl}/${projectPath}/merge_requests/${mergeRequestId}#note_${commentId}`;
- const feedbackInfo = `Feedback sent. View at <a class="gitlab-link" href="${feedbackLink}">${projectPath} !${mergeRequestId} (comment ${commentId})</a>`;
- confirmAndClear(feedbackInfo);
- })
- .catch(err => {
- postError(commentErrors(err), COMMENT_BOX);
- resetCommentBox();
- resetCommentButton();
- });
-};
-
-export default postComment;
diff --git a/app/assets/javascripts/visual_review_toolbar/components/comment_storage.js b/app/assets/javascripts/visual_review_toolbar/components/comment_storage.js
deleted file mode 100644
index 49c9400437e..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/components/comment_storage.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import { selectCommentBox } from './utils';
-import { sessionStorage, STORAGE_COMMENT } from '../shared';
-
-const getSavedComment = () => sessionStorage.getItem(STORAGE_COMMENT) || '';
-
-const saveComment = () => {
- const currentComment = selectCommentBox();
-
- // This may be added to any view via top-level beforeunload listener
- // so let's skip if it does not apply
- if (currentComment && currentComment.value) {
- sessionStorage.setItem(STORAGE_COMMENT, currentComment.value);
- }
-};
-
-const clearSavedComment = () => {
- sessionStorage.removeItem(STORAGE_COMMENT);
-};
-
-export { getSavedComment, saveComment, clearSavedComment };
diff --git a/app/assets/javascripts/visual_review_toolbar/components/form_elements.js b/app/assets/javascripts/visual_review_toolbar/components/form_elements.js
deleted file mode 100644
index 608488a6fea..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/components/form_elements.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import { REMEMBER_ITEM } from '../shared';
-import { buttonClearStyles } from './utils';
-
-/* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
-const rememberBox = (rememberText = 'Remember me') => `
- <div class="gitlab-checkbox-wrapper">
- <input type="checkbox" id="${REMEMBER_ITEM}" name="${REMEMBER_ITEM}" value="remember">
- <label for="${REMEMBER_ITEM}" class="gitlab-checkbox-label">${rememberText}</label>
- </div>
-`;
-
-const submitButton = buttonId => `
- <div class="gitlab-button-wrapper">
- <button class="gitlab-button-wide gitlab-button gitlab-button-success" style="${buttonClearStyles}" type="button" id="${buttonId}"> Submit </button>
- </div>
-`;
-export { rememberBox, submitButton };
diff --git a/app/assets/javascripts/visual_review_toolbar/components/index.js b/app/assets/javascripts/visual_review_toolbar/components/index.js
deleted file mode 100644
index e88b3637ad8..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/components/index.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import { changeSelectedMr, comment, logoutUser, postComment, saveComment } from './comment';
-import { authorizeUser, login } from './login';
-import { addMr, mrForm } from './mr_id';
-import { note } from './note';
-import { selectContainer, selectForm } from './utils';
-import { buttonAndForm, toggleForm } from './wrapper';
-
-export {
- addMr,
- authorizeUser,
- buttonAndForm,
- changeSelectedMr,
- comment,
- login,
- logoutUser,
- mrForm,
- note,
- postComment,
- saveComment,
- selectContainer,
- selectForm,
- toggleForm,
-};
diff --git a/app/assets/javascripts/visual_review_toolbar/components/login.js b/app/assets/javascripts/visual_review_toolbar/components/login.js
deleted file mode 100644
index 20ab01bc690..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/components/login.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import { nextView } from '../store';
-import { localStorage, LOGIN, TOKEN_BOX, STORAGE_TOKEN } from '../shared';
-import { clearNote, postError } from './note';
-import { rememberBox, submitButton } from './form_elements';
-import { selectRemember, selectToken } from './utils';
-import { addForm } from './wrapper';
-
-const labelText = `
- Enter your <a class="gitlab-link" href="https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html">personal access token</a>
-`;
-
-const login = `
- <div>
- <label for="${TOKEN_BOX}" class="gitlab-label">${labelText}</label>
- <input class="gitlab-input" type="password" id="${TOKEN_BOX}" name="${TOKEN_BOX}" autocomplete="current-password" aria-required="true">
- </div>
- ${rememberBox()}
- ${submitButton(LOGIN)}
-`;
-
-const storeToken = (token, state) => {
- const rememberMe = selectRemember().checked;
-
- if (rememberMe) {
- localStorage.setItem(STORAGE_TOKEN, token);
- }
-
- state.token = token;
-};
-
-const authorizeUser = state => {
- // Clear any old errors
- clearNote(TOKEN_BOX);
-
- const token = selectToken().value;
-
- if (!token) {
- /* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
- postError('Please enter your token.', TOKEN_BOX);
- return;
- }
-
- storeToken(token, state);
- addForm(nextView(state, LOGIN));
-};
-
-export { authorizeUser, login, storeToken };
diff --git a/app/assets/javascripts/visual_review_toolbar/components/mr_id.js b/app/assets/javascripts/visual_review_toolbar/components/mr_id.js
deleted file mode 100644
index 695b3af8aa0..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/components/mr_id.js
+++ /dev/null
@@ -1,63 +0,0 @@
-import { nextView } from '../store';
-import { MR_ID, MR_ID_BUTTON, STORAGE_MR_ID, localStorage } from '../shared';
-import { clearNote, postError } from './note';
-import { rememberBox, submitButton } from './form_elements';
-import { selectForm, selectMrBox, selectRemember } from './utils';
-import { addForm } from './wrapper';
-
-/* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
-const mrLabel = `Enter your merge request ID`;
-/* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
-const mrRememberText = `Remember this number`;
-
-const mrForm = `
- <div>
- <label for="${MR_ID}" class="gitlab-label">${mrLabel}</label>
- <input class="gitlab-input" type="text" pattern="[1-9][0-9]*" id="${MR_ID}" name="${MR_ID}" placeholder="e.g., 321" aria-required="true">
- </div>
- ${rememberBox(mrRememberText)}
- ${submitButton(MR_ID_BUTTON)}
-`;
-
-const storeMR = (id, state) => {
- const rememberMe = selectRemember().checked;
-
- if (rememberMe) {
- localStorage.setItem(STORAGE_MR_ID, id);
- }
-
- state.mergeRequestId = id;
-};
-
-const getFormError = (mrNumber, form) => {
- if (!mrNumber) {
- /* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
- return 'Please enter your merge request ID number.';
- }
-
- if (!form.checkValidity()) {
- /* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
- return 'Please remove any non-number values from the field.';
- }
-
- return null;
-};
-
-const addMr = state => {
- // Clear any old errors
- clearNote(MR_ID);
-
- const mrNumber = selectMrBox().value;
- const form = selectForm();
- const formError = getFormError(mrNumber, form);
-
- if (formError) {
- postError(formError, MR_ID);
- return;
- }
-
- storeMR(mrNumber, state);
- addForm(nextView(state, MR_ID));
-};
-
-export { addMr, mrForm, storeMR };
diff --git a/app/assets/javascripts/visual_review_toolbar/components/note.js b/app/assets/javascripts/visual_review_toolbar/components/note.js
deleted file mode 100644
index 9cddcb710f2..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/components/note.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import { NOTE, NOTE_CONTAINER, RED } from '../shared';
-import { selectById, selectNote, selectNoteContainer } from './utils';
-
-const note = `
- <div id="${NOTE_CONTAINER}" style="visibility: hidden;">
- <p id="${NOTE}" class="gitlab-message"></p>
- </div>
-`;
-
-const clearNote = inputId => {
- const currentNote = selectNote();
- const noteContainer = selectNoteContainer();
-
- currentNote.innerText = '';
- currentNote.style.color = '';
- noteContainer.style.visibility = 'hidden';
-
- if (inputId) {
- const field = document.getElementById(inputId);
- field.style.borderColor = '';
- }
-};
-
-const postError = (message, inputId) => {
- const currentNote = selectNote();
- const noteContainer = selectNoteContainer();
- const field = selectById(inputId);
- field.style.borderColor = RED;
- currentNote.style.color = RED;
- currentNote.innerText = message;
- noteContainer.style.visibility = 'visible';
- setTimeout(clearNote.bind(null, inputId), 5000);
-};
-
-export { clearNote, note, postError };
diff --git a/app/assets/javascripts/visual_review_toolbar/components/utils.js b/app/assets/javascripts/visual_review_toolbar/components/utils.js
deleted file mode 100644
index 4ec9bd4a32a..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/components/utils.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/* global document */
-
-import {
- COLLAPSE_BUTTON,
- COMMENT_BOX,
- COMMENT_BUTTON,
- FORM,
- FORM_CONTAINER,
- MR_ID,
- NOTE,
- NOTE_CONTAINER,
- REMEMBER_ITEM,
- REVIEW_CONTAINER,
- TOKEN_BOX,
-} from '../shared';
-
-// this style must be applied inline in a handful of components
-/* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
-const buttonClearStyles = `
- -webkit-appearance: none;
-`;
-
-// selector functions to abstract out a little
-const selectById = id => document.getElementById(id);
-const selectCollapseButton = () => document.getElementById(COLLAPSE_BUTTON);
-const selectCommentBox = () => document.getElementById(COMMENT_BOX);
-const selectCommentButton = () => document.getElementById(COMMENT_BUTTON);
-const selectContainer = () => document.getElementById(REVIEW_CONTAINER);
-const selectForm = () => document.getElementById(FORM);
-const selectFormContainer = () => document.getElementById(FORM_CONTAINER);
-const selectMrBox = () => document.getElementById(MR_ID);
-const selectNote = () => document.getElementById(NOTE);
-const selectNoteContainer = () => document.getElementById(NOTE_CONTAINER);
-const selectRemember = () => document.getElementById(REMEMBER_ITEM);
-const selectToken = () => document.getElementById(TOKEN_BOX);
-
-export {
- buttonClearStyles,
- selectById,
- selectCollapseButton,
- selectContainer,
- selectCommentBox,
- selectCommentButton,
- selectForm,
- selectFormContainer,
- selectMrBox,
- selectNote,
- selectNoteContainer,
- selectRemember,
- selectToken,
-};
diff --git a/app/assets/javascripts/visual_review_toolbar/components/wrapper.js b/app/assets/javascripts/visual_review_toolbar/components/wrapper.js
deleted file mode 100644
index fdf8ad7c41f..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/components/wrapper.js
+++ /dev/null
@@ -1,79 +0,0 @@
-import { CLEAR, FORM, FORM_CONTAINER, WHITE } from '../shared';
-import {
- selectCollapseButton,
- selectForm,
- selectFormContainer,
- selectNoteContainer,
-} from './utils';
-import { collapseButton, commentIcon, compressIcon } from './wrapper_icons';
-
-const form = content => `
- <form id="${FORM}" novalidate>
- ${content}
- </form>
-`;
-
-const buttonAndForm = content => `
- <div id="${FORM_CONTAINER}" class="gitlab-form-open">
- ${collapseButton}
- ${form(content)}
- </div>
-`;
-
-const addForm = nextForm => {
- const formWrapper = selectForm();
- formWrapper.innerHTML = nextForm;
-};
-
-function toggleForm() {
- const toggleButton = selectCollapseButton();
- const currentForm = selectForm();
- const formContainer = selectFormContainer();
- const noteContainer = selectNoteContainer();
- const OPEN = 'open';
- const CLOSED = 'closed';
-
- /*
- You may wonder why we spread the arrays before we reverse them.
- In the immortal words of MDN,
- Careful: reverse is destructive. It also changes the original array
- */
-
- const openButtonClasses = ['gitlab-collapse-closed', 'gitlab-collapse-open'];
- const closedButtonClasses = [...openButtonClasses].reverse();
- const openContainerClasses = ['gitlab-wrapper-closed', 'gitlab-wrapper-open'];
- const closedContainerClasses = [...openContainerClasses].reverse();
-
- const stateVals = {
- [OPEN]: {
- buttonClasses: openButtonClasses,
- containerClasses: openContainerClasses,
- icon: compressIcon,
- display: 'flex',
- backgroundColor: WHITE,
- },
- [CLOSED]: {
- buttonClasses: closedButtonClasses,
- containerClasses: closedContainerClasses,
- icon: commentIcon,
- display: 'none',
- backgroundColor: CLEAR,
- },
- };
-
- const nextState = toggleButton.classList.contains('gitlab-collapse-open') ? CLOSED : OPEN;
- const currentVals = stateVals[nextState];
-
- formContainer.classList.replace(...currentVals.containerClasses);
- formContainer.style.backgroundColor = currentVals.backgroundColor;
- formContainer.classList.toggle('gitlab-form-open');
- currentForm.style.display = currentVals.display;
- toggleButton.classList.replace(...currentVals.buttonClasses);
- toggleButton.innerHTML = currentVals.icon;
-
- if (noteContainer && noteContainer.innerText.length > 0) {
- noteContainer.style.display = currentVals.display;
- }
-}
-
-export { addForm, buttonAndForm, toggleForm };
diff --git a/app/assets/javascripts/visual_review_toolbar/components/wrapper_icons.js b/app/assets/javascripts/visual_review_toolbar/components/wrapper_icons.js
deleted file mode 100644
index b686fd4f5c2..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/components/wrapper_icons.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import { buttonClearStyles } from './utils';
-
-const commentIcon = `
- <svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><title>icn/comment</title><path d="M4 11.132l1.446-.964A1 1 0 0 1 6 10h5a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v6.132zM6.303 12l-2.748 1.832A1 1 0 0 1 2 13V5a3 3 0 0 1 3-3h6a3 3 0 0 1 3 3v4a3 3 0 0 1-3 3H6.303z" id="gitlab-comment-icon"/></svg>
-`;
-
-const compressIcon = `
- <svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><title>icn/compress</title><path d="M5.27 12.182l-1.562 1.561a1 1 0 0 1-1.414 0h-.001a1 1 0 0 1 0-1.415l1.56-1.56L2.44 9.353a.5.5 0 0 1 .353-.854H7.09a.5.5 0 0 1 .5.5v4.294a.5.5 0 0 1-.853.353l-1.467-1.465zm6.911-6.914l1.464 1.464a.5.5 0 0 1-.353.854H8.999a.5.5 0 0 1-.5-.5V2.793a.5.5 0 0 1 .854-.354l1.414 1.415 1.56-1.561a1 1 0 1 1 1.415 1.414l-1.561 1.56z" id="gitlab-compress-icon"/></svg>
-`;
-
-const collapseButton = `
- <button id='gitlab-collapse' style='${buttonClearStyles}' class='gitlab-button gitlab-button-secondary gitlab-collapse gitlab-collapse-open'>${compressIcon}</button>
-`;
-
-export { commentIcon, compressIcon, collapseButton };
diff --git a/app/assets/javascripts/visual_review_toolbar/index.js b/app/assets/javascripts/visual_review_toolbar/index.js
deleted file mode 100644
index 67b3fadd772..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/index.js
+++ /dev/null
@@ -1,51 +0,0 @@
-import './styles/toolbar.css';
-
-import { buttonAndForm, note, selectForm, selectContainer } from './components';
-import { REVIEW_CONTAINER } from './shared';
-import { eventLookup, getInitialView, initializeGlobalListeners, initializeState } from './store';
-
-/*
-
- Welcome to the visual review toolbar files. A few useful notes:
-
- - These files build a static script that is served from our webpack
- assets folder. (https://gitlab.com/assets/webpack/visual_review_toolbar.js)
-
- - To compile this file, run `yarn webpack-vrt`.
-
- - Vue is not used in these files because we do not want to ask users to
- install another library at this time. It's all pure vanilla javascript.
-
-*/
-
-window.addEventListener('load', () => {
- initializeState(window, document);
-
- const mainContent = buttonAndForm(getInitialView());
- const container = document.createElement('div');
- container.setAttribute('id', REVIEW_CONTAINER);
- container.insertAdjacentHTML('beforeend', note);
- container.insertAdjacentHTML('beforeend', mainContent);
-
- document.body.insertBefore(container, document.body.firstChild);
-
- selectContainer().addEventListener('click', event => {
- eventLookup(event.target.id)();
- });
-
- selectForm().addEventListener('submit', event => {
- // this is important to prevent the form from adding data
- // as URL params and inadvertently revealing secrets
- event.preventDefault();
-
- const id =
- event.target.querySelector('.gitlab-button-wrapper') &&
- event.target.querySelector('.gitlab-button-wrapper').getElementsByTagName('button')[0] &&
- event.target.querySelector('.gitlab-button-wrapper').getElementsByTagName('button')[0].id;
-
- // even if this is called with false, it's ok; it will get the default no-op
- eventLookup(id)();
- });
-
- initializeGlobalListeners();
-});
diff --git a/app/assets/javascripts/visual_review_toolbar/shared/constants.js b/app/assets/javascripts/visual_review_toolbar/shared/constants.js
deleted file mode 100644
index 0d5b666ab0a..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/shared/constants.js
+++ /dev/null
@@ -1,56 +0,0 @@
-// component selectors
-const CHANGE_MR_ID_BUTTON = 'gitlab-change-mr';
-const COLLAPSE_BUTTON = 'gitlab-collapse';
-const COMMENT_BOX = 'gitlab-comment';
-const COMMENT_BUTTON = 'gitlab-comment-button';
-const FORM = 'gitlab-form';
-const FORM_CONTAINER = 'gitlab-form-wrapper';
-const LOGIN = 'gitlab-login-button';
-const LOGOUT = 'gitlab-logout-button';
-const MR_ID = 'gitlab-submit-mr';
-const MR_ID_BUTTON = 'gitlab-submit-mr-button';
-const NOTE = 'gitlab-validation-note';
-const NOTE_CONTAINER = 'gitlab-note-wrapper';
-const REMEMBER_ITEM = 'gitlab-remember-item';
-const REVIEW_CONTAINER = 'gitlab-review-container';
-const TOKEN_BOX = 'gitlab-token';
-
-// Storage keys
-const STORAGE_PREFIX = '--gitlab'; // Using `--` to make the prefix more unique
-const STORAGE_MR_ID = `${STORAGE_PREFIX}-merge-request-id`;
-const STORAGE_TOKEN = `${STORAGE_PREFIX}-token`;
-const STORAGE_COMMENT = `${STORAGE_PREFIX}-comment`;
-
-// colors — these are applied programmatically
-// rest of styles belong in ./styles
-const BLACK = 'rgba(46, 46, 46, 1)';
-const CLEAR = 'rgba(255, 255, 255, 0)';
-const MUTED = 'rgba(223, 223, 223, 0.5)';
-const RED = 'rgba(219, 59, 33, 1)';
-const WHITE = 'rgba(250, 250, 250, 1)';
-
-export {
- CHANGE_MR_ID_BUTTON,
- COLLAPSE_BUTTON,
- COMMENT_BOX,
- COMMENT_BUTTON,
- FORM,
- FORM_CONTAINER,
- LOGIN,
- LOGOUT,
- MR_ID,
- MR_ID_BUTTON,
- NOTE,
- NOTE_CONTAINER,
- REMEMBER_ITEM,
- REVIEW_CONTAINER,
- TOKEN_BOX,
- STORAGE_MR_ID,
- STORAGE_TOKEN,
- STORAGE_COMMENT,
- BLACK,
- CLEAR,
- MUTED,
- RED,
- WHITE,
-};
diff --git a/app/assets/javascripts/visual_review_toolbar/shared/index.js b/app/assets/javascripts/visual_review_toolbar/shared/index.js
deleted file mode 100644
index d8ccb170592..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/shared/index.js
+++ /dev/null
@@ -1,55 +0,0 @@
-import {
- CHANGE_MR_ID_BUTTON,
- COLLAPSE_BUTTON,
- COMMENT_BOX,
- COMMENT_BUTTON,
- FORM,
- FORM_CONTAINER,
- LOGIN,
- LOGOUT,
- MR_ID,
- MR_ID_BUTTON,
- NOTE,
- NOTE_CONTAINER,
- REMEMBER_ITEM,
- REVIEW_CONTAINER,
- TOKEN_BOX,
- STORAGE_MR_ID,
- STORAGE_TOKEN,
- STORAGE_COMMENT,
- BLACK,
- CLEAR,
- MUTED,
- RED,
- WHITE,
-} from './constants';
-
-import { localStorage, sessionStorage } from './storage_utils';
-
-export {
- localStorage,
- sessionStorage,
- CHANGE_MR_ID_BUTTON,
- COLLAPSE_BUTTON,
- COMMENT_BOX,
- COMMENT_BUTTON,
- FORM,
- FORM_CONTAINER,
- LOGIN,
- LOGOUT,
- MR_ID,
- MR_ID_BUTTON,
- NOTE,
- NOTE_CONTAINER,
- REMEMBER_ITEM,
- REVIEW_CONTAINER,
- TOKEN_BOX,
- STORAGE_MR_ID,
- STORAGE_TOKEN,
- STORAGE_COMMENT,
- BLACK,
- CLEAR,
- MUTED,
- RED,
- WHITE,
-};
diff --git a/app/assets/javascripts/visual_review_toolbar/shared/storage_utils.js b/app/assets/javascripts/visual_review_toolbar/shared/storage_utils.js
deleted file mode 100644
index 00456d3536e..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/shared/storage_utils.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import { setUsingGracefulStorageFlag } from '../store/state';
-
-const TEST_KEY = 'gitlab-storage-test';
-
-const createStorageStub = () => {
- const items = {};
-
- return {
- getItem(key) {
- return items[key];
- },
- setItem(key, value) {
- items[key] = value;
- },
- removeItem(key) {
- delete items[key];
- },
- };
-};
-
-const hasStorageSupport = storage => {
- // Support test taken from https://stackoverflow.com/a/11214467/1708147
- try {
- storage.setItem(TEST_KEY, TEST_KEY);
- storage.removeItem(TEST_KEY);
- setUsingGracefulStorageFlag(true);
-
- return true;
- } catch (err) {
- setUsingGracefulStorageFlag(false);
- return false;
- }
-};
-
-const useGracefulStorage = storage =>
- // If a browser does not support local storage, let's return a graceful implementation.
- hasStorageSupport(storage) ? storage : createStorageStub();
-
-const localStorage = useGracefulStorage(window.localStorage);
-const sessionStorage = useGracefulStorage(window.sessionStorage);
-
-export { localStorage, sessionStorage };
diff --git a/app/assets/javascripts/visual_review_toolbar/store/events.js b/app/assets/javascripts/visual_review_toolbar/store/events.js
deleted file mode 100644
index c9095c77ef1..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/store/events.js
+++ /dev/null
@@ -1,73 +0,0 @@
-import {
- addMr,
- authorizeUser,
- changeSelectedMr,
- logoutUser,
- postComment,
- saveComment,
- toggleForm,
-} from '../components';
-
-import {
- CHANGE_MR_ID_BUTTON,
- COLLAPSE_BUTTON,
- COMMENT_BUTTON,
- LOGIN,
- LOGOUT,
- MR_ID_BUTTON,
-} from '../shared';
-
-import { state } from './state';
-import debounce from './utils';
-
-const noop = () => {};
-
-// State needs to be bound here to be acted on
-// because these are called by click events and
-// as such are called with only the `event` object
-const eventLookup = id => {
- switch (id) {
- case CHANGE_MR_ID_BUTTON:
- return () => {
- saveComment();
- changeSelectedMr(state);
- };
- case COLLAPSE_BUTTON:
- return toggleForm;
- case COMMENT_BUTTON:
- return postComment.bind(null, state);
- case LOGIN:
- return authorizeUser.bind(null, state);
- case LOGOUT:
- return () => {
- saveComment();
- logoutUser(state);
- };
- case MR_ID_BUTTON:
- return addMr.bind(null, state);
- default:
- return noop;
- }
-};
-
-const updateWindowSize = wind => {
- state.innerWidth = wind.innerWidth;
- state.innerHeight = wind.innerHeight;
-};
-
-const initializeGlobalListeners = () => {
- window.addEventListener('resize', debounce(updateWindowSize.bind(null, window), 200));
- window.addEventListener('beforeunload', event => {
- if (state.usingGracefulStorage) {
- // if there is no browser storage support, reloading will lose the comment; this way, the user will be warned
- // we assign the return value because it is required by Chrome see: https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload#Example,
- event.preventDefault();
- /* eslint-disable-next-line no-param-reassign */
- event.returnValue = '';
- }
-
- saveComment();
- });
-};
-
-export { eventLookup, initializeGlobalListeners };
diff --git a/app/assets/javascripts/visual_review_toolbar/store/index.js b/app/assets/javascripts/visual_review_toolbar/store/index.js
deleted file mode 100644
index 07c8dd6f1d2..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/store/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { eventLookup, initializeGlobalListeners } from './events';
-import { nextView, getInitialView, initializeState, setUsingGracefulStorageFlag } from './state';
-
-export {
- eventLookup,
- getInitialView,
- initializeGlobalListeners,
- initializeState,
- nextView,
- setUsingGracefulStorageFlag,
-};
diff --git a/app/assets/javascripts/visual_review_toolbar/store/state.js b/app/assets/javascripts/visual_review_toolbar/store/state.js
deleted file mode 100644
index b7853bb0723..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/store/state.js
+++ /dev/null
@@ -1,95 +0,0 @@
-import { comment, login, mrForm } from '../components';
-import { localStorage, COMMENT_BOX, LOGIN, MR_ID, STORAGE_MR_ID, STORAGE_TOKEN } from '../shared';
-
-const state = {
- browser: '',
- usingGracefulStorage: '',
- innerWidth: '',
- innerHeight: '',
- mergeRequestId: '',
- mrUrl: '',
- platform: '',
- projectId: '',
- userAgent: '',
- token: '',
-};
-
-// adapted from https://developer.mozilla.org/en-US/docs/Web/API/Window/navigator#Example_2_Browser_detect_and_return_an_index
-const getBrowserId = sUsrAg => {
- /* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
- const aKeys = ['MSIE', 'Edge', 'Firefox', 'Safari', 'Chrome', 'Opera'];
- let nIdx = aKeys.length - 1;
-
- for (nIdx; nIdx > -1 && sUsrAg.indexOf(aKeys[nIdx]) === -1; nIdx -= 1);
- return aKeys[nIdx];
-};
-
-const nextView = (appState, form = 'none') => {
- const formsList = {
- [COMMENT_BOX]: currentState => (currentState.token ? mrForm : login),
- [LOGIN]: currentState => (currentState.mergeRequestId ? comment(currentState) : mrForm),
- [MR_ID]: currentState => (currentState.token ? comment(currentState) : login),
- none: currentState => {
- if (!currentState.token) {
- return login;
- }
-
- if (currentState.token && !currentState.mergeRequestId) {
- return mrForm;
- }
-
- return comment(currentState);
- },
- };
-
- return formsList[form](appState);
-};
-
-const initializeState = (wind, doc) => {
- const {
- innerWidth,
- innerHeight,
- navigator: { platform, userAgent },
- } = wind;
-
- const browser = getBrowserId(userAgent);
-
- const scriptEl = doc.getElementById('review-app-toolbar-script');
- const { projectId, mergeRequestId, mrUrl, projectPath } = scriptEl.dataset;
-
- // This mutates our default state object above. It's weird but it makes the linter happy.
- Object.assign(state, {
- browser,
- innerWidth,
- innerHeight,
- mergeRequestId,
- mrUrl,
- platform,
- projectId,
- projectPath,
- userAgent,
- });
-
- return state;
-};
-
-const getInitialView = () => {
- const token = localStorage.getItem(STORAGE_TOKEN);
- const mrId = localStorage.getItem(STORAGE_MR_ID);
-
- if (token) {
- state.token = token;
- }
-
- if (mrId) {
- state.mergeRequestId = mrId;
- }
-
- return nextView(state);
-};
-
-const setUsingGracefulStorageFlag = flag => {
- state.usingGracefulStorage = !flag;
-};
-
-export { initializeState, getInitialView, nextView, setUsingGracefulStorageFlag, state };
diff --git a/app/assets/javascripts/visual_review_toolbar/store/utils.js b/app/assets/javascripts/visual_review_toolbar/store/utils.js
deleted file mode 100644
index 5cf145351b3..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/store/utils.js
+++ /dev/null
@@ -1,15 +0,0 @@
-const debounce = (fn, time) => {
- let current;
-
- const debounced = () => {
- if (current) {
- clearTimeout(current);
- }
-
- current = setTimeout(fn, time);
- };
-
- return debounced;
-};
-
-export default debounce;
diff --git a/app/assets/javascripts/visual_review_toolbar/styles/toolbar.css b/app/assets/javascripts/visual_review_toolbar/styles/toolbar.css
deleted file mode 100644
index d1a8d66ef40..00000000000
--- a/app/assets/javascripts/visual_review_toolbar/styles/toolbar.css
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- As a standalone script, the toolbar has its own css
- */
-
-#gitlab-collapse > * {
- pointer-events: none;
-}
-
-#gitlab-comment {
- background-color: #fafafa;
-}
-
-#gitlab-form {
- display: flex;
- flex-direction: column;
- width: 100%;
- margin-bottom: 0;
-}
-
-#gitlab-note-wrapper {
- display: flex;
- flex-direction: column;
- background-color: #fafafa;
- border-radius: 4px;
- margin-bottom: .5rem;
- padding: 1rem;
-}
-
-#gitlab-form-wrapper {
- overflow: auto;
- display: flex;
- flex-direction: row-reverse;
- border-radius: 4px;
-}
-
-#gitlab-review-container {
- max-width: 22rem;
- max-height: 22rem;
- overflow: auto;
- display: flex;
- flex-direction: column;
- position: fixed;
- bottom: 1rem;
- right: 1rem;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Noto Sans', Ubuntu, Cantarell,
- 'Helvetica Neue', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
- 'Noto Color Emoji';
- font-size: .8rem;
- font-weight: 400;
- color: #2e2e2e;
- z-index: 9999; /* toolbar should always be on top */
-}
-
-.gitlab-wrapper-open {
- max-width: 22rem;
- max-height: 22rem;
-}
-
-.gitlab-wrapper-closed {
- max-width: 3.4rem;
- max-height: 3.4rem;
-}
-
-.gitlab-button {
- cursor: pointer;
- transition: background-color 100ms linear, border-color 100ms linear, color 100ms linear, box-shadow 100ms linear;
-}
-
-.gitlab-button-secondary {
- background: none #fafafa;
- margin: 0 .5rem;
- border: 1px solid #e3e3e3;
-}
-
-.gitlab-button-secondary:hover {
- background-color: #f0f0f0;
- border-color: #e3e3e3;
- color: #2e2e2e;
-}
-
-.gitlab-button-secondary:active {
- color: #2e2e2e;
- background-color: #e1e1e1;
- border-color: #dadada;
-}
-
-.gitlab-button-success:hover {
- color: #fff;
- background-color: #137e3f;
- border-color: #127339;
-}
-
-.gitlab-button-success:active {
- background-color: #168f48;
- border-color: #12753a;
- color: #fff;
-}
-
-.gitlab-button-success {
- background-color: #1aaa55;
- border: 1px solid #168f48;
- color: #fff;
-}
-
-.gitlab-button-wide {
- width: 100%;
-}
-
-.gitlab-button-wrapper {
- margin-top: 0.5rem;
- display: flex;
- align-items: baseline;
- /*
- this makes sure the hit enter to submit picks the correct button
- on the comment view
- */
- flex-direction: row-reverse;
-}
-
-.gitlab-collapse {
- width: 2.4rem;
- height: 2.2rem;
- margin-left: 1rem;
- padding: .5rem;
-}
-
-.gitlab-collapse-closed {
- align-self: center;
-}
-
-.gitlab-checkbox-label {
- padding: 0 .2rem;
-}
-
-.gitlab-checkbox-wrapper {
- display: flex;
- align-items: baseline;
-}
-
-.gitlab-form-open {
- padding: 1rem;
- background-color: #fafafa;
-}
-
-.gitlab-label {
- font-weight: 600;
- display: inline-block;
- width: 100%;
-}
-
-.gitlab-link {
- color: #1b69b6;
- text-decoration: none;
- background-color: transparent;
- background-image: none;
-}
-
-.gitlab-link:hover {
- text-decoration: underline;
-}
-
-.gitlab-link-button {
- border: none;
- cursor: pointer;
- padding: 0 .15rem;
-}
-
-.gitlab-message {
- padding: .25rem 0;
- margin: 0;
- line-height: 1.2rem;
-}
-
-.gitlab-metadata-note {
- font-size: .7rem;
- line-height: 1rem;
- color: #666;
- margin-bottom: .5rem;
-}
-
-.gitlab-input {
- width: 100%;
- border: 1px solid #dfdfdf;
- border-radius: 4px;
- padding: .1rem .2rem;
- min-height: 2rem;
- max-width: 17rem;
-}
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index 92190f8979e..9871771542d 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -469,6 +469,7 @@ $link-active-background: rgba(0, 0, 0, 0.04);
$link-hover-background: rgba(0, 0, 0, 0.06);
$inactive-badge-background: rgba(0, 0, 0, 0.08);
$sidebar-toggle-height: 60px;
+$sidebar-toggle-width: 40px;
$sidebar-milestone-toggle-bottom-margin: 10px;
/*
diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss
index 343cca96851..e77a2d1e333 100644
--- a/app/assets/stylesheets/pages/boards.scss
+++ b/app/assets/stylesheets/pages/boards.scss
@@ -86,6 +86,9 @@
}
.board {
+ // the next line cannot be replaced with .d-inline-block because it breaks display: none of SortableJS
+ // see https://gitlab.com/gitlab-org/gitlab-ce/issues/64828
+ display: inline-block;
width: calc(85vw - 15px);
@include media-breakpoint-up(sm) {
diff --git a/app/assets/stylesheets/pages/wiki.scss b/app/assets/stylesheets/pages/wiki.scss
index 379df1c4db1..0b65b915abf 100644
--- a/app/assets/stylesheets/pages/wiki.scss
+++ b/app/assets/stylesheets/pages/wiki.scss
@@ -32,13 +32,11 @@
color: $gl-text-color-secondary;
}
- .git-access-header {
- padding: $gl-padding 0 $gl-padding-top;
- }
-
.git-clone-holder {
- width: 100%;
- padding-bottom: 40px;
+ .input-group-prepend,
+ .input-group-append {
+ background-color: transparent;
+ }
}
button.sidebar-toggle {
@@ -48,19 +46,8 @@
display: block;
}
- @include media-breakpoint-up(sm) {
- &.has-sidebar-toggle {
- padding-right: 40px;
- }
-
- .git-clone-holder {
- width: 480px;
- padding-bottom: $gl-padding;
- }
-
- .nav-controls {
- width: auto;
- }
+ &.has-sidebar-toggle .git-access-header {
+ padding-right: $sidebar-toggle-width;
}
@include media-breakpoint-up(md) {
@@ -105,10 +92,6 @@
padding: 0 $gl-padding;
}
- .block {
- width: 100%;
- }
-
a {
color: $layout-link-gray;
diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb
index 5ecf4f114cf..da39d64c93d 100644
--- a/app/controllers/jwt_controller.rb
+++ b/app/controllers/jwt_controller.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
class JwtController < ApplicationController
+ skip_around_action :set_session_storage
skip_before_action :authenticate_user!
skip_before_action :verify_authenticity_token
before_action :authenticate_project_or_user
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index e6e3a440925..499d4918899 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -180,7 +180,7 @@ class Projects::PipelinesController < Projects::ApplicationController
else
project
.all_pipelines
- .includes(user: :status)
+ .includes(builds: :tags, user: :status)
.find_by!(id: params[:id])
.present(current_user: current_user)
end
diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb
index f2b5b82b013..144df676304 100644
--- a/app/helpers/ci_status_helper.rb
+++ b/app/helpers/ci_status_helper.rb
@@ -105,14 +105,13 @@ module CiStatusHelper
path = pipelines_project_commit_path(project, commit, ref: ref)
render_status_with_link(
- 'commit',
commit.status(ref),
path,
tooltip_placement: tooltip_placement,
icon_size: 24)
end
- def render_status_with_link(type, status, path = nil, tooltip_placement: 'left', cssclass: '', container: 'body', icon_size: 16)
+ def render_status_with_link(status, path = nil, type: _('pipeline'), tooltip_placement: 'left', cssclass: '', container: 'body', icon_size: 16)
klass = "ci-status-link ci-status-icon-#{status.dasherize} d-inline-flex #{cssclass}"
title = "#{type.titleize}: #{ci_label_for_status(status)}"
data = { toggle: 'tooltip', placement: tooltip_placement, container: container }
diff --git a/app/helpers/notifications_helper.rb b/app/helpers/notifications_helper.rb
index 5678304ffcf..8855e0cdd70 100644
--- a/app/helpers/notifications_helper.rb
+++ b/app/helpers/notifications_helper.rb
@@ -106,9 +106,9 @@ module NotificationsHelper
end
end
- def notification_setting_icon(notification_setting)
+ def notification_setting_icon(notification_setting = nil)
sprite_icon(
- notification_setting.disabled? ? "notifications-off" : "notifications",
+ !notification_setting.present? || notification_setting.disabled? ? "notifications-off" : "notifications",
css_class: "icon notifications-icon js-notifications-icon"
)
end
diff --git a/app/models/analytics/cycle_analytics/project_stage.rb b/app/models/analytics/cycle_analytics/project_stage.rb
index 88c8cb40ccb..a312bd24e78 100644
--- a/app/models/analytics/cycle_analytics/project_stage.rb
+++ b/app/models/analytics/cycle_analytics/project_stage.rb
@@ -3,7 +3,12 @@
module Analytics
module CycleAnalytics
class ProjectStage < ApplicationRecord
+ include Analytics::CycleAnalytics::Stage
+
+ validates :project, presence: true
belongs_to :project
+
+ alias_attribute :parent, :project
end
end
end
diff --git a/app/models/concerns/analytics/cycle_analytics/stage.rb b/app/models/concerns/analytics/cycle_analytics/stage.rb
new file mode 100644
index 00000000000..0c603c2d5e6
--- /dev/null
+++ b/app/models/concerns/analytics/cycle_analytics/stage.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+module Analytics
+ module CycleAnalytics
+ module Stage
+ extend ActiveSupport::Concern
+
+ included do
+ validates :name, presence: true
+ validates :start_event_identifier, presence: true
+ validates :end_event_identifier, presence: true
+ validate :validate_stage_event_pairs
+
+ enum start_event_identifier: Gitlab::Analytics::CycleAnalytics::StageEvents.to_enum, _prefix: :start_event_identifier
+ enum end_event_identifier: Gitlab::Analytics::CycleAnalytics::StageEvents.to_enum, _prefix: :end_event_identifier
+
+ alias_attribute :custom_stage?, :custom
+ end
+
+ def parent=(_)
+ raise NotImplementedError
+ end
+
+ def parent
+ raise NotImplementedError
+ end
+
+ def start_event
+ Gitlab::Analytics::CycleAnalytics::StageEvents[start_event_identifier].new(params_for_start_event)
+ end
+
+ def end_event
+ Gitlab::Analytics::CycleAnalytics::StageEvents[end_event_identifier].new(params_for_end_event)
+ end
+
+ def params_for_start_event
+ {}
+ end
+
+ def params_for_end_event
+ {}
+ end
+
+ def default_stage?
+ !custom
+ end
+
+ # The model that is going to be queried, Issue or MergeRequest
+ def subject_model
+ start_event.object_type
+ end
+
+ private
+
+ def validate_stage_event_pairs
+ return if start_event_identifier.nil? || end_event_identifier.nil?
+
+ unless pairing_rules.fetch(start_event.class, []).include?(end_event.class)
+ errors.add(:end_event, :not_allowed_for_the_given_start_event)
+ end
+ end
+
+ def pairing_rules
+ Gitlab::Analytics::CycleAnalytics::StageEvents.pairing_rules
+ end
+ end
+ end
+end
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index e60b6497cb7..db46d7afbb9 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -186,16 +186,15 @@ module Issuable
def sort_by_attribute(method, excluded_labels: [])
sorted =
case method.to_s
- when 'downvotes_desc' then order_downvotes_desc
- when 'label_priority' then order_labels_priority(excluded_labels: excluded_labels)
- when 'label_priority_desc' then order_labels_priority('DESC', excluded_labels: excluded_labels)
- when 'milestone', 'milestone_due_asc' then order_milestone_due_asc
- when 'milestone_due_desc' then order_milestone_due_desc
- when 'popularity', 'popularity_desc' then order_upvotes_desc
- when 'popularity_asc' then order_upvotes_asc
- when 'priority', 'priority_asc' then order_due_date_and_labels_priority(excluded_labels: excluded_labels)
- when 'priority_desc' then order_due_date_and_labels_priority('DESC', excluded_labels: excluded_labels)
- when 'upvotes_desc' then order_upvotes_desc
+ when 'downvotes_desc' then order_downvotes_desc
+ when 'label_priority', 'label_priority_asc' then order_labels_priority(excluded_labels: excluded_labels)
+ when 'label_priority_desc' then order_labels_priority('DESC', excluded_labels: excluded_labels)
+ when 'milestone', 'milestone_due_asc' then order_milestone_due_asc
+ when 'milestone_due_desc' then order_milestone_due_desc
+ when 'popularity_asc' then order_upvotes_asc
+ when 'popularity', 'popularity_desc', 'upvotes_desc' then order_upvotes_desc
+ when 'priority', 'priority_asc' then order_due_date_and_labels_priority(excluded_labels: excluded_labels)
+ when 'priority_desc' then order_due_date_and_labels_priority('DESC', excluded_labels: excluded_labels)
else order_by(method)
end
diff --git a/app/models/concerns/sortable.rb b/app/models/concerns/sortable.rb
index df1a9e3fe6e..c4af1b1fab2 100644
--- a/app/models/concerns/sortable.rb
+++ b/app/models/concerns/sortable.rb
@@ -27,14 +27,18 @@ module Sortable
def simple_sorts
{
'created_asc' => -> { order_created_asc },
+ 'created_at_asc' => -> { order_created_asc },
'created_date' => -> { order_created_desc },
'created_desc' => -> { order_created_desc },
+ 'created_at_desc' => -> { order_created_desc },
'id_asc' => -> { order_id_asc },
'id_desc' => -> { order_id_desc },
'name_asc' => -> { order_name_asc },
'name_desc' => -> { order_name_desc },
'updated_asc' => -> { order_updated_asc },
- 'updated_desc' => -> { order_updated_desc }
+ 'updated_at_asc' => -> { order_updated_asc },
+ 'updated_desc' => -> { order_updated_desc },
+ 'updated_at_desc' => -> { order_updated_desc }
}
end
diff --git a/app/models/deployment.rb b/app/models/deployment.rb
index 68586e7a1fd..bff5d348ca0 100644
--- a/app/models/deployment.rb
+++ b/app/models/deployment.rb
@@ -162,6 +162,14 @@ class Deployment < ApplicationRecord
deployed_at&.to_time&.in_time_zone&.to_s(:medium)
end
+ def deployed_by
+ # We use deployable's user if available because Ci::PlayBuildService
+ # does not update the deployment's user, just the one for the deployable.
+ # TODO: use deployment's user once https://gitlab.com/gitlab-org/gitlab-ce/issues/66442
+ # is completed.
+ deployable&.user || user
+ end
+
private
def ref_path
diff --git a/app/models/issue.rb b/app/models/issue.rb
index c5a18f0af0f..caea8eadd18 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -128,11 +128,10 @@ class Issue < ApplicationRecord
def self.sort_by_attribute(method, excluded_labels: [])
case method.to_s
- when 'closest_future_date' then order_closest_future_date
- when 'due_date' then order_due_date_asc
- when 'due_date_asc' then order_due_date_asc
- when 'due_date_desc' then order_due_date_desc
- when 'relative_position' then order_relative_position_asc.with_order_id_desc
+ when 'closest_future_date', 'closest_future_date_asc' then order_closest_future_date
+ when 'due_date', 'due_date_asc' then order_due_date_asc
+ when 'due_date_desc' then order_due_date_desc
+ when 'relative_position', 'relative_position_asc' then order_relative_position_asc.with_order_id_desc
else
super
end
diff --git a/app/serializers/deployment_entity.rb b/app/serializers/deployment_entity.rb
index d6466ad1cdd..8b967459173 100644
--- a/app/serializers/deployment_entity.rb
+++ b/app/serializers/deployment_entity.rb
@@ -21,7 +21,7 @@ class DeploymentEntity < Grape::Entity
expose :deployed_at
expose :tag
expose :last?
- expose :user, using: UserEntity
+ expose :deployed_by, as: :user, using: UserEntity
expose :deployable do |deployment, opts|
deployment.deployable.yield_self do |deployable|
diff --git a/app/services/self_monitoring/project/create_service.rb b/app/services/self_monitoring/project/create_service.rb
deleted file mode 100644
index c925c6a1610..00000000000
--- a/app/services/self_monitoring/project/create_service.rb
+++ /dev/null
@@ -1,219 +0,0 @@
-# frozen_string_literal: true
-
-module SelfMonitoring
- module Project
- class CreateService < ::BaseService
- include Stepable
- include Gitlab::Utils::StrongMemoize
-
- VISIBILITY_LEVEL = Gitlab::VisibilityLevel::INTERNAL
- PROJECT_NAME = 'GitLab Instance Administration'
- PROJECT_DESCRIPTION = <<~HEREDOC
- This project is automatically generated and will be used to help monitor this GitLab instance.
- HEREDOC
-
- GROUP_NAME = 'GitLab Instance Administrators'
- GROUP_PATH = 'gitlab-instance-administrators'
-
- steps :validate_admins,
- :create_group,
- :create_project,
- :save_project_id,
- :add_group_members,
- :add_to_whitelist,
- :add_prometheus_manual_configuration
-
- def initialize
- super(nil)
- end
-
- def execute
- execute_steps
- end
-
- private
-
- def validate_admins
- unless instance_admins.any?
- log_error('No active admin user found')
- return error('No active admin user found')
- end
-
- success
- end
-
- def create_group
- if project_created?
- log_info(_('Instance administrators group already exists'))
- @group = application_settings.instance_administration_project.owner
- return success(group: @group)
- end
-
- admin_user = group_owner
- @group = ::Groups::CreateService.new(admin_user, create_group_params).execute
-
- if @group.persisted?
- success(group: @group)
- else
- error('Could not create group')
- end
- end
-
- def create_project
- if project_created?
- log_info(_('Instance administration project already exists'))
- @project = application_settings.instance_administration_project
- return success(project: project)
- end
-
- admin_user = group_owner
- @project = ::Projects::CreateService.new(admin_user, create_project_params).execute
-
- if project.persisted?
- success(project: project)
- else
- log_error(_("Could not create instance administration project. Errors: %{errors}") % { errors: project.errors.full_messages })
- error(_('Could not create project'))
- end
- end
-
- def save_project_id
- return success if project_created?
-
- result = ApplicationSettings::UpdateService.new(
- application_settings,
- group_owner,
- { instance_administration_project_id: @project.id }
- ).execute
-
- if result
- success
- else
- log_error(_("Could not save instance administration project ID, errors: %{errors}") % { errors: application_settings.errors.full_messages })
- error(_('Could not save project ID'))
- end
- end
-
- def add_group_members
- members = @group.add_users(group_maintainers, Gitlab::Access::MAINTAINER)
- errors = members.flat_map { |member| member.errors.full_messages }
-
- if errors.any?
- log_error("Could not add admins as members to self-monitoring project. Errors: #{errors}")
- error('Could not add admins as members')
- else
- success
- end
- end
-
- def add_to_whitelist
- return success unless prometheus_enabled?
- return success unless prometheus_listen_address.present?
-
- uri = parse_url(internal_prometheus_listen_address_uri)
- return error(_('Prometheus listen_address is not a valid URI')) unless uri
-
- result = ApplicationSettings::UpdateService.new(
- application_settings,
- group_owner,
- add_to_outbound_local_requests_whitelist: [uri.normalized_host]
- ).execute
-
- if result
- success
- else
- log_error(_("Could not add prometheus URL to whitelist, errors: %{errors}") % { errors: application_settings.errors.full_messages })
- error(_('Could not add prometheus URL to whitelist'))
- end
- end
-
- def add_prometheus_manual_configuration
- return success unless prometheus_enabled?
- return success unless prometheus_listen_address.present?
-
- service = project.find_or_initialize_service('prometheus')
-
- unless service.update(prometheus_service_attributes)
- log_error("Could not save prometheus manual configuration for self-monitoring project. Errors: #{service.errors.full_messages}")
- return error('Could not save prometheus manual configuration')
- end
-
- success
- end
-
- def application_settings
- strong_memoize(:application_settings) do
- Gitlab::CurrentSettings.expire_current_application_settings
- Gitlab::CurrentSettings.current_application_settings
- end
- end
-
- def project_created?
- application_settings.instance_administration_project.present?
- end
-
- def parse_url(uri_string)
- Addressable::URI.parse(uri_string)
- rescue Addressable::URI::InvalidURIError, TypeError
- end
-
- def prometheus_enabled?
- Gitlab.config.prometheus.enable
- rescue Settingslogic::MissingSetting
- false
- end
-
- def prometheus_listen_address
- Gitlab.config.prometheus.listen_address
- rescue Settingslogic::MissingSetting
- end
-
- def instance_admins
- @instance_admins ||= User.admins.active
- end
-
- def group_owner
- instance_admins.first
- end
-
- def group_maintainers
- # Exclude the first so that the group_owner is not added again as a member.
- instance_admins - [group_owner]
- end
-
- def create_group_params
- {
- name: GROUP_NAME,
- path: "#{GROUP_PATH}-#{SecureRandom.hex(4)}",
- visibility_level: VISIBILITY_LEVEL
- }
- end
-
- def create_project_params
- {
- initialize_with_readme: true,
- visibility_level: VISIBILITY_LEVEL,
- name: PROJECT_NAME,
- description: PROJECT_DESCRIPTION,
- namespace_id: @group.id
- }
- end
-
- def internal_prometheus_listen_address_uri
- if prometheus_listen_address.starts_with?('http')
- prometheus_listen_address
- else
- 'http://' + prometheus_listen_address
- end
- end
-
- def prometheus_service_attributes
- {
- api_url: internal_prometheus_listen_address_uri,
- manual_configuration: true,
- active: true
- }
- end
- end
- end
-end
diff --git a/app/views/ci/status/_icon.html.haml b/app/views/ci/status/_icon.html.haml
index 1249b98221f..fdaacb732c7 100644
--- a/app/views/ci/status/_icon.html.haml
+++ b/app/views/ci/status/_icon.html.haml
@@ -1,13 +1,10 @@
- status = local_assigns.fetch(:status)
- size = local_assigns.fetch(:size, 16)
-- type = local_assigns.fetch(:type, 'pipeline')
- tooltip_placement = local_assigns.fetch(:tooltip_placement, "left")
- path = local_assigns.fetch(:path, status.has_details? ? status.details_path : nil)
- option_css_classes = local_assigns.fetch(:option_css_classes, '')
- css_classes = "ci-status-link ci-status-icon ci-status-icon-#{status.group} has-tooltip #{option_css_classes}"
- title = s_("PipelineStatusTooltip|Pipeline: %{ci_status}") % {ci_status: status.label}
-- if type == 'commit'
- - title = s_("PipelineStatusTooltip|Commit: %{ci_status}") % {ci_status: status.label}
- if path
= link_to path, class: css_classes, title: title, data: { placement: tooltip_placement } do
diff --git a/app/views/projects/deployments/_deployment.html.haml b/app/views/projects/deployments/_deployment.html.haml
index a11e23b6daa..752be02443c 100644
--- a/app/views/projects/deployments/_deployment.html.haml
+++ b/app/views/projects/deployments/_deployment.html.haml
@@ -15,10 +15,10 @@
.flex-truncate-child
= link_to [@project.namespace.becomes(Namespace), @project, deployment.deployable], class: 'build-link' do
#{deployment.deployable.name} (##{deployment.deployable.id})
- - if deployment.user
+ - if deployment.deployed_by
%div
by
- = user_avatar(user: deployment.user, size: 20, css_class: "mr-0 float-none")
+ = user_avatar(user: deployment.deployed_by, size: 20, css_class: "mr-0 float-none")
.table-section.section-15{ role: 'gridcell' }
.table-mobile-header{ role: 'rowheader' }= _("Created")
diff --git a/app/views/projects/serverless/functions/index.html.haml b/app/views/projects/serverless/functions/index.html.haml
index 9c69aedfbfc..bac6c76684b 100644
--- a/app/views/projects/serverless/functions/index.html.haml
+++ b/app/views/projects/serverless/functions/index.html.haml
@@ -14,5 +14,5 @@
.js-serverless-functions-notice
.flash-container
- .top-area.adjust
+ .top-area.adjust.d-flex.justify-content-center
.serverless-functions-table#js-serverless-functions
diff --git a/app/views/projects/wikis/_sidebar.html.haml b/app/views/projects/wikis/_sidebar.html.haml
index a9d21470944..83d145444d8 100644
--- a/app/views/projects/wikis/_sidebar.html.haml
+++ b/app/views/projects/wikis/_sidebar.html.haml
@@ -1,6 +1,6 @@
%aside.right-sidebar.right-sidebar-expanded.wiki-sidebar.js-wiki-sidebar.js-right-sidebar{ data: { "offset-top" => "50", "spy" => "affix" } }
.sidebar-container
- .block.wiki-sidebar-header.append-bottom-default
+ .block.wiki-sidebar-header.append-bottom-default.w-100
%a.gutter-toggle.float-right.d-block.d-sm-block.d-md-none.js-sidebar-wiki-toggle{ href: "#" }
= icon('angle-double-right')
@@ -10,12 +10,12 @@
%span= _("Clone repository")
.blocks-container
- .block.block-first
+ .block.block-first.w-100
- if @sidebar_page
= render_wiki_content(@sidebar_page)
- else
%ul.wiki-pages
= render @sidebar_wiki_entries, context: 'sidebar'
- .block
+ .block.w-100
= link_to project_wikis_pages_path(@project), class: 'btn btn-block' do
= s_("Wiki|More Pages")
diff --git a/app/views/projects/wikis/edit.html.haml b/app/views/projects/wikis/edit.html.haml
index 815b4a51261..9ccf5acfefc 100644
--- a/app/views/projects/wikis/edit.html.haml
+++ b/app/views/projects/wikis/edit.html.haml
@@ -5,7 +5,7 @@
= wiki_page_errors(@error)
-.wiki-page-header.top-area.has-sidebar-toggle
+.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row
%button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" }
= icon('angle-double-left')
@@ -19,7 +19,7 @@
- else
= s_("Wiki|Create New Page")
- .nav-controls
+ .nav-controls.pb-md-3.pb-lg-0
- if @page.persisted?
= link_to project_wiki_history_path(@project, @page), class: "btn" do
= s_("Wiki|Page history")
diff --git a/app/views/projects/wikis/git_access.html.haml b/app/views/projects/wikis/git_access.html.haml
index 009133be117..6972eda9bb7 100644
--- a/app/views/projects/wikis/git_access.html.haml
+++ b/app/views/projects/wikis/git_access.html.haml
@@ -1,15 +1,17 @@
- @content_class = "limit-container-width" unless fluid_layout
- page_title s_("WikiClone|Git Access"), _("Wiki")
-.wiki-page-header.top-area.has-sidebar-toggle
+.wiki-page-header.top-area.has-sidebar-toggle.py-3.flex-column.flex-lg-row
%button.btn.btn-default.d-block.d-sm-block.d-md-none.float-right.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" }
= icon('angle-double-left')
- .git-access-header
- = _("Clone repository")
- %strong= @project_wiki.full_path
+ .git-access-header.w-100.d-flex.flex-column.justify-content-center
+ %span
+ = _("Clone repository")
+ %strong= @project_wiki.full_path
- = render "shared/clone_panel", project: @project_wiki
+ .pt-3.pt-lg-0.w-100
+ = render "shared/clone_panel", project: @project_wiki
.wiki-git-access
%h3= s_("WikiClone|Install Gollum")
diff --git a/app/views/projects/wikis/history.html.haml b/app/views/projects/wikis/history.html.haml
index f8468ef9a78..d3a55c53649 100644
--- a/app/views/projects/wikis/history.html.haml
+++ b/app/views/projects/wikis/history.html.haml
@@ -1,6 +1,6 @@
- page_title _("History"), @page.human_title, _("Wiki")
-.wiki-page-header.top-area.has-sidebar-toggle
+.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row
%button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" }
= icon('angle-double-left')
diff --git a/app/views/projects/wikis/pages.html.haml b/app/views/projects/wikis/pages.html.haml
index f7999c3f1bd..275dc5dbd23 100644
--- a/app/views/projects/wikis/pages.html.haml
+++ b/app/views/projects/wikis/pages.html.haml
@@ -5,13 +5,13 @@
- sort_title = wiki_sort_title(params[:sort])
%div{ class: container_class }
- .wiki-page-header.top-area
+ .wiki-page-header.top-area.flex-column.flex-lg-row
.nav-text.flex-fill
%h2.wiki-page-title
= s_("Wiki|Wiki Pages")
- .nav-controls
+ .nav-controls.pb-md-3.pb-lg-0
= link_to project_wikis_git_access_path(@project), class: 'btn' do
= icon('cloud-download')
= _("Clone repository")
diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml
index 1d649886331..c6197fe576e 100644
--- a/app/views/projects/wikis/show.html.haml
+++ b/app/views/projects/wikis/show.html.haml
@@ -4,7 +4,7 @@
- page_title @page.human_title, _("Wiki")
- add_to_breadcrumbs _("Wiki"), project_wiki_path(@project, :home)
-.wiki-page-header.top-area.has-sidebar-toggle
+.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row
%button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" }
= icon('angle-double-left')
@@ -15,7 +15,7 @@
= (_("Last edited by %{name}") % { name: "<strong>#{@page.last_version.author_name}</strong>" }).html_safe
#{time_ago_with_tooltip(@page.last_version.authored_date)}
- .nav-controls
+ .nav-controls.pb-md-3.pb-lg-0
= render 'main_links'
- if @page.historical?
diff --git a/app/views/shared/boards/components/_board.html.haml b/app/views/shared/boards/components/_board.html.haml
index 5abd4ce0fb9..ffa24d1c041 100644
--- a/app/views/shared/boards/components/_board.html.haml
+++ b/app/views/shared/boards/components/_board.html.haml
@@ -1,4 +1,4 @@
-.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" }',
+.board.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", data: { qa_selector: "board_list" } }
.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) }", data: { qa_selector: "board_list_header" } }
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index aea09bf8d4d..837707707a9 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -139,7 +139,9 @@
- if signed_in
- if issuable_sidebar[:project_emails_disabled]
.block.js-emails-disabled
- = notification_description(:owner_disabled)
+ .sidebar-collapsed-icon.has-tooltip{ title: notification_description(:owner_disabled), data: { placement: "left", container: "body", boundary: 'viewport' } }
+ = notification_setting_icon
+ .hide-collapsed= notification_description(:owner_disabled)
- else
.js-sidebar-subscriptions-entry-point
diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml
index b7474d891dc..573ed36d7f4 100644
--- a/app/views/shared/projects/_project.html.haml
+++ b/app/views/shared/projects/_project.html.haml
@@ -89,7 +89,7 @@
- if pipeline_status && can?(current_user, :read_cross_project) && project.pipeline_status.has_status? && can?(current_user, :read_build, project)
- pipeline_path = pipelines_project_commit_path(project.pipeline_status.project, project.pipeline_status.sha, ref: project.pipeline_status.ref)
%span.icon-wrapper.pipeline-status
- = render 'ci/status/icon', status: project.commit.last_pipeline.detailed_status(current_user), type: 'commit', tooltip_placement: 'top', path: pipeline_path
+ = render 'ci/status/icon', status: project.commit.last_pipeline.detailed_status(current_user), tooltip_placement: 'top', path: pipeline_path
.updated-note
%span
= _('Updated')
diff --git a/app/workers/git_garbage_collect_worker.rb b/app/workers/git_garbage_collect_worker.rb
index 489d6215774..5499e12e49b 100644
--- a/app/workers/git_garbage_collect_worker.rb
+++ b/app/workers/git_garbage_collect_worker.rb
@@ -24,7 +24,7 @@ class GitGarbageCollectWorker
task = task.to_sym
- ::Projects::GitDeduplicationService.new(project).execute
+ ::Projects::GitDeduplicationService.new(project).execute if task == :gc
gitaly_call(task, project.repository.raw_repository)
diff --git a/changelogs/unreleased/55360-redundant-index-in-the-releases-table_v2.yml b/changelogs/unreleased/55360-redundant-index-in-the-releases-table_v2.yml
new file mode 100644
index 00000000000..91a1fb5e6c9
--- /dev/null
+++ b/changelogs/unreleased/55360-redundant-index-in-the-releases-table_v2.yml
@@ -0,0 +1,5 @@
+---
+title: Removed redundant index on releases table
+merge_request: 31487
+author:
+type: removed
diff --git a/changelogs/unreleased/55999-misleading-pipeline-tooltip-messages-and-misleading-ci-status-icons.yml b/changelogs/unreleased/55999-misleading-pipeline-tooltip-messages-and-misleading-ci-status-icons.yml
new file mode 100644
index 00000000000..a937614be38
--- /dev/null
+++ b/changelogs/unreleased/55999-misleading-pipeline-tooltip-messages-and-misleading-ci-status-icons.yml
@@ -0,0 +1,5 @@
+---
+title: Remove "Commit" from pipeline status tooltips
+merge_request: 31861
+author:
+type: fixed
diff --git a/changelogs/unreleased/56883-migration.yml b/changelogs/unreleased/56883-migration.yml
new file mode 100644
index 00000000000..d6eb49e62e1
--- /dev/null
+++ b/changelogs/unreleased/56883-migration.yml
@@ -0,0 +1,5 @@
+---
+title: Create a project for self-monitoring the GitLab instance
+merge_request: 31389
+author:
+type: added
diff --git a/changelogs/unreleased/57402-upate-issues-list-sort-options.yml b/changelogs/unreleased/57402-upate-issues-list-sort-options.yml
new file mode 100644
index 00000000000..900e71e3204
--- /dev/null
+++ b/changelogs/unreleased/57402-upate-issues-list-sort-options.yml
@@ -0,0 +1,5 @@
+---
+title: Updates issues REST API to allow extended sort options
+merge_request: 31849
+author:
+type: changed
diff --git a/changelogs/unreleased/62322-add-optional-id-to-label-api-put-delete-pd.yml b/changelogs/unreleased/62322-add-optional-id-to-label-api-put-delete-pd.yml
new file mode 100644
index 00000000000..7e1eeddef32
--- /dev/null
+++ b/changelogs/unreleased/62322-add-optional-id-to-label-api-put-delete-pd.yml
@@ -0,0 +1,5 @@
+---
+title: Add optional label_id parameter to label API for PUT and DELETE
+merge_request: 31804
+author:
+type: changed
diff --git a/changelogs/unreleased/64269-pipeline-api-fails-with-401.yml b/changelogs/unreleased/64269-pipeline-api-fails-with-401.yml
new file mode 100644
index 00000000000..582339901ae
--- /dev/null
+++ b/changelogs/unreleased/64269-pipeline-api-fails-with-401.yml
@@ -0,0 +1,5 @@
+---
+title: Read pipelines from public projects through API without an access token
+merge_request: 31816
+author:
+type: fixed
diff --git a/changelogs/unreleased/64385-charts-scroll-handle-icon-has-disappeared.yml b/changelogs/unreleased/64385-charts-scroll-handle-icon-has-disappeared.yml
new file mode 100644
index 00000000000..93ed2ff4619
--- /dev/null
+++ b/changelogs/unreleased/64385-charts-scroll-handle-icon-has-disappeared.yml
@@ -0,0 +1,5 @@
+---
+title: fix charts scroll handle icon to use gitlab svg
+merge_request: 31825
+author:
+type: fixed
diff --git a/changelogs/unreleased/64764-fix-serverless-layout.yml b/changelogs/unreleased/64764-fix-serverless-layout.yml
new file mode 100644
index 00000000000..9717062df93
--- /dev/null
+++ b/changelogs/unreleased/64764-fix-serverless-layout.yml
@@ -0,0 +1,5 @@
+---
+title: Fix serverless entry page layout
+merge_request: 32029
+author:
+type: fixed
diff --git a/changelogs/unreleased/66022-git-clone-url-box-on-wiki-git-access-page-is-broken.yml b/changelogs/unreleased/66022-git-clone-url-box-on-wiki-git-access-page-is-broken.yml
new file mode 100644
index 00000000000..931e947f8ed
--- /dev/null
+++ b/changelogs/unreleased/66022-git-clone-url-box-on-wiki-git-access-page-is-broken.yml
@@ -0,0 +1,5 @@
+---
+title: Fix broken git clone box on wiki git access page
+merge_request: 31898
+author:
+type: fixed
diff --git a/changelogs/unreleased/66037-deployment-user.yml b/changelogs/unreleased/66037-deployment-user.yml
new file mode 100644
index 00000000000..8a61b8145af
--- /dev/null
+++ b/changelogs/unreleased/66037-deployment-user.yml
@@ -0,0 +1,5 @@
+---
+title: Return correct user for manual deployments
+merge_request: 32004
+author:
+type: fixed
diff --git a/changelogs/unreleased/66073-use-time-series-chart-instead-of-area-chart-in-panel_types.yml b/changelogs/unreleased/66073-use-time-series-chart-instead-of-area-chart-in-panel_types.yml
new file mode 100644
index 00000000000..8d7af96a7d8
--- /dev/null
+++ b/changelogs/unreleased/66073-use-time-series-chart-instead-of-area-chart-in-panel_types.yml
@@ -0,0 +1,5 @@
+---
+title: Enable line charts in dashbaord panels and embedded charts
+merge_request: 31920
+author:
+type: added
diff --git a/changelogs/unreleased/66402-use-visual-review-tools-npm-package.yml b/changelogs/unreleased/66402-use-visual-review-tools-npm-package.yml
new file mode 100644
index 00000000000..46773e12002
--- /dev/null
+++ b/changelogs/unreleased/66402-use-visual-review-tools-npm-package.yml
@@ -0,0 +1,5 @@
+---
+title: Move visual review toolbar code to NPM
+merge_request: 32159
+author:
+type: fixed
diff --git a/changelogs/unreleased/fe-fix-issuable-sidebar-icon-of-notification-disabled.yml b/changelogs/unreleased/fe-fix-issuable-sidebar-icon-of-notification-disabled.yml
new file mode 100644
index 00000000000..736e12ff694
--- /dev/null
+++ b/changelogs/unreleased/fe-fix-issuable-sidebar-icon-of-notification-disabled.yml
@@ -0,0 +1,5 @@
+---
+title: Fix issuable sidebar icon on notification disabled
+merge_request: 32134
+author:
+type: fixed
diff --git a/changelogs/unreleased/labkit-cache-tracing.yml b/changelogs/unreleased/labkit-cache-tracing.yml
new file mode 100644
index 00000000000..7e58e1b88dd
--- /dev/null
+++ b/changelogs/unreleased/labkit-cache-tracing.yml
@@ -0,0 +1,5 @@
+---
+title: Add Redis interceptor tracing
+merge_request: 30238
+author:
+type: other
diff --git a/changelogs/unreleased/security-gitaly-1-61-0.yml b/changelogs/unreleased/security-gitaly-1-61-0.yml
new file mode 100644
index 00000000000..cbcd5f545a0
--- /dev/null
+++ b/changelogs/unreleased/security-gitaly-1-61-0.yml
@@ -0,0 +1,5 @@
+---
+title: "Gitaly: ignore git redirects"
+merge_request:
+author:
+type: security
diff --git a/changelogs/unreleased/sh-eliminate-gitaly-nplus-one-notes.yml b/changelogs/unreleased/sh-eliminate-gitaly-nplus-one-notes.yml
new file mode 100644
index 00000000000..00523f53dd7
--- /dev/null
+++ b/changelogs/unreleased/sh-eliminate-gitaly-nplus-one-notes.yml
@@ -0,0 +1,5 @@
+---
+title: Eliminate Gitaly N+1 queries with notes API
+merge_request: 32089
+author:
+type: performance
diff --git a/changelogs/unreleased/sh-fix-issues-api-gitaly-nplusone.yml b/changelogs/unreleased/sh-fix-issues-api-gitaly-nplusone.yml
deleted file mode 100644
index 3177cb8d18c..00000000000
--- a/changelogs/unreleased/sh-fix-issues-api-gitaly-nplusone.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix Gitaly N+1 calls with listing issues/MRs via API
-merge_request: 31938
-author:
-type: performance
diff --git a/changelogs/unreleased/sh-revert-redis-cache-store.yml b/changelogs/unreleased/sh-revert-redis-cache-store.yml
deleted file mode 100644
index 710b6e7941d..00000000000
--- a/changelogs/unreleased/sh-revert-redis-cache-store.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix "ERR value is not an integer or out of range" errors
-merge_request: 32126
-author:
-type: fixed
diff --git a/changelogs/unreleased/tr-param-undefined-fix.yml b/changelogs/unreleased/tr-param-undefined-fix.yml
deleted file mode 100644
index 0a9051485bd..00000000000
--- a/changelogs/unreleased/tr-param-undefined-fix.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix for embedded metrics undefined params
-merge_request: 31975
-author:
-type: fixed
diff --git a/changelogs/unreleased/winh-deduplicate-board-headers.yml b/changelogs/unreleased/winh-deduplicate-board-headers.yml
new file mode 100644
index 00000000000..009ce59b6bc
--- /dev/null
+++ b/changelogs/unreleased/winh-deduplicate-board-headers.yml
@@ -0,0 +1,5 @@
+---
+title: Hide duplicate board list while dragging
+merge_request: 32099
+author:
+type: fixed
diff --git a/config/initializers/tracing.rb b/config/initializers/tracing.rb
index 3c8779f238f..5b55a06692e 100644
--- a/config/initializers/tracing.rb
+++ b/config/initializers/tracing.rb
@@ -21,9 +21,13 @@ if Labkit::Tracing.enabled?
end
end
+ # Instrument Redis
+ Labkit::Tracing::Redis.instrument
+
# Instrument Rails
Labkit::Tracing::Rails::ActiveRecordSubscriber.instrument
Labkit::Tracing::Rails::ActionViewSubscriber.instrument
+ Labkit::Tracing::Rails::ActiveSupportSubscriber.instrument
# In multi-processed clustered architectures (puma, unicorn) don't
# start tracing until the worker processes are spawned. This works
diff --git a/config/webpack.config.js b/config/webpack.config.js
index 442b4b4c21e..969a84e85dd 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -298,6 +298,13 @@ module.exports = {
from: path.join(ROOT_PATH, 'node_modules/pdfjs-dist/cmaps/'),
to: path.join(ROOT_PATH, 'public/assets/webpack/cmaps/'),
},
+ {
+ from: path.join(
+ ROOT_PATH,
+ 'node_modules/@gitlab/visual-review-tools/dist/visual_review_toolbar.js',
+ ),
+ to: path.join(ROOT_PATH, 'public/assets/webpack'),
+ },
]),
// compression can require a lot of compute time and is disabled in CI
diff --git a/config/webpack.config.review_toolbar.js b/config/webpack.config.review_toolbar.js
deleted file mode 100644
index baaba7ed387..00000000000
--- a/config/webpack.config.review_toolbar.js
+++ /dev/null
@@ -1,58 +0,0 @@
-const path = require('path');
-const CompressionPlugin = require('compression-webpack-plugin');
-
-const ROOT_PATH = path.resolve(__dirname, '..');
-const CACHE_PATH = process.env.WEBPACK_CACHE_PATH || path.join(ROOT_PATH, 'tmp/cache');
-const NO_SOURCEMAPS = process.env.NO_SOURCEMAPS;
-const IS_PRODUCTION = process.env.NODE_ENV === 'production';
-
-const devtool = IS_PRODUCTION ? 'source-map' : 'cheap-module-eval-source-map';
-
-const alias = {
- vendor: path.join(ROOT_PATH, 'vendor/assets/javascripts'),
- spec: path.join(ROOT_PATH, 'spec/javascripts'),
-};
-
-module.exports = {
- mode: IS_PRODUCTION ? 'production' : 'development',
-
- context: path.join(ROOT_PATH, 'app/assets/javascripts'),
-
- name: 'visual_review_toolbar',
-
- entry: './visual_review_toolbar',
-
- output: {
- path: path.join(ROOT_PATH, 'public/assets/webpack'),
- filename: 'visual_review_toolbar.js',
- library: 'VisualReviewToolbar',
- libraryTarget: 'var',
- },
-
- resolve: {
- alias,
- },
-
- module: {
- rules: [
- {
- test: /\.js$/,
- loader: 'babel-loader',
- options: {
- cacheDirectory: path.join(CACHE_PATH, 'babel-loader'),
- },
- },
- {
- test: /\.css$/,
- use: ['style-loader', 'css-loader'],
- },
- ],
- },
-
- plugins: [
- // compression can require a lot of compute time and is disabled in CI
- new CompressionPlugin(),
- ].filter(Boolean),
-
- devtool: NO_SOURCEMAPS ? false : devtool,
-};
diff --git a/db/migrate/20171230123729_init_schema.rb b/db/migrate/20171230123729_init_schema.rb
index fa90b37954f..a474ea2f925 100644
--- a/db/migrate/20171230123729_init_schema.rb
+++ b/db/migrate/20171230123729_init_schema.rb
@@ -5,6 +5,7 @@
# rubocop:disable Metrics/AbcSize
# rubocop:disable Migration/AddConcurrentForeignKey
# rubocop:disable Style/WordArray
+# rubocop:disable Migration/AddLimitToStringColumns
class InitSchema < ActiveRecord::Migration[4.2]
DOWNTIME = false
@@ -1852,3 +1853,4 @@ class InitSchema < ActiveRecord::Migration[4.2]
raise ActiveRecord::IrreversibleMigration, "The initial migration is not revertable"
end
end
+# rubocop:enable Migration/AddLimitToStringColumns
diff --git a/db/migrate/20180101160629_create_prometheus_metrics.rb b/db/migrate/20180101160629_create_prometheus_metrics.rb
index e3b1ed710d6..a098b999a0a 100644
--- a/db/migrate/20180101160629_create_prometheus_metrics.rb
+++ b/db/migrate/20180101160629_create_prometheus_metrics.rb
@@ -4,6 +4,7 @@ class CreatePrometheusMetrics < ActiveRecord::Migration[4.2]
DOWNTIME = false
def change
+ # rubocop:disable Migration/AddLimitToStringColumns
create_table :prometheus_metrics do |t|
t.references :project, index: true, foreign_key: { on_delete: :cascade }, null: false
t.string :title, null: false
@@ -14,5 +15,6 @@ class CreatePrometheusMetrics < ActiveRecord::Migration[4.2]
t.integer :group, null: false, index: true
t.timestamps_with_timezone null: false
end
+ # rubocop:enable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20180122162010_add_auto_devops_domain_to_application_settings.rb b/db/migrate/20180122162010_add_auto_devops_domain_to_application_settings.rb
index c76dc5b3a68..eb446ad0d72 100644
--- a/db/migrate/20180122162010_add_auto_devops_domain_to_application_settings.rb
+++ b/db/migrate/20180122162010_add_auto_devops_domain_to_application_settings.rb
@@ -8,6 +8,6 @@ class AddAutoDevopsDomainToApplicationSettings < ActiveRecord::Migration[4.2]
DOWNTIME = false
def change
- add_column :application_settings, :auto_devops_domain, :string
+ add_column :application_settings, :auto_devops_domain, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20180129193323_add_uploads_builder_context.rb b/db/migrate/20180129193323_add_uploads_builder_context.rb
index c7227bf0f1e..710fa7b3ba8 100644
--- a/db/migrate/20180129193323_add_uploads_builder_context.rb
+++ b/db/migrate/20180129193323_add_uploads_builder_context.rb
@@ -8,7 +8,9 @@ class AddUploadsBuilderContext < ActiveRecord::Migration[4.2]
DOWNTIME = false
def change
+ # rubocop:disable Migration/AddLimitToStringColumns
add_column :uploads, :mount_point, :string
add_column :uploads, :secret, :string
+ # rubocop:enable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20180212030105_add_external_ip_to_clusters_applications_ingress.rb b/db/migrate/20180212030105_add_external_ip_to_clusters_applications_ingress.rb
index e2a9a68b1ad..78aa2014601 100644
--- a/db/migrate/20180212030105_add_external_ip_to_clusters_applications_ingress.rb
+++ b/db/migrate/20180212030105_add_external_ip_to_clusters_applications_ingress.rb
@@ -4,6 +4,6 @@ class AddExternalIpToClustersApplicationsIngress < ActiveRecord::Migration[4.2]
DOWNTIME = false
def change
- add_column :clusters_applications_ingress, :external_ip, :string
+ add_column :clusters_applications_ingress, :external_ip, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20180214093516_create_badges.rb b/db/migrate/20180214093516_create_badges.rb
index 66e017b115a..fe27d465571 100644
--- a/db/migrate/20180214093516_create_badges.rb
+++ b/db/migrate/20180214093516_create_badges.rb
@@ -2,6 +2,7 @@ class CreateBadges < ActiveRecord::Migration[4.2]
DOWNTIME = false
def change
+ # rubocop:disable Migration/AddLimitToStringColumns
create_table :badges do |t|
t.string :link_url, null: false
t.string :image_url, null: false
@@ -11,6 +12,7 @@ class CreateBadges < ActiveRecord::Migration[4.2]
t.timestamps_with_timezone null: false
end
+ # rubocop:enable Migration/AddLimitToStringColumns
# rubocop:disable Migration/AddConcurrentForeignKey
add_foreign_key :badges, :namespaces, column: :group_id, on_delete: :cascade
diff --git a/db/migrate/20180214155405_create_clusters_applications_runners.rb b/db/migrate/20180214155405_create_clusters_applications_runners.rb
index ce594c91890..f611fefbb0d 100644
--- a/db/migrate/20180214155405_create_clusters_applications_runners.rb
+++ b/db/migrate/20180214155405_create_clusters_applications_runners.rb
@@ -13,7 +13,7 @@ class CreateClustersApplicationsRunners < ActiveRecord::Migration[4.2]
t.index :cluster_id, unique: true
t.integer :status, null: false
t.timestamps_with_timezone null: false
- t.string :version, null: false
+ t.string :version, null: false # rubocop:disable Migration/AddLimitToStringColumns
t.text :status_reason
end
diff --git a/db/migrate/20180216120000_add_pages_domain_verification.rb b/db/migrate/20180216120000_add_pages_domain_verification.rb
index f709f5a5809..b2f19f2e1a9 100644
--- a/db/migrate/20180216120000_add_pages_domain_verification.rb
+++ b/db/migrate/20180216120000_add_pages_domain_verification.rb
@@ -3,6 +3,6 @@ class AddPagesDomainVerification < ActiveRecord::Migration[4.2]
def change
add_column :pages_domains, :verified_at, :datetime_with_timezone
- add_column :pages_domains, :verification_code, :string
+ add_column :pages_domains, :verification_code, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20180222043024_add_ip_address_to_runner.rb b/db/migrate/20180222043024_add_ip_address_to_runner.rb
index b52366c0be1..08fb0bd900c 100644
--- a/db/migrate/20180222043024_add_ip_address_to_runner.rb
+++ b/db/migrate/20180222043024_add_ip_address_to_runner.rb
@@ -4,6 +4,6 @@ class AddIpAddressToRunner < ActiveRecord::Migration[4.2]
DOWNTIME = false
def change
- add_column :ci_runners, :ip_address, :string
+ add_column :ci_runners, :ip_address, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20180308125206_add_user_internal_regex_to_application_setting.rb b/db/migrate/20180308125206_add_user_internal_regex_to_application_setting.rb
index 5e4bf96f86f..9bdd44baf58 100644
--- a/db/migrate/20180308125206_add_user_internal_regex_to_application_setting.rb
+++ b/db/migrate/20180308125206_add_user_internal_regex_to_application_setting.rb
@@ -4,7 +4,7 @@ class AddUserInternalRegexToApplicationSetting < ActiveRecord::Migration[4.2]
DOWNTIME = false
def up
- add_column :application_settings, :user_default_internal_regex, :string, null: true
+ add_column :application_settings, :user_default_internal_regex, :string, null: true # rubocop:disable Migration/AddLimitToStringColumns
end
def down
diff --git a/db/migrate/20180315160435_add_external_auth_mutual_tls_fields_to_project_settings.rb b/db/migrate/20180315160435_add_external_auth_mutual_tls_fields_to_project_settings.rb
index ee3d1078f5e..c379d207ff0 100644
--- a/db/migrate/20180315160435_add_external_auth_mutual_tls_fields_to_project_settings.rb
+++ b/db/migrate/20180315160435_add_external_auth_mutual_tls_fields_to_project_settings.rb
@@ -2,6 +2,7 @@ class AddExternalAuthMutualTlsFieldsToProjectSettings < ActiveRecord::Migration[
DOWNTIME = false
def change
+ # rubocop:disable Migration/AddLimitToStringColumns
add_column :application_settings,
:external_auth_client_cert, :text
add_column :application_settings,
@@ -12,5 +13,6 @@ class AddExternalAuthMutualTlsFieldsToProjectSettings < ActiveRecord::Migration[
:encrypted_external_auth_client_key_pass, :string
add_column :application_settings,
:encrypted_external_auth_client_key_pass_iv, :string
+ # rubocop:enable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20180319190020_create_deploy_tokens.rb b/db/migrate/20180319190020_create_deploy_tokens.rb
index a4d797679c5..f444521b3ae 100644
--- a/db/migrate/20180319190020_create_deploy_tokens.rb
+++ b/db/migrate/20180319190020_create_deploy_tokens.rb
@@ -2,6 +2,7 @@ class CreateDeployTokens < ActiveRecord::Migration[4.2]
DOWNTIME = false
def change
+ # rubocop:disable Migration/AddLimitToStringColumns
create_table :deploy_tokens do |t|
t.boolean :revoked, default: false
t.boolean :read_repository, null: false, default: false
@@ -15,5 +16,6 @@ class CreateDeployTokens < ActiveRecord::Migration[4.2]
t.index [:token, :expires_at, :id], where: "(revoked IS FALSE)"
end
+ # rubocop:enable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20180502122856_create_project_mirror_data.rb b/db/migrate/20180502122856_create_project_mirror_data.rb
index 9781815a97b..04367e1c98b 100644
--- a/db/migrate/20180502122856_create_project_mirror_data.rb
+++ b/db/migrate/20180502122856_create_project_mirror_data.rb
@@ -3,6 +3,7 @@ class CreateProjectMirrorData < ActiveRecord::Migration[4.2]
DOWNTIME = false
+ # rubocop:disable Migration/AddLimitToStringColumns
def up
if table_exists?(:project_mirror_data)
add_column :project_mirror_data, :status, :string unless column_exists?(:project_mirror_data, :status)
@@ -17,6 +18,7 @@ class CreateProjectMirrorData < ActiveRecord::Migration[4.2]
end
end
end
+ # rubocop:enable Migration/AddLimitToStringColumns
def down
remove_column :project_mirror_data, :status
diff --git a/db/migrate/20180503131624_create_remote_mirrors.rb b/db/migrate/20180503131624_create_remote_mirrors.rb
index 288ae365f0f..a079c1b3328 100644
--- a/db/migrate/20180503131624_create_remote_mirrors.rb
+++ b/db/migrate/20180503131624_create_remote_mirrors.rb
@@ -5,6 +5,7 @@ class CreateRemoteMirrors < ActiveRecord::Migration[4.2]
disable_ddl_transaction!
+ # rubocop:disable Migration/AddLimitToStringColumns
def up
return if table_exists?(:remote_mirrors)
@@ -27,6 +28,7 @@ class CreateRemoteMirrors < ActiveRecord::Migration[4.2]
t.timestamps null: false
end
end
+ # rubocop:enable Migration/AddLimitToStringColumns
def down
# ee/db/migrate/20160321161032_create_remote_mirrors_ee.rb will remove the table
diff --git a/db/migrate/20180503175053_ensure_missing_columns_to_project_mirror_data.rb b/db/migrate/20180503175053_ensure_missing_columns_to_project_mirror_data.rb
index 3775b3a08c9..f00493ed515 100644
--- a/db/migrate/20180503175053_ensure_missing_columns_to_project_mirror_data.rb
+++ b/db/migrate/20180503175053_ensure_missing_columns_to_project_mirror_data.rb
@@ -4,8 +4,8 @@ class EnsureMissingColumnsToProjectMirrorData < ActiveRecord::Migration[4.2]
DOWNTIME = false
def up
- add_column :project_mirror_data, :status, :string unless column_exists?(:project_mirror_data, :status)
- add_column :project_mirror_data, :jid, :string unless column_exists?(:project_mirror_data, :jid)
+ add_column :project_mirror_data, :status, :string unless column_exists?(:project_mirror_data, :status) # rubocop:disable Migration/AddLimitToStringColumns
+ add_column :project_mirror_data, :jid, :string unless column_exists?(:project_mirror_data, :jid) # rubocop:disable Migration/AddLimitToStringColumns
add_column :project_mirror_data, :last_error, :text unless column_exists?(:project_mirror_data, :last_error)
end
diff --git a/db/migrate/20180511131058_create_clusters_applications_jupyter.rb b/db/migrate/20180511131058_create_clusters_applications_jupyter.rb
index 749aeeb4792..4633d930e2d 100644
--- a/db/migrate/20180511131058_create_clusters_applications_jupyter.rb
+++ b/db/migrate/20180511131058_create_clusters_applications_jupyter.rb
@@ -7,17 +7,19 @@ class CreateClustersApplicationsJupyter < ActiveRecord::Migration[4.2]
DOWNTIME = false
def change
+ # rubocop:disable Migration/AddLimitToStringColumns
create_table :clusters_applications_jupyter do |t|
t.references :cluster, null: false, unique: true, foreign_key: { on_delete: :cascade }
t.references :oauth_application, foreign_key: { on_delete: :nullify }
t.integer :status, null: false
- t.string :version, null: false
- t.string :hostname
+ t.string :version, null: false # rubocop:disable Migration/AddLimitToStringColumns
+ t.string :hostname # rubocop:disable Migration/AddLimitToStringColumns
t.timestamps_with_timezone null: false
t.text :status_reason
end
+ # rubocop:enable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20180515121227_create_notes_diff_files.rb b/db/migrate/20180515121227_create_notes_diff_files.rb
index e50324d8599..5f6dba11ff9 100644
--- a/db/migrate/20180515121227_create_notes_diff_files.rb
+++ b/db/migrate/20180515121227_create_notes_diff_files.rb
@@ -4,6 +4,7 @@ class CreateNotesDiffFiles < ActiveRecord::Migration[4.2]
disable_ddl_transaction!
def change
+ # rubocop:disable Migration/AddLimitToStringColumns
create_table :note_diff_files do |t|
t.references :diff_note, references: :notes, null: false, index: { unique: true }
t.text :diff, null: false
@@ -18,5 +19,6 @@ class CreateNotesDiffFiles < ActiveRecord::Migration[4.2]
# rubocop:disable Migration/AddConcurrentForeignKey
add_foreign_key :note_diff_files, :notes, column: :diff_note_id, on_delete: :cascade
+ # rubocop:enable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20180529093006_ensure_remote_mirror_columns.rb b/db/migrate/20180529093006_ensure_remote_mirror_columns.rb
index 207e1f089fb..a0a1150f022 100644
--- a/db/migrate/20180529093006_ensure_remote_mirror_columns.rb
+++ b/db/migrate/20180529093006_ensure_remote_mirror_columns.rb
@@ -8,7 +8,7 @@ class EnsureRemoteMirrorColumns < ActiveRecord::Migration[4.2]
def up
# rubocop:disable Migration/Datetime
add_column :remote_mirrors, :last_update_started_at, :datetime unless column_exists?(:remote_mirrors, :last_update_started_at)
- add_column :remote_mirrors, :remote_name, :string unless column_exists?(:remote_mirrors, :remote_name)
+ add_column :remote_mirrors, :remote_name, :string unless column_exists?(:remote_mirrors, :remote_name) # rubocop:disable Migration/AddLimitToStringColumns
unless column_exists?(:remote_mirrors, :only_protected_branches)
add_column_with_default(:remote_mirrors,
diff --git a/db/migrate/20180531185349_add_repository_languages.rb b/db/migrate/20180531185349_add_repository_languages.rb
index 26a01c3bb26..d517c21c26c 100644
--- a/db/migrate/20180531185349_add_repository_languages.rb
+++ b/db/migrate/20180531185349_add_repository_languages.rb
@@ -4,6 +4,7 @@ class AddRepositoryLanguages < ActiveRecord::Migration[4.2]
DOWNTIME = false
def up
+ # rubocop:disable Migration/AddLimitToStringColumns
create_table(:programming_languages) do |t|
t.string :name, null: false
t.string :color, null: false
@@ -19,6 +20,7 @@ class AddRepositoryLanguages < ActiveRecord::Migration[4.2]
add_index :programming_languages, :name, unique: true
add_index :repository_languages, [:project_id, :programming_language_id],
unique: true, name: "index_repository_languages_on_project_and_languages_id"
+ # rubocop:enable Migration/AddLimitToStringColumns
end
def down
diff --git a/db/migrate/20180613081317_create_ci_builds_runner_session.rb b/db/migrate/20180613081317_create_ci_builds_runner_session.rb
index eb41f76b105..68af38834d2 100644
--- a/db/migrate/20180613081317_create_ci_builds_runner_session.rb
+++ b/db/migrate/20180613081317_create_ci_builds_runner_session.rb
@@ -8,6 +8,7 @@ class CreateCiBuildsRunnerSession < ActiveRecord::Migration[4.2]
DOWNTIME = false
def change
+ # rubocop:disable Migration/AddLimitToStringColumns
create_table :ci_builds_runner_session, id: :bigserial do |t|
t.integer :build_id, null: false
t.string :url, null: false
@@ -17,5 +18,6 @@ class CreateCiBuildsRunnerSession < ActiveRecord::Migration[4.2]
t.foreign_key :ci_builds, column: :build_id, on_delete: :cascade
t.index :build_id, unique: true
end
+ # rubocop:enable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20180713092803_create_user_statuses.rb b/db/migrate/20180713092803_create_user_statuses.rb
index 43b96805c1e..3abab4e45a9 100644
--- a/db/migrate/20180713092803_create_user_statuses.rb
+++ b/db/migrate/20180713092803_create_user_statuses.rb
@@ -6,6 +6,7 @@ class CreateUserStatuses < ActiveRecord::Migration[4.2]
DOWNTIME = false
def change
+ # rubocop:disable Migration/AddLimitToStringColumns
create_table :user_statuses, id: false, primary_key: :user_id do |t|
t.references :user,
foreign_key: { on_delete: :cascade },
@@ -16,5 +17,6 @@ class CreateUserStatuses < ActiveRecord::Migration[4.2]
t.string :message, limit: 100
t.string :message_html
end
+ # rubocop:enable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20180814153625_add_commit_email_to_users.rb b/db/migrate/20180814153625_add_commit_email_to_users.rb
index 4d9217ea504..98bafc14a03 100644
--- a/db/migrate/20180814153625_add_commit_email_to_users.rb
+++ b/db/migrate/20180814153625_add_commit_email_to_users.rb
@@ -28,6 +28,6 @@ class AddCommitEmailToUsers < ActiveRecord::Migration[4.2]
# disable_ddl_transaction!
def change
- add_column :users, :commit_email, :string
+ add_column :users, :commit_email, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20180831164908_add_identifier_to_prometheus_metric.rb b/db/migrate/20180831164908_add_identifier_to_prometheus_metric.rb
index 7aa5950249c..8f30363c310 100644
--- a/db/migrate/20180831164908_add_identifier_to_prometheus_metric.rb
+++ b/db/migrate/20180831164908_add_identifier_to_prometheus_metric.rb
@@ -6,6 +6,6 @@ class AddIdentifierToPrometheusMetric < ActiveRecord::Migration[4.2]
DOWNTIME = false
def change
- add_column :prometheus_metrics, :identifier, :string
+ add_column :prometheus_metrics, :identifier, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20180910115836_add_attr_encrypted_columns_to_web_hook.rb b/db/migrate/20180910115836_add_attr_encrypted_columns_to_web_hook.rb
index ca8dbdba2bb..9757f7fdc79 100644
--- a/db/migrate/20180910115836_add_attr_encrypted_columns_to_web_hook.rb
+++ b/db/migrate/20180910115836_add_attr_encrypted_columns_to_web_hook.rb
@@ -6,10 +6,12 @@ class AddAttrEncryptedColumnsToWebHook < ActiveRecord::Migration[4.2]
DOWNTIME = false
def change
+ # rubocop:disable Migration/AddLimitToStringColumns
add_column :web_hooks, :encrypted_token, :string
add_column :web_hooks, :encrypted_token_iv, :string
add_column :web_hooks, :encrypted_url, :string
add_column :web_hooks, :encrypted_url_iv, :string
+ # rubocop:enable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20180910153412_add_token_digest_to_personal_access_tokens.rb b/db/migrate/20180910153412_add_token_digest_to_personal_access_tokens.rb
index 142e454832f..52923f52499 100644
--- a/db/migrate/20180910153412_add_token_digest_to_personal_access_tokens.rb
+++ b/db/migrate/20180910153412_add_token_digest_to_personal_access_tokens.rb
@@ -8,7 +8,7 @@ class AddTokenDigestToPersonalAccessTokens < ActiveRecord::Migration[4.2]
def up
change_column :personal_access_tokens, :token, :string, null: true
- add_column :personal_access_tokens, :token_digest, :string
+ add_column :personal_access_tokens, :token_digest, :string # rubocop:disable Migration/AddLimitToStringColumns
end
def down
diff --git a/db/migrate/20180912111628_add_knative_application.rb b/db/migrate/20180912111628_add_knative_application.rb
index 86d9100d2e7..7c55de02d1c 100644
--- a/db/migrate/20180912111628_add_knative_application.rb
+++ b/db/migrate/20180912111628_add_knative_application.rb
@@ -6,6 +6,7 @@ class AddKnativeApplication < ActiveRecord::Migration[4.2]
DOWNTIME = false
def change
+ # rubocop:disable Migration/AddLimitToStringColumns
create_table "clusters_applications_knative" do |t|
t.references :cluster, null: false, unique: true, foreign_key: { on_delete: :cascade }
@@ -16,5 +17,6 @@ class AddKnativeApplication < ActiveRecord::Migration[4.2]
t.string "hostname"
t.text "status_reason"
end
+ # rubocop:enable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20181009190428_create_clusters_kubernetes_namespaces.rb b/db/migrate/20181009190428_create_clusters_kubernetes_namespaces.rb
index 62ad6c63d0a..b6ffb2866aa 100644
--- a/db/migrate/20181009190428_create_clusters_kubernetes_namespaces.rb
+++ b/db/migrate/20181009190428_create_clusters_kubernetes_namespaces.rb
@@ -5,6 +5,7 @@ class CreateClustersKubernetesNamespaces < ActiveRecord::Migration[4.2]
INDEX_NAME = 'kubernetes_namespaces_cluster_and_namespace'
def change
+ # rubocop:disable Migration/AddLimitToStringColumns
create_table :clusters_kubernetes_namespaces, id: :bigserial do |t|
t.references :cluster, null: false, index: true, foreign_key: { on_delete: :cascade }
t.references :project, index: true, foreign_key: { on_delete: :nullify }
@@ -20,5 +21,6 @@ class CreateClustersKubernetesNamespaces < ActiveRecord::Migration[4.2]
t.index [:cluster_id, :namespace], name: INDEX_NAME, unique: true
end
+ # rubocop:enable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20181019032400_add_shards_table.rb b/db/migrate/20181019032400_add_shards_table.rb
index e31af97cc94..82287e5c3b5 100644
--- a/db/migrate/20181019032400_add_shards_table.rb
+++ b/db/migrate/20181019032400_add_shards_table.rb
@@ -5,7 +5,7 @@ class AddShardsTable < ActiveRecord::Migration[4.2]
def change
create_table :shards do |t|
- t.string :name, null: false, index: { unique: true }
+ t.string :name, null: false, index: { unique: true } # rubocop:disable Migration/AddLimitToStringColumns
end
end
end
diff --git a/db/migrate/20181019032408_add_repositories_table.rb b/db/migrate/20181019032408_add_repositories_table.rb
index 2153c1c9fc6..dd510b44084 100644
--- a/db/migrate/20181019032408_add_repositories_table.rb
+++ b/db/migrate/20181019032408_add_repositories_table.rb
@@ -6,7 +6,7 @@ class AddRepositoriesTable < ActiveRecord::Migration[4.2]
def change
create_table :repositories, id: :bigserial do |t|
t.references :shard, null: false, index: true, foreign_key: { on_delete: :restrict }
- t.string :disk_path, null: false, index: { unique: true }
+ t.string :disk_path, null: false, index: { unique: true } # rubocop:disable Migration/AddLimitToStringColumns
end
add_column :projects, :pool_repository_id, :bigint
diff --git a/db/migrate/20181025115728_add_private_commit_email_hostname_to_application_settings.rb b/db/migrate/20181025115728_add_private_commit_email_hostname_to_application_settings.rb
index 052a344f182..c0e4897b8d7 100644
--- a/db/migrate/20181025115728_add_private_commit_email_hostname_to_application_settings.rb
+++ b/db/migrate/20181025115728_add_private_commit_email_hostname_to_application_settings.rb
@@ -6,6 +6,6 @@ class AddPrivateCommitEmailHostnameToApplicationSettings < ActiveRecord::Migrati
DOWNTIME = false
def change
- add_column(:application_settings, :commit_email_hostname, :string, null: true)
+ add_column(:application_settings, :commit_email_hostname, :string, null: true) # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20181031190559_drop_gcp_clusters_table.rb b/db/migrate/20181031190559_drop_gcp_clusters_table.rb
index 597fe49f4c8..850fa93c75a 100644
--- a/db/migrate/20181031190559_drop_gcp_clusters_table.rb
+++ b/db/migrate/20181031190559_drop_gcp_clusters_table.rb
@@ -10,6 +10,7 @@ class DropGcpClustersTable < ActiveRecord::Migration[4.2]
end
def down
+ # rubocop:disable Migration/AddLimitToStringColumns
create_table :gcp_clusters do |t|
# Order columns by best align scheme
t.references :project, null: false, index: { unique: true }, foreign_key: { on_delete: :cascade }
@@ -49,5 +50,6 @@ class DropGcpClustersTable < ActiveRecord::Migration[4.2]
t.text :encrypted_gcp_token
t.string :encrypted_gcp_token_iv
end
+ # rubocop:enable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20181101191341_create_clusters_applications_cert_manager.rb b/db/migrate/20181101191341_create_clusters_applications_cert_manager.rb
index 0b6155356d9..3bc20046311 100644
--- a/db/migrate/20181101191341_create_clusters_applications_cert_manager.rb
+++ b/db/migrate/20181101191341_create_clusters_applications_cert_manager.rb
@@ -6,6 +6,7 @@ class CreateClustersApplicationsCertManager < ActiveRecord::Migration[4.2]
DOWNTIME = false
def change
+ # rubocop:disable Migration/AddLimitToStringColumns
create_table :clusters_applications_cert_managers do |t|
t.references :cluster, null: false, index: false, foreign_key: { on_delete: :cascade }
t.integer :status, null: false
@@ -15,5 +16,6 @@ class CreateClustersApplicationsCertManager < ActiveRecord::Migration[4.2]
t.text :status_reason
t.index :cluster_id, unique: true
end
+ # rubocop:enable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20181115140140_add_encrypted_runners_token_to_settings.rb b/db/migrate/20181115140140_add_encrypted_runners_token_to_settings.rb
index 5b2bb4f6b08..124eedf7933 100644
--- a/db/migrate/20181115140140_add_encrypted_runners_token_to_settings.rb
+++ b/db/migrate/20181115140140_add_encrypted_runners_token_to_settings.rb
@@ -6,6 +6,6 @@ class AddEncryptedRunnersTokenToSettings < ActiveRecord::Migration[4.2]
DOWNTIME = false
def change
- add_column :application_settings, :runners_registration_token_encrypted, :string
+ add_column :application_settings, :runners_registration_token_encrypted, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20181116050532_knative_external_ip.rb b/db/migrate/20181116050532_knative_external_ip.rb
index 5645b040a23..4634b411108 100644
--- a/db/migrate/20181116050532_knative_external_ip.rb
+++ b/db/migrate/20181116050532_knative_external_ip.rb
@@ -9,6 +9,6 @@ class KnativeExternalIp < ActiveRecord::Migration[4.2]
DOWNTIME = false
def change
- add_column :clusters_applications_knative, :external_ip, :string
+ add_column :clusters_applications_knative, :external_ip, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20181116141415_add_encrypted_runners_token_to_namespaces.rb b/db/migrate/20181116141415_add_encrypted_runners_token_to_namespaces.rb
index dcf565cd6c0..0a8ed912891 100644
--- a/db/migrate/20181116141415_add_encrypted_runners_token_to_namespaces.rb
+++ b/db/migrate/20181116141415_add_encrypted_runners_token_to_namespaces.rb
@@ -6,6 +6,6 @@ class AddEncryptedRunnersTokenToNamespaces < ActiveRecord::Migration[4.2]
DOWNTIME = false
def change
- add_column :namespaces, :runners_token_encrypted, :string
+ add_column :namespaces, :runners_token_encrypted, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20181116141504_add_encrypted_runners_token_to_projects.rb b/db/migrate/20181116141504_add_encrypted_runners_token_to_projects.rb
index 13cd80e5c8b..3083dff49b8 100644
--- a/db/migrate/20181116141504_add_encrypted_runners_token_to_projects.rb
+++ b/db/migrate/20181116141504_add_encrypted_runners_token_to_projects.rb
@@ -6,6 +6,6 @@ class AddEncryptedRunnersTokenToProjects < ActiveRecord::Migration[4.2]
DOWNTIME = false
def change
- add_column :projects, :runners_token_encrypted, :string
+ add_column :projects, :runners_token_encrypted, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20181120151656_add_token_encrypted_to_ci_runners.rb b/db/migrate/20181120151656_add_token_encrypted_to_ci_runners.rb
index 8b990451adc..2270246dfb4 100644
--- a/db/migrate/20181120151656_add_token_encrypted_to_ci_runners.rb
+++ b/db/migrate/20181120151656_add_token_encrypted_to_ci_runners.rb
@@ -6,6 +6,6 @@ class AddTokenEncryptedToCiRunners < ActiveRecord::Migration[4.2]
DOWNTIME = false
def change
- add_column :ci_runners, :token_encrypted, :string
+ add_column :ci_runners, :token_encrypted, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20181122160027_create_project_repositories.rb b/db/migrate/20181122160027_create_project_repositories.rb
index e42cef9b1c6..3f123daa150 100644
--- a/db/migrate/20181122160027_create_project_repositories.rb
+++ b/db/migrate/20181122160027_create_project_repositories.rb
@@ -11,7 +11,7 @@ class CreateProjectRepositories < ActiveRecord::Migration[5.0]
def change
create_table :project_repositories, id: :bigserial do |t|
t.references :shard, null: false, index: true, foreign_key: { on_delete: :restrict }
- t.string :disk_path, null: false, index: { unique: true }
+ t.string :disk_path, null: false, index: { unique: true } # rubocop:disable Migration/AddLimitToStringColumns
t.references :project, null: false, index: { unique: true }, foreign_key: { on_delete: :cascade }
end
end
diff --git a/db/migrate/20181123144235_create_suggestions.rb b/db/migrate/20181123144235_create_suggestions.rb
index 1723f6de7eb..78888517db5 100644
--- a/db/migrate/20181123144235_create_suggestions.rb
+++ b/db/migrate/20181123144235_create_suggestions.rb
@@ -8,7 +8,7 @@ class CreateSuggestions < ActiveRecord::Migration[5.0]
t.references :note, foreign_key: { on_delete: :cascade }, null: false
t.integer :relative_order, null: false, limit: 2
t.boolean :applied, null: false, default: false
- t.string :commit_id
+ t.string :commit_id # rubocop:disable Migration/AddLimitToStringColumns
t.text :from_content, null: false
t.text :to_content, null: false
diff --git a/db/migrate/20181128123704_add_state_to_pool_repository.rb b/db/migrate/20181128123704_add_state_to_pool_repository.rb
index 714232ede56..04bbcf24f62 100644
--- a/db/migrate/20181128123704_add_state_to_pool_repository.rb
+++ b/db/migrate/20181128123704_add_state_to_pool_repository.rb
@@ -9,7 +9,7 @@ class AddStateToPoolRepository < ActiveRecord::Migration[5.0]
# the transactions don't have to be disabled
# rubocop: disable Migration/AddConcurrentForeignKey, Migration/AddIndex
def change
- add_column(:pool_repositories, :state, :string, null: true)
+ add_column(:pool_repositories, :state, :string, null: true) # rubocop:disable Migration/AddLimitToStringColumns
add_column :pool_repositories, :source_project_id, :integer
add_index :pool_repositories, :source_project_id, unique: true
diff --git a/db/migrate/20181129104854_add_token_encrypted_to_ci_builds.rb b/db/migrate/20181129104854_add_token_encrypted_to_ci_builds.rb
index 11b98203793..62a7421eae0 100644
--- a/db/migrate/20181129104854_add_token_encrypted_to_ci_builds.rb
+++ b/db/migrate/20181129104854_add_token_encrypted_to_ci_builds.rb
@@ -6,6 +6,6 @@ class AddTokenEncryptedToCiBuilds < ActiveRecord::Migration[5.0]
DOWNTIME = false
def change
- add_column :ci_builds, :token_encrypted, :string
+ add_column :ci_builds, :token_encrypted, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20181203002526_add_project_bfg_object_map_column.rb b/db/migrate/20181203002526_add_project_bfg_object_map_column.rb
index 8b42cd6f941..5e6d416895c 100644
--- a/db/migrate/20181203002526_add_project_bfg_object_map_column.rb
+++ b/db/migrate/20181203002526_add_project_bfg_object_map_column.rb
@@ -4,6 +4,6 @@ class AddProjectBfgObjectMapColumn < ActiveRecord::Migration[5.0]
DOWNTIME = false
def change
- add_column :projects, :bfg_object_map, :string
+ add_column :projects, :bfg_object_map, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20181211092510_add_name_author_id_and_sha_to_releases.rb b/db/migrate/20181211092510_add_name_author_id_and_sha_to_releases.rb
index 60815e0c31a..3ab808ba667 100644
--- a/db/migrate/20181211092510_add_name_author_id_and_sha_to_releases.rb
+++ b/db/migrate/20181211092510_add_name_author_id_and_sha_to_releases.rb
@@ -7,7 +7,7 @@ class AddNameAuthorIdAndShaToReleases < ActiveRecord::Migration[5.0]
def change
add_column :releases, :author_id, :integer
- add_column :releases, :name, :string
- add_column :releases, :sha, :string
+ add_column :releases, :name, :string # rubocop:disable Migration/AddLimitToStringColumns
+ add_column :releases, :sha, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20181212171634_create_error_tracking_settings.rb b/db/migrate/20181212171634_create_error_tracking_settings.rb
index 18c38bd2c47..950b9a88005 100644
--- a/db/migrate/20181212171634_create_error_tracking_settings.rb
+++ b/db/migrate/20181212171634_create_error_tracking_settings.rb
@@ -6,6 +6,7 @@ class CreateErrorTrackingSettings < ActiveRecord::Migration[5.0]
DOWNTIME = false
def change
+ # rubocop:disable Migration/AddLimitToStringColumns
create_table :project_error_tracking_settings, id: :int, primary_key: :project_id, default: nil do |t|
t.boolean :enabled, null: false, default: true
t.string :api_url, null: false
@@ -13,5 +14,6 @@ class CreateErrorTrackingSettings < ActiveRecord::Migration[5.0]
t.string :encrypted_token_iv
t.foreign_key :projects, column: :project_id, on_delete: :cascade
end
+ # rubocop:enable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20181228175414_create_releases_link_table.rb b/db/migrate/20181228175414_create_releases_link_table.rb
index 03558202137..168c4722cc1 100644
--- a/db/migrate/20181228175414_create_releases_link_table.rb
+++ b/db/migrate/20181228175414_create_releases_link_table.rb
@@ -6,6 +6,7 @@ class CreateReleasesLinkTable < ActiveRecord::Migration[5.0]
DOWNTIME = false
def change
+ # rubocop:disable Migration/AddLimitToStringColumns
create_table :release_links, id: :bigserial do |t|
t.references :release, null: false, index: false, foreign_key: { on_delete: :cascade }
t.string :url, null: false
@@ -15,5 +16,6 @@ class CreateReleasesLinkTable < ActiveRecord::Migration[5.0]
t.index [:release_id, :url], unique: true
t.index [:release_id, :name], unique: true
end
+ # rubocop:enable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20190109153125_add_merge_request_external_diffs.rb b/db/migrate/20190109153125_add_merge_request_external_diffs.rb
index c67903c7f67..a680856a3d8 100644
--- a/db/migrate/20190109153125_add_merge_request_external_diffs.rb
+++ b/db/migrate/20190109153125_add_merge_request_external_diffs.rb
@@ -11,7 +11,7 @@ class AddMergeRequestExternalDiffs < ActiveRecord::Migration[5.0]
def change
# Allow the merge request diff to store details about an external file
- add_column :merge_request_diffs, :external_diff, :string
+ add_column :merge_request_diffs, :external_diff, :string # rubocop:disable Migration/AddLimitToStringColumns
add_column :merge_request_diffs, :external_diff_store, :integer
add_column :merge_request_diffs, :stored_externally, :boolean
diff --git a/db/migrate/20190114172110_add_domain_to_cluster.rb b/db/migrate/20190114172110_add_domain_to_cluster.rb
index 58d7664b8c0..d8f10af9cad 100644
--- a/db/migrate/20190114172110_add_domain_to_cluster.rb
+++ b/db/migrate/20190114172110_add_domain_to_cluster.rb
@@ -4,6 +4,6 @@ class AddDomainToCluster < ActiveRecord::Migration[5.0]
DOWNTIME = false
def change
- add_column :clusters, :domain, :string
+ add_column :clusters, :domain, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20190115092821_add_columns_project_error_tracking_settings.rb b/db/migrate/20190115092821_add_columns_project_error_tracking_settings.rb
index 190b6f958fd..afed929cce4 100644
--- a/db/migrate/20190115092821_add_columns_project_error_tracking_settings.rb
+++ b/db/migrate/20190115092821_add_columns_project_error_tracking_settings.rb
@@ -6,8 +6,8 @@ class AddColumnsProjectErrorTrackingSettings < ActiveRecord::Migration[5.0]
DOWNTIME = false
def change
- add_column :project_error_tracking_settings, :project_name, :string
- add_column :project_error_tracking_settings, :organization_name, :string
+ add_column :project_error_tracking_settings, :project_name, :string # rubocop:disable Migration/AddLimitToStringColumns
+ add_column :project_error_tracking_settings, :organization_name, :string # rubocop:disable Migration/AddLimitToStringColumns
change_column_default :project_error_tracking_settings, :enabled, from: true, to: false
diff --git a/db/migrate/20190116234221_add_sorting_fields_to_user_preference.rb b/db/migrate/20190116234221_add_sorting_fields_to_user_preference.rb
index 7bf581fe9b0..39aab600546 100644
--- a/db/migrate/20190116234221_add_sorting_fields_to_user_preference.rb
+++ b/db/migrate/20190116234221_add_sorting_fields_to_user_preference.rb
@@ -10,8 +10,8 @@ class AddSortingFieldsToUserPreference < ActiveRecord::Migration[5.0]
DOWNTIME = false
def up
- add_column :user_preferences, :issues_sort, :string
- add_column :user_preferences, :merge_requests_sort, :string
+ add_column :user_preferences, :issues_sort, :string # rubocop:disable Migration/AddLimitToStringColumns
+ add_column :user_preferences, :merge_requests_sort, :string # rubocop:disable Migration/AddLimitToStringColumns
end
def down
diff --git a/db/migrate/20190301182457_add_external_hostname_to_ingress_and_knative.rb b/db/migrate/20190301182457_add_external_hostname_to_ingress_and_knative.rb
index 2c3a54b12a9..37ba1090cf0 100644
--- a/db/migrate/20190301182457_add_external_hostname_to_ingress_and_knative.rb
+++ b/db/migrate/20190301182457_add_external_hostname_to_ingress_and_knative.rb
@@ -4,7 +4,7 @@ class AddExternalHostnameToIngressAndKnative < ActiveRecord::Migration[5.0]
DOWNTIME = false
def change
- add_column :clusters_applications_ingress, :external_hostname, :string
- add_column :clusters_applications_knative, :external_hostname, :string
+ add_column :clusters_applications_ingress, :external_hostname, :string # rubocop:disable Migration/AddLimitToStringColumns
+ add_column :clusters_applications_knative, :external_hostname, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20190320174702_add_lets_encrypt_notification_email_to_application_settings.rb b/db/migrate/20190320174702_add_lets_encrypt_notification_email_to_application_settings.rb
index e9cf2af84a5..aeabf4e3cb4 100644
--- a/db/migrate/20190320174702_add_lets_encrypt_notification_email_to_application_settings.rb
+++ b/db/migrate/20190320174702_add_lets_encrypt_notification_email_to_application_settings.rb
@@ -10,6 +10,6 @@ class AddLetsEncryptNotificationEmailToApplicationSettings < ActiveRecord::Migra
DOWNTIME = false
def change
- add_column :application_settings, :lets_encrypt_notification_email, :string
+ add_column :application_settings, :lets_encrypt_notification_email, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20190325105715_add_fields_to_user_preferences.rb b/db/migrate/20190325105715_add_fields_to_user_preferences.rb
index 9ea3b4f9cd8..4da5c496147 100644
--- a/db/migrate/20190325105715_add_fields_to_user_preferences.rb
+++ b/db/migrate/20190325105715_add_fields_to_user_preferences.rb
@@ -11,7 +11,7 @@ class AddFieldsToUserPreferences < ActiveRecord::Migration[5.0]
DOWNTIME = false
def up
- add_column(:user_preferences, :timezone, :string)
+ add_column(:user_preferences, :timezone, :string) # rubocop:disable Migration/AddLimitToStringColumns
add_column(:user_preferences, :time_display_relative, :boolean)
add_column(:user_preferences, :time_format_in_24h, :boolean)
end
diff --git a/db/migrate/20190327163904_add_notification_email_to_notification_settings.rb b/db/migrate/20190327163904_add_notification_email_to_notification_settings.rb
index 2f3069032a1..d912f922510 100644
--- a/db/migrate/20190327163904_add_notification_email_to_notification_settings.rb
+++ b/db/migrate/20190327163904_add_notification_email_to_notification_settings.rb
@@ -6,6 +6,6 @@ class AddNotificationEmailToNotificationSettings < ActiveRecord::Migration[5.0]
DOWNTIME = false
def change
- add_column :notification_settings, :notification_email, :string
+ add_column :notification_settings, :notification_email, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20190402150158_backport_enterprise_schema.rb b/db/migrate/20190402150158_backport_enterprise_schema.rb
index 8762cc53ed7..3f13b68c2f3 100644
--- a/db/migrate/20190402150158_backport_enterprise_schema.rb
+++ b/db/migrate/20190402150158_backport_enterprise_schema.rb
@@ -2,6 +2,7 @@
# rubocop: disable Metrics/AbcSize
# rubocop: disable Migration/Datetime
+# rubocop: disable Migration/AddLimitToStringColumns
class BackportEnterpriseSchema < ActiveRecord::Migration[5.0]
include Gitlab::Database::MigrationHelpers
@@ -2190,3 +2191,4 @@ class BackportEnterpriseSchema < ActiveRecord::Migration[5.0]
end
# rubocop: enable Metrics/AbcSize
# rubocop: enable Migration/Datetime
+# rubocop: enable Migration/AddLimitToStringColumns
diff --git a/db/migrate/20190409224933_add_name_to_geo_nodes.rb b/db/migrate/20190409224933_add_name_to_geo_nodes.rb
index 2dff81b429c..65c01683995 100644
--- a/db/migrate/20190409224933_add_name_to_geo_nodes.rb
+++ b/db/migrate/20190409224933_add_name_to_geo_nodes.rb
@@ -10,7 +10,7 @@ class AddNameToGeoNodes < ActiveRecord::Migration[5.0]
DOWNTIME = false
def up
- add_column :geo_nodes, :name, :string
+ add_column :geo_nodes, :name, :string # rubocop:disable Migration/AddLimitToStringColumns
# url is also unique, and its type and size is identical to the name column,
# so this is safe.
diff --git a/db/migrate/20190422082247_create_project_metrics_settings.rb b/db/migrate/20190422082247_create_project_metrics_settings.rb
index 3e21dd0a934..a0a2ed64820 100644
--- a/db/migrate/20190422082247_create_project_metrics_settings.rb
+++ b/db/migrate/20190422082247_create_project_metrics_settings.rb
@@ -7,7 +7,7 @@ class CreateProjectMetricsSettings < ActiveRecord::Migration[5.0]
def change
create_table :project_metrics_settings, id: :int, primary_key: :project_id, default: nil do |t|
- t.string :external_dashboard_url, null: false
+ t.string :external_dashboard_url, null: false # rubocop:disable Migration/AddLimitToStringColumns
t.foreign_key :projects, column: :project_id, on_delete: :cascade
end
end
diff --git a/db/migrate/20190429082448_create_pages_domain_acme_orders.rb b/db/migrate/20190429082448_create_pages_domain_acme_orders.rb
index af811e83518..ca1796d054c 100644
--- a/db/migrate/20190429082448_create_pages_domain_acme_orders.rb
+++ b/db/migrate/20190429082448_create_pages_domain_acme_orders.rb
@@ -10,6 +10,7 @@ class CreatePagesDomainAcmeOrders < ActiveRecord::Migration[5.1]
DOWNTIME = false
def change
+ # rubocop:disable Migration/AddLimitToStringColumns
create_table :pages_domain_acme_orders do |t|
t.references :pages_domain, null: false, index: true, foreign_key: { on_delete: :cascade }, type: :integer
@@ -24,5 +25,6 @@ class CreatePagesDomainAcmeOrders < ActiveRecord::Migration[5.1]
t.text :encrypted_private_key, null: false
t.text :encrypted_private_key_iv, null: false
end
+ # rubocop:enable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20190430131225_create_issue_tracker_data.rb b/db/migrate/20190430131225_create_issue_tracker_data.rb
index 7859bea9c22..d2134ad82c7 100644
--- a/db/migrate/20190430131225_create_issue_tracker_data.rb
+++ b/db/migrate/20190430131225_create_issue_tracker_data.rb
@@ -9,6 +9,7 @@ class CreateIssueTrackerData < ActiveRecord::Migration[5.1]
DOWNTIME = false
def change
+ # rubocop:disable Migration/AddLimitToStringColumns
create_table :issue_tracker_data do |t|
t.references :service, foreign_key: { on_delete: :cascade }, type: :integer, index: true, null: false
t.timestamps_with_timezone
@@ -19,5 +20,6 @@ class CreateIssueTrackerData < ActiveRecord::Migration[5.1]
t.string :encrypted_new_issue_url
t.string :encrypted_new_issue_url_iv
end
+ # rubocop:enable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20190430142025_create_jira_tracker_data.rb b/db/migrate/20190430142025_create_jira_tracker_data.rb
index d328ad63854..5e53e5a701a 100644
--- a/db/migrate/20190430142025_create_jira_tracker_data.rb
+++ b/db/migrate/20190430142025_create_jira_tracker_data.rb
@@ -9,6 +9,7 @@ class CreateJiraTrackerData < ActiveRecord::Migration[5.1]
DOWNTIME = false
def change
+ # rubocop:disable Migration/AddLimitToStringColumns
create_table :jira_tracker_data do |t|
t.references :service, foreign_key: { on_delete: :cascade }, type: :integer, index: true, null: false
t.timestamps_with_timezone
@@ -22,5 +23,6 @@ class CreateJiraTrackerData < ActiveRecord::Migration[5.1]
t.string :encrypted_password_iv
t.string :jira_issue_transition_id
end
+ # rubocop:enable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20190514105711_create_ip_restriction.rb b/db/migrate/20190514105711_create_ip_restriction.rb
index dfafbe32ad1..69f8c1b8c4e 100644
--- a/db/migrate/20190514105711_create_ip_restriction.rb
+++ b/db/migrate/20190514105711_create_ip_restriction.rb
@@ -12,7 +12,7 @@ class CreateIpRestriction < ActiveRecord::Migration[5.1]
type: :integer,
null: false,
index: true
- t.string :range, null: false
+ t.string :range, null: false # rubocop:disable Migration/AddLimitToStringColumns
end
add_foreign_key(:ip_restrictions, :namespaces, column: :group_id, on_delete: :cascade) # rubocop: disable Migration/AddConcurrentForeignKey
diff --git a/db/migrate/20190527011309_add_required_template_name_to_application_settings.rb b/db/migrate/20190527011309_add_required_template_name_to_application_settings.rb
index 6cbac0ed507..5c47e6f33c2 100644
--- a/db/migrate/20190527011309_add_required_template_name_to_application_settings.rb
+++ b/db/migrate/20190527011309_add_required_template_name_to_application_settings.rb
@@ -10,6 +10,6 @@ class AddRequiredTemplateNameToApplicationSettings < ActiveRecord::Migration[5.1
DOWNTIME = false
def change
- add_column :application_settings, :required_instance_ci_template, :string, null: true
+ add_column :application_settings, :required_instance_ci_template, :string, null: true # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20190606054742_add_token_encrypted_to_operations_feature_flags_clients.rb b/db/migrate/20190606054742_add_token_encrypted_to_operations_feature_flags_clients.rb
index 024b5bd2ba5..2db4dc85750 100644
--- a/db/migrate/20190606054742_add_token_encrypted_to_operations_feature_flags_clients.rb
+++ b/db/migrate/20190606054742_add_token_encrypted_to_operations_feature_flags_clients.rb
@@ -6,6 +6,6 @@ class AddTokenEncryptedToOperationsFeatureFlagsClients < ActiveRecord::Migration
DOWNTIME = false
def change
- add_column :operations_feature_flags_clients, :token_encrypted, :string
+ add_column :operations_feature_flags_clients, :token_encrypted, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20190613044655_add_username_to_deploy_tokens.rb b/db/migrate/20190613044655_add_username_to_deploy_tokens.rb
index 793553afe35..a0acb02013b 100644
--- a/db/migrate/20190613044655_add_username_to_deploy_tokens.rb
+++ b/db/migrate/20190613044655_add_username_to_deploy_tokens.rb
@@ -4,6 +4,6 @@ class AddUsernameToDeployTokens < ActiveRecord::Migration[5.1]
DOWNTIME = false
def change
- add_column :deploy_tokens, :username, :string
+ add_column :deploy_tokens, :username, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20190613073003_create_project_aliases.rb b/db/migrate/20190613073003_create_project_aliases.rb
index 5a2c2ba0cf2..896d3ca5813 100644
--- a/db/migrate/20190613073003_create_project_aliases.rb
+++ b/db/migrate/20190613073003_create_project_aliases.rb
@@ -8,7 +8,7 @@ class CreateProjectAliases < ActiveRecord::Migration[5.1]
def change
create_table :project_aliases do |t|
t.references :project, null: false, index: true, foreign_key: { on_delete: :cascade }, type: :integer
- t.string :name, null: false, index: { unique: true }
+ t.string :name, null: false, index: { unique: true } # rubocop:disable Migration/AddLimitToStringColumns
t.timestamps_with_timezone null: false
end
diff --git a/db/migrate/20190621151636_add_merge_request_rebase_jid.rb b/db/migrate/20190621151636_add_merge_request_rebase_jid.rb
index 1fed5690ead..6c1081732e8 100644
--- a/db/migrate/20190621151636_add_merge_request_rebase_jid.rb
+++ b/db/migrate/20190621151636_add_merge_request_rebase_jid.rb
@@ -4,6 +4,6 @@ class AddMergeRequestRebaseJid < ActiveRecord::Migration[5.1]
DOWNTIME = false
def change
- add_column :merge_requests, :rebase_jid, :string
+ add_column :merge_requests, :rebase_jid, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/migrate/20190624123615_add_grafana_url_to_settings.rb b/db/migrate/20190624123615_add_grafana_url_to_settings.rb
index 61efe64a7a1..835ec4e9094 100644
--- a/db/migrate/20190624123615_add_grafana_url_to_settings.rb
+++ b/db/migrate/20190624123615_add_grafana_url_to_settings.rb
@@ -8,8 +8,10 @@ class AddGrafanaUrlToSettings < ActiveRecord::Migration[5.1]
DOWNTIME = false
def up
+ # rubocop:disable Migration/AddLimitToStringColumns
add_column_with_default(:application_settings, :grafana_url, :string,
default: '/-/grafana', allow_null: false)
+ # rubocop:enable Migration/AddLimitToStringColumns
end
def down
diff --git a/db/migrate/20190711124721_create_job_variables.rb b/db/migrate/20190711124721_create_job_variables.rb
index a860522f39e..4ff4b031d8f 100644
--- a/db/migrate/20190711124721_create_job_variables.rb
+++ b/db/migrate/20190711124721_create_job_variables.rb
@@ -10,6 +10,7 @@ class CreateJobVariables < ActiveRecord::Migration[5.1]
DOWNTIME = false
def change
+ # rubocop:disable Migration/AddLimitToStringColumns
create_table :ci_job_variables do |t|
t.string :key, null: false
t.text :encrypted_value
@@ -17,6 +18,7 @@ class CreateJobVariables < ActiveRecord::Migration[5.1]
t.references :job, null: false, index: true, foreign_key: { to_table: :ci_builds, on_delete: :cascade }
t.integer :variable_type, null: false, limit: 2, default: 1
end
+ # rubocop:enable Migration/AddLimitToStringColumns
add_index :ci_job_variables, [:key, :job_id], unique: true
end
diff --git a/db/migrate/20190726101050_rename_allow_local_requests_from_hooks_and_services_application_setting.rb b/db/migrate/20190726101050_rename_allow_local_requests_from_hooks_and_services_application_setting.rb
index ac65e8d745c..cce8942128c 100644
--- a/db/migrate/20190726101050_rename_allow_local_requests_from_hooks_and_services_application_setting.rb
+++ b/db/migrate/20190726101050_rename_allow_local_requests_from_hooks_and_services_application_setting.rb
@@ -12,6 +12,6 @@ class RenameAllowLocalRequestsFromHooksAndServicesApplicationSetting < ActiveRec
end
def down
- cleanup_concurrent_column_rename :application_settings, :allow_local_requests_from_web_hooks_and_services, :allow_local_requests_from_hooks_and_services
+ undo_rename_column_concurrently :application_settings, :allow_local_requests_from_hooks_and_services, :allow_local_requests_from_web_hooks_and_services
end
end
diff --git a/db/migrate/20190805140353_remove_rendundant_index_from_releases.rb b/db/migrate/20190805140353_remove_rendundant_index_from_releases.rb
new file mode 100644
index 00000000000..fc4bc1a423b
--- /dev/null
+++ b/db/migrate/20190805140353_remove_rendundant_index_from_releases.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class RemoveRendundantIndexFromReleases < ActiveRecord::Migration[5.2]
+ include Gitlab::Database::MigrationHelpers
+
+ # Set this constant to true if this migration requires downtime.
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ remove_concurrent_index :releases, :project_id
+ end
+
+ def down
+ add_concurrent_index :releases, :project_id
+ end
+end
diff --git a/db/post_migrate/20181013005024_remove_koding_from_application_settings.rb b/db/post_migrate/20181013005024_remove_koding_from_application_settings.rb
index 550ad94f4ab..b6e5473e896 100644
--- a/db/post_migrate/20181013005024_remove_koding_from_application_settings.rb
+++ b/db/post_migrate/20181013005024_remove_koding_from_application_settings.rb
@@ -12,6 +12,6 @@ class RemoveKodingFromApplicationSettings < ActiveRecord::Migration[4.2]
def down
add_column :application_settings, :koding_enabled, :boolean # rubocop:disable Migration/SaferBooleanColumn
- add_column :application_settings, :koding_url, :string
+ add_column :application_settings, :koding_url, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/post_migrate/20190404231137_remove_alternate_url_from_geo_nodes.rb b/db/post_migrate/20190404231137_remove_alternate_url_from_geo_nodes.rb
index 785ceb2fb28..8e7ef0ec54f 100644
--- a/db/post_migrate/20190404231137_remove_alternate_url_from_geo_nodes.rb
+++ b/db/post_migrate/20190404231137_remove_alternate_url_from_geo_nodes.rb
@@ -16,6 +16,6 @@ class RemoveAlternateUrlFromGeoNodes < ActiveRecord::Migration[5.0]
end
def down
- add_column :geo_nodes, :alternate_url, :string
+ add_column :geo_nodes, :alternate_url, :string # rubocop:disable Migration/AddLimitToStringColumns
end
end
diff --git a/db/post_migrate/20190625184066_remove_sentry_from_application_settings.rb b/db/post_migrate/20190625184066_remove_sentry_from_application_settings.rb
index 427df343193..9d71bfafffb 100644
--- a/db/post_migrate/20190625184066_remove_sentry_from_application_settings.rb
+++ b/db/post_migrate/20190625184066_remove_sentry_from_application_settings.rb
@@ -32,7 +32,7 @@ class RemoveSentryFromApplicationSettings < ActiveRecord::Migration[5.0]
end
SENTRY_DSN_COLUMNS.each do |column|
- add_column(:application_settings, column, :string) unless column_exists?(:application_settings, column)
+ add_column(:application_settings, column, :string) unless column_exists?(:application_settings, column) # rubocop:disable Migration/AddLimitToStringColumns
end
end
end
diff --git a/db/post_migrate/20190801072937_add_gitlab_instance_administration_project.rb b/db/post_migrate/20190801072937_add_gitlab_instance_administration_project.rb
new file mode 100644
index 00000000000..8b2cf7b3d76
--- /dev/null
+++ b/db/post_migrate/20190801072937_add_gitlab_instance_administration_project.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class AddGitlabInstanceAdministrationProject < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def up
+ Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService.new.execute!
+ end
+
+ def down
+ ApplicationSetting.current_without_cache
+ &.instance_administration_project
+ &.owner
+ &.destroy!
+ end
+end
diff --git a/db/post_migrate/20190801114109_cleanup_allow_local_requests_from_hooks_and_services_application_setting_rename.rb b/db/post_migrate/20190801114109_cleanup_allow_local_requests_from_hooks_and_services_application_setting_rename.rb
index 127e44254ac..cb86f843f9c 100644
--- a/db/post_migrate/20190801114109_cleanup_allow_local_requests_from_hooks_and_services_application_setting_rename.rb
+++ b/db/post_migrate/20190801114109_cleanup_allow_local_requests_from_hooks_and_services_application_setting_rename.rb
@@ -12,6 +12,6 @@ class CleanupAllowLocalRequestsFromHooksAndServicesApplicationSettingRename < Ac
end
def down
- rename_column_concurrently :application_settings, :allow_local_requests_from_web_hooks_and_services, :allow_local_requests_from_hooks_and_services
+ undo_cleanup_concurrent_column_rename :application_settings, :allow_local_requests_from_hooks_and_services, :allow_local_requests_from_web_hooks_and_services
end
end
diff --git a/db/post_migrate/20190809072552_set_self_monitoring_project_alerting_token.rb b/db/post_migrate/20190809072552_set_self_monitoring_project_alerting_token.rb
new file mode 100644
index 00000000000..0c4faebc548
--- /dev/null
+++ b/db/post_migrate/20190809072552_set_self_monitoring_project_alerting_token.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+
+class SetSelfMonitoringProjectAlertingToken < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ module Migratable
+ module Alerting
+ class ProjectAlertingSetting < ApplicationRecord
+ self.table_name = 'project_alerting_settings'
+
+ belongs_to :project
+
+ validates :token, presence: true
+
+ attr_encrypted :token,
+ mode: :per_attribute_iv,
+ key: Settings.attr_encrypted_db_key_base_truncated,
+ algorithm: 'aes-256-gcm'
+
+ before_validation :ensure_token
+
+ private
+
+ def ensure_token
+ self.token ||= generate_token
+ end
+
+ def generate_token
+ SecureRandom.hex
+ end
+ end
+ end
+
+ class Project < ApplicationRecord
+ has_one :alerting_setting, inverse_of: :project, class_name: 'Alerting::ProjectAlertingSetting'
+ end
+
+ class ApplicationSetting < ApplicationRecord
+ self.table_name = 'application_settings'
+
+ belongs_to :instance_administration_project, class_name: 'Project'
+
+ def self.current_without_cache
+ last
+ end
+ end
+ end
+
+ def setup_alertmanager_token(project)
+ return unless License.feature_available?(:prometheus_alerts)
+
+ project.create_alerting_setting!
+ end
+
+ def up
+ Gitlab.ee do
+ project = Migratable::ApplicationSetting.current_without_cache&.instance_administration_project
+
+ if project
+ setup_alertmanager_token(project)
+ end
+ end
+ end
+
+ def down
+ Gitlab.ee do
+ Migratable::ApplicationSetting.current_without_cache
+ &.instance_administration_project
+ &.alerting_setting
+ &.destroy!
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 3f7917654cf..944d23e5365 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -3015,7 +3015,6 @@ ActiveRecord::Schema.define(version: 2019_08_15_093949) do
t.datetime_with_timezone "released_at", null: false
t.index ["author_id"], name: "index_releases_on_author_id"
t.index ["project_id", "tag"], name: "index_releases_on_project_id_and_tag"
- t.index ["project_id"], name: "index_releases_on_project_id"
end
create_table "remote_mirrors", id: :serial, force: :cascade do |t|
diff --git a/doc/administration/monitoring/prometheus/gitlab_metrics.md b/doc/administration/monitoring/prometheus/gitlab_metrics.md
index ec26c0b2e7e..0605fb76e2f 100644
--- a/doc/administration/monitoring/prometheus/gitlab_metrics.md
+++ b/doc/administration/monitoring/prometheus/gitlab_metrics.md
@@ -19,38 +19,106 @@ it, the client IP needs to be [included in a whitelist][whitelist].
For Omnibus and Chart installations, these metrics are automatically enabled and collected as of [GitLab 9.4](https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests/1702). For source installations or earlier versions, these metrics will need to be enabled manually and collected by a Prometheus server.
-## Unicorn Metrics available
+## Metrics available
The following metrics are available:
-| Metric | Type | Since | Description |
-|:--------------------------------- |:--------- |:----- |:----------- |
-| db_ping_timeout | Gauge | 9.4 | Whether or not the last database ping timed out |
-| db_ping_success | Gauge | 9.4 | Whether or not the last database ping succeeded |
-| db_ping_latency_seconds | Gauge | 9.4 | Round trip time of the database ping |
-| filesystem_access_latency_seconds | Gauge | 9.4 | Latency in accessing a specific filesystem |
-| filesystem_accessible | Gauge | 9.4 | Whether or not a specific filesystem is accessible |
-| filesystem_write_latency_seconds | Gauge | 9.4 | Write latency of a specific filesystem |
-| filesystem_writable | Gauge | 9.4 | Whether or not the filesystem is writable |
-| filesystem_read_latency_seconds | Gauge | 9.4 | Read latency of a specific filesystem |
-| filesystem_readable | Gauge | 9.4 | Whether or not the filesystem is readable |
-| gitlab_cache_misses_total | Counter | 10.2 | Cache read miss |
-| gitlab_cache_operation_duration_seconds | Histogram | 10.2 | Cache access time |
-| gitlab_cache_operations_total | Counter | 12.2 | Cache operations by controller/action |
-| http_requests_total | Counter | 9.4 | Rack request count |
-| http_request_duration_seconds | Histogram | 9.4 | HTTP response time from rack middleware |
-| pipelines_created_total | Counter | 9.4 | Counter of pipelines created |
-| rack_uncaught_errors_total | Counter | 9.4 | Rack connections handling uncaught errors count |
-| redis_ping_timeout | Gauge | 9.4 | Whether or not the last redis ping timed out |
-| redis_ping_success | Gauge | 9.4 | Whether or not the last redis ping succeeded |
-| redis_ping_latency_seconds | Gauge | 9.4 | Round trip time of the redis ping |
-| user_session_logins_total | Counter | 9.4 | Counter of how many users have logged in |
-| upload_file_does_not_exist | Counter | 10.7 in EE, 11.5 in CE | Number of times an upload record could not find its file |
-| failed_login_captcha_total | Gauge | 11.0 | Counter of failed CAPTCHA attempts during login |
-| successful_login_captcha_total | Gauge | 11.0 | Counter of successful CAPTCHA attempts during login |
-| unicorn_active_connections | Gauge | 11.0 | The number of active Unicorn connections (workers) |
-| unicorn_queued_connections | Gauge | 11.0 | The number of queued Unicorn connections |
-| unicorn_workers | Gauge | 12.0 | The number of Unicorn workers |
+| Metric | Type | Since | Description | Labels |
+|:-------------------------------------------------------------|:----------|-----------------------:|:----------------------------------------------------------------------------------------------------|:----------------------------------------------------|
+| gitlab_banzai_cached_render_real_duration_seconds | Histogram | 9.4 | Duration of rendering markdown into HTML when cached output exists | controller, action |
+| gitlab_banzai_cacheless_render_real_duration_seconds | Histogram | 9.4 | Duration of rendering markdown into HTML when cached outupt does not exist | controller, action |
+| gitlab_cache_misses_total | Counter | 10.2 | Cache read miss | controller, action |
+| gitlab_cache_operation_duration_seconds | Histogram | 10.2 | Cache access time | |
+| gitlab_cache_operations_total | Counter | 12.2 | Cache operations by controller/action | controller, action, operation |
+| gitlab_database_transaction_seconds | Histogram | 12.1 | Time spent in database transactions, in seconds | |
+| gitlab_method_call_duration_seconds | Histogram | 10.2 | Method calls real duration | controller, action, module, method |
+| gitlab_rails_queue_duration_seconds | Histogram | 9.4 | Measures latency between gitlab-workhorse forwarding a request to Rails | |
+| gitlab_sql_duration_seconds | Histogram | 10.2 | SQL execution time, excluding SCHEMA operations and BEGIN / COMMIT | |
+| gitlab_transaction_allocated_memory_bytes | Histogram | 10.2 | Allocated memory for all transactions (gitlab_transaction_* metrics) | |
+| gitlab_transaction_cache_<key>_count_total | Counter | 10.2 | Counter for total Rails cache calls (per key) | |
+| gitlab_transaction_cache_<key>_duration_total | Counter | 10.2 | Counter for total time (seconds) spent in Rails cache calls (per key) | |
+| gitlab_transaction_cache_count_total | Counter | 10.2 | Counter for total Rails cache calls (aggregate) | |
+| gitlab_transaction_cache_duration_total | Counter | 10.2 | Counter for total time (seconds) spent in Rails cache calls (aggregate) | |
+| gitlab_transaction_cache_read_hit_count_total | Counter | 10.2 | Counter for cache hits for Rails cache calls | controller, action |
+| gitlab_transaction_cache_read_miss_count_total | Counter | 10.2 | Counter for cache misses for Rails cache calls | controller, action |
+| gitlab_transaction_duration_seconds | Histogram | 10.2 | Duration for all transactions (gitlab_transaction_* metrics) | controller, action |
+| gitlab_transaction_event_build_found_total | Counter | 9.4 | Counter for build found for api /jobs/request | |
+| gitlab_transaction_event_build_invalid_total | Counter | 9.4 | Counter for build invalid due to concurrency conflict for api /jobs/request | |
+| gitlab_transaction_event_build_not_found_cached_total | Counter | 9.4 | Counter for cached response of build not found for api /jobs/request | |
+| gitlab_transaction_event_build_not_found_total | Counter | 9.4 | Counter for build not found for api /jobs/request | |
+| gitlab_transaction_event_change_default_branch_total | Counter | 9.4 | Counter when default branch is changed for any repository | |
+| gitlab_transaction_event_create_repository_total | Counter | 9.4 | Counter when any repository is created | |
+| gitlab_transaction_event_etag_caching_cache_hit_total | Counter | 9.4 | Counter for etag cache hit. | endpoint |
+| gitlab_transaction_event_etag_caching_header_missing_total | Counter | 9.4 | Counter for etag cache miss - header missing | endpoint |
+| gitlab_transaction_event_etag_caching_key_not_found_total | Counter | 9.4 | Counter for etag cache miss - key not found | endpoint |
+| gitlab_transaction_event_etag_caching_middleware_used_total | Counter | 9.4 | Counter for etag middleware accessed | endpoint |
+| gitlab_transaction_event_etag_caching_resource_changed_total | Counter | 9.4 | Counter for etag cache miss - resource changed | endpoint |
+| gitlab_transaction_event_fork_repository_total | Counter | 9.4 | Counter for repository forks (RepositoryForkWorker). Only incremented when source repository exists | |
+| gitlab_transaction_event_import_repository_total | Counter | 9.4 | Counter for repository imports (RepositoryImportWorker) | |
+| gitlab_transaction_event_push_branch_total | Counter | 9.4 | Counter for all branch pushes | |
+| gitlab_transaction_event_push_commit_total | Counter | 9.4 | Counter for commits | branch |
+| gitlab_transaction_event_push_tag_total | Counter | 9.4 | Counter for tag pushes | |
+| gitlab_transaction_event_rails_exception_total | Counter | 9.4 | Counter for number of rails exceptions | |
+| gitlab_transaction_event_receive_email_total | Counter | 9.4 | Counter for recieved emails | handler |
+| gitlab_transaction_event_remote_mirrors_failed_total | Counter | 10.8 | Counter for failed remote mirrors | |
+| gitlab_transaction_event_remote_mirrors_finished_total | Counter | 10.8 | Counter for finished remote mirrors | |
+| gitlab_transaction_event_remote_mirrors_running_total | Counter | 10.8 | Counter for running remote mirrors | |
+| gitlab_transaction_event_remove_branch_total | Counter | 9.4 | Counter when a branch is removed for any repository | |
+| gitlab_transaction_event_remove_repository_total | Counter | 9.4 | Counter when a repository is removed | |
+| gitlab_transaction_event_remove_tag_total | Counter | 9.4 | Counter when a tag is remove for any repository | |
+| gitlab_transaction_event_sidekiq_exception_total | Counter | 9.4 | Counter of sidekiq exceptions | |
+| gitlab_transaction_event_stuck_import_jobs_total | Counter | 9.4 | Count of stuck import jobs | projects_without_jid_count, projects_with_jid_count |
+| gitlab_transaction_event_update_build_total | Counter | 9.4 | Counter for update build for api /jobs/request/:id | |
+| gitlab_transaction_new_redis_connections_total | Counter | 9.4 | Counter for new redis connections | |
+| gitlab_transaction_queue_duration_total | Counter | 9.4 | Duration jobs were enqueued before processing | |
+| gitlab_transaction_rails_queue_duration_total | Counter | 9.4 | Measures latency between gitlab-workhorse forwarding a request to Rails | controller, action |
+| gitlab_transaction_view_duration_total | Counter | 9.4 | Duration for views | controller, action, view |
+| gitlab_view_rendering_duration_seconds | Histogram | 10.2 | Duration for views (histogram) | controller, action, view |
+| http_requests_total | Counter | 9.4 | Rack request count | method |
+| http_request_duration_seconds | Histogram | 9.4 | HTTP response time from rack middleware | method, status |
+| pipelines_created_total | Counter | 9.4 | Counter of pipelines created | |
+| rack_uncaught_errors_total | Counter | 9.4 | Rack connections handling uncaught errors count | |
+| user_session_logins_total | Counter | 9.4 | Counter of how many users have logged in | |
+| upload_file_does_not_exist | Counter | 10.7 in EE, 11.5 in CE | Number of times an upload record could not find its file | |
+| failed_login_captcha_total | Gauge | 11.0 | Counter of failed CAPTCHA attempts during login | |
+| successful_login_captcha_total | Gauge | 11.0 | Counter of successful CAPTCHA attempts during login | |
+
+## Metrics controlled by a feature flag
+
+The following metrics can be controlled by feature flags:
+
+| Metric | Feature Flag |
+|:-------------------------------------------------------------|:-----------------------------------------------------------------|
+| gitlab_method_call_duration_seconds | prometheus_metrics_method_instrumentation |
+| gitlab_transaction_allocated_memory_bytes | prometheus_metrics_transaction_allocated_memory |
+| gitlab_transaction_event_build_found_total | prometheus_transaction_event_build_found_total |
+| gitlab_transaction_event_build_invalid_total | prometheus_transaction_event_build_invalid_total |
+| gitlab_transaction_event_build_not_found_cached_total | prometheus_transaction_event_build_not_found_cached_total |
+| gitlab_transaction_event_build_not_found_total | prometheus_transaction_event_build_not_found_total |
+| gitlab_transaction_event_change_default_branch_total | prometheus_transaction_event_change_default_branch_total |
+| gitlab_transaction_event_create_repository_total | prometheus_transaction_event_create_repository_total |
+| gitlab_transaction_event_etag_caching_cache_hit_total | prometheus_transaction_event_etag_caching_cache_hit_total |
+| gitlab_transaction_event_etag_caching_header_missing_total | prometheus_transaction_event_etag_caching_header_missing_total |
+| gitlab_transaction_event_etag_caching_key_not_found_total | prometheus_transaction_event_etag_caching_key_not_found_total |
+| gitlab_transaction_event_etag_caching_middleware_used_total | prometheus_transaction_event_etag_caching_middleware_used_total |
+| gitlab_transaction_event_etag_caching_resource_changed_total | prometheus_transaction_event_etag_caching_resource_changed_total |
+| gitlab_transaction_event_fork_repository_total | prometheus_transaction_event_fork_repository_total |
+| gitlab_transaction_event_import_repository_total | prometheus_transaction_event_import_repository_total |
+| gitlab_transaction_event_push_branch_total | prometheus_transaction_event_push_branch_total |
+| gitlab_transaction_event_push_commit_total | prometheus_transaction_event_push_commit_total |
+| gitlab_transaction_event_push_tag_total | prometheus_transaction_event_push_tag_total |
+| gitlab_transaction_event_rails_exception_total | prometheus_transaction_event_rails_exception_total |
+| gitlab_transaction_event_receive_email_total | prometheus_transaction_event_receive_email_total |
+| gitlab_transaction_event_remote_mirrors_failed_total | prometheus_transaction_event_remote_mirrors_failed_total |
+| gitlab_transaction_event_remote_mirrors_finished_total | prometheus_transaction_event_remote_mirrors_finished_total |
+| gitlab_transaction_event_remote_mirrors_running_total | prometheus_transaction_event_remote_mirrors_running_total |
+| gitlab_transaction_event_remove_branch_total | prometheus_transaction_event_remove_branch_total |
+| gitlab_transaction_event_remove_repository_total | prometheus_transaction_event_remove_repository_total |
+| gitlab_transaction_event_remove_tag_total | prometheus_transaction_event_remove_tag_total |
+| gitlab_transaction_event_sidekiq_exception_total | prometheus_transaction_event_sidekiq_exception_total |
+| gitlab_transaction_event_stuck_import_jobs_total | prometheus_transaction_event_stuck_import_jobs_total |
+| gitlab_transaction_event_update_build_total | prometheus_transaction_event_update_build_total |
+| gitlab_view_rendering_duration_seconds | prometheus_metrics_view_instrumentation |
## Sidekiq Metrics available for Geo **(PREMIUM)**
@@ -99,17 +167,27 @@ Some basic Ruby runtime metrics are available:
| Metric | Type | Since | Description |
|:-------------------------------------- |:--------- |:----- |:----------- |
-| ruby_gc_duration_seconds_total | Counter | 11.1 | Time spent by Ruby in GC |
+| ruby_gc_duration_seconds | Counter | 11.1 | Time spent by Ruby in GC |
| ruby_gc_stat_... | Gauge | 11.1 | Various metrics from [GC.stat] |
| ruby_file_descriptors | Gauge | 11.1 | File descriptors per process |
| ruby_memory_bytes | Gauge | 11.1 | Memory usage by process |
-| ruby_sampler_duration_seconds_total | Counter | 11.1 | Time spent collecting stats |
+| ruby_sampler_duration_seconds | Counter | 11.1 | Time spent collecting stats |
| ruby_process_cpu_seconds_total | Gauge | 12.0 | Total amount of CPU time per process |
| ruby_process_max_fds | Gauge | 12.0 | Maximum number of open file descriptors per process |
| ruby_process_resident_memory_bytes | Gauge | 12.0 | Memory usage by process, measured in bytes |
| ruby_process_start_time_seconds | Gauge | 12.0 | UNIX timestamp of process start time |
-[GC.stat]: https://ruby-doc.org/core-2.3.0/GC.html#method-c-stat
+[GC.stat]: https://ruby-doc.org/core-2.6.3/GC.html#method-c-stat
+
+## Unicorn Metrics
+
+Unicorn specific metrics, when Unicorn is used.
+
+| Metric | Type | Since | Description |
+|:---------------------------|:------|:------|:---------------------------------------------------|
+| unicorn_active_connections | Gauge | 11.0 | The number of active Unicorn connections (workers) |
+| unicorn_queued_connections | Gauge | 11.0 | The number of queued Unicorn connections |
+| unicorn_workers | Gauge | 12.0 | The number of Unicorn workers |
## Puma Metrics **(EXPERIMENTAL)**
@@ -126,7 +204,6 @@ When Puma is used instead of Unicorn, following metrics are available:
| puma_pool_capacity | Gauge | 12.0 | Number of requests the worker is capable of taking right now |
| puma_max_threads | Gauge | 12.0 | Maximum number of worker threads |
| puma_idle_threads | Gauge | 12.0 | Number of spawned threads which are not processing a request |
-| rack_state_total | Gauge | 12.0 | Number of requests in a given rack state |
| puma_killer_terminations_total | Gauge | 12.0 | Number of workers terminated by PumaWorkerKiller |
## Metrics shared directory
diff --git a/doc/api/dependencies.md b/doc/api/dependencies.md
index 5767d3572dd..5296d4e316f 100644
--- a/doc/api/dependencies.md
+++ b/doc/api/dependencies.md
@@ -5,7 +5,8 @@ This API is in an alpha stage and considered unstable.
The response payload may be subject to change or breakage
across GitLab releases.
-Every call to this endpoint requires authentication. To perform this call, user should be authorized to read
+Every call to this endpoint requires authentication. To perform this call, user should be authorized to read repository.
+To see vulnerabilities in response, user should be authorized to read
[Project Security Dashboard](../user/application_security/security_dashboard/index.md#project-security-dashboard).
## List project dependencies
@@ -17,8 +18,8 @@ supported by Gemnasium.
```
GET /projects/:id/dependencies
-GET /projects/:id/vulnerabilities?package_manager=maven
-GET /projects/:id/vulnerabilities?package_manager=yarn,bundler
+GET /projects/:id/dependencies?package_manager=maven
+GET /projects/:id/dependencies?package_manager=yarn,bundler
```
| Attribute | Type | Required | Description |
@@ -38,13 +39,18 @@ Example response:
"name": "rails",
"version": "5.0.1",
"package_manager": "bundler",
- "dependency_file_path": "Gemfile.lock"
+ "dependency_file_path": "Gemfile.lock",
+ "vulnerabilities": [{
+ "name": "DDoS",
+ "severity": "unknown"
+ }]
},
{
"name": "hanami",
"version": "1.3.1",
"package_manager": "bundler",
- "dependency_file_path": "Gemfile.lock"
+ "dependency_file_path": "Gemfile.lock",
+ "vulnerabilities": []
}
]
```
diff --git a/doc/api/issues.md b/doc/api/issues.md
index 4f2b4a966c9..8313dd2c3bd 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -49,7 +49,7 @@ GET /issues?confidential=true
| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. _([Introduced][ce-14016] in GitLab 10.0)_ |
| `weight` **(STARTER)** | integer | no | Return issues with the specified `weight`. `None` returns issues with no weight assigned. `Any` returns issues with a weight assigned. |
| `iids[]` | integer array | no | Return only the issues having the given `iid` |
-| `order_by` | string | no | Return issues ordered by `created_at` or `updated_at` fields. Default is `created_at` |
+| `order_by` | string | no | Return issues ordered by `created_at`, `updated_at`, `priority`, `due_date`, `relative_position`, `label_priority`, `milestone_due`, `popularity`, `weight` fields. Default is `created_at` |
| `sort` | string | no | Return issues sorted in `asc` or `desc` order. Default is `desc` |
| `search` | string | no | Search issues against their `title` and `description` |
| `in` | string | no | Modify the scope of the `search` attribute. `title`, `description`, or a string joining them with comma. Default is `title,description` |
@@ -198,7 +198,7 @@ GET /groups/:id/issues?confidential=true
| `assignee_username` | string array | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In CE version `assignee_username` array should only contain a single value or an invalid param error will be returned otherwise. |
| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. _([Introduced][ce-14016] in GitLab 10.0)_ |
| `weight` **(STARTER)** | integer | no | Return issues with the specified `weight`. `None` returns issues with no weight assigned. `Any` returns issues with a weight assigned. |
-| `order_by` | string | no | Return issues ordered by `created_at` or `updated_at` fields. Default is `created_at` |
+| `order_by` | string | no | Return issues ordered by `created_at`, `updated_at`, `priority`, `due_date`, `relative_position`, `label_priority`, `milestone_due`, `popularity`, `weight` fields. Default is `created_at` |
| `sort` | string | no | Return issues sorted in `asc` or `desc` order. Default is `desc` |
| `search` | string | no | Search group issues against their `title` and `description` |
| `created_after` | datetime | no | Return issues created on or after the given time |
@@ -347,7 +347,7 @@ GET /projects/:id/issues?confidential=true
| `assignee_username` | string array | no | Return issues assigned to the given `username`. Similar to `assignee_id` and mutually exclusive with `assignee_id`. In CE version `assignee_username` array should only contain a single value or an invalid param error will be returned otherwise. |
| `my_reaction_emoji` | string | no | Return issues reacted by the authenticated user by the given `emoji`. `None` returns issues not given a reaction. `Any` returns issues given at least one reaction. _([Introduced][ce-14016] in GitLab 10.0)_ |
| `weight` **(STARTER)** | integer | no | Return issues with the specified `weight`. `None` returns issues with no weight assigned. `Any` returns issues with a weight assigned. |
-| `order_by` | string | no | Return issues ordered by `created_at` or `updated_at` fields. Default is `created_at` |
+| `order_by` | string | no | Return issues ordered by `created_at`, `updated_at`, `priority`, `due_date`, `relative_position`, `label_priority`, `milestone_due`, `popularity`, `weight` fields. Default is `created_at` |
| `sort` | string | no | Return issues sorted in `asc` or `desc` order. Default is `desc` |
| `search` | string | no | Search project issues against their `title` and `description` |
| `created_after` | datetime | no | Return issues created on or after the given time |
diff --git a/doc/api/labels.md b/doc/api/labels.md
index 5db0edcf14d..fde1d861cf6 100644
--- a/doc/api/labels.md
+++ b/doc/api/labels.md
@@ -137,8 +137,9 @@ DELETE /projects/:id/labels
| Attribute | Type | Required | Description |
| --------- | ------- | -------- | --------------------- |
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
-| `name` | string | yes | The name of the label |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
+| `label_id` | integer | yes (or `name`) | The id of the existing label |
+| `name` | string | yes (or `label_id`) | The name of the existing label |
```bash
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/labels?name=bug"
@@ -156,7 +157,8 @@ PUT /projects/:id/labels
| Attribute | Type | Required | Description |
| --------------- | ------- | --------------------------------- | ------------------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
-| `name` | string | yes | The name of the existing label |
+| `label_id` | integer | yes (or `name`) | The id of the existing label |
+| `name` | string | yes (or `label_id`) | The name of the existing label |
| `new_name` | string | yes if `color` is not provided | The new name of the label |
| `color` | string | yes if `new_name` is not provided | The color of the label given in 6-digit hex notation with leading '#' sign (e.g. #FFAABB) or one of the [CSS color names](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords) |
| `description` | string | no | The new description of the label |
diff --git a/doc/development/README.md b/doc/development/README.md
index 5e35d4c7437..3912a828dec 100644
--- a/doc/development/README.md
+++ b/doc/development/README.md
@@ -65,6 +65,7 @@ description: 'Learn how to contribute to GitLab.'
- [Repository mirroring](repository_mirroring.md)
- [Git LFS](lfs.md)
- [Developing against interacting components or features](interacting_components.md)
+- [File uploads](uploads.md)
## Performance guides
diff --git a/doc/development/documentation/feature-change-workflow.md b/doc/development/documentation/feature-change-workflow.md
index ac93ada5a4b..00c76fe0f1b 100644
--- a/doc/development/documentation/feature-change-workflow.md
+++ b/doc/development/documentation/feature-change-workflow.md
@@ -69,7 +69,7 @@ To follow a consistent workflow every month, documentation changes
involve the Product Managers, the developer who shipped the feature,
and the technical writer for the DevOps stage. Each role is described below.
-The Documentation items in the GitLab CE/EE [Feature Proposal issue template](https://gitlab.com/gitlab-org/gitlab-ce/raw/template-improvements-for-documentation/.gitlab/issue_templates/Feature%20proposal.md)
+The Documentation items in the GitLab CE/EE [Feature Proposal issue template](https://gitlab.com/gitlab-org/gitlab-ce/raw/master/.gitlab/issue_templates/Feature%20proposal.md)
and default merge request template will assist you with following this process.
### Product Manager role
diff --git a/doc/development/file_storage.md b/doc/development/file_storage.md
index 475d1c1611e..44af2b020a4 100644
--- a/doc/development/file_storage.md
+++ b/doc/development/file_storage.md
@@ -2,6 +2,8 @@
We use the [CarrierWave] gem to handle file upload, store and retrieval.
+File uploads should be accelerated by workhorse, for details please refer to [uploads development documentation](uploads.md).
+
There are many places where file uploading is used, according to contexts:
- System
diff --git a/doc/development/uploads.md b/doc/development/uploads.md
new file mode 100644
index 00000000000..234539bb673
--- /dev/null
+++ b/doc/development/uploads.md
@@ -0,0 +1,271 @@
+# Uploads development documentation
+
+[GitLab Workhorse](https://gitlab.com/gitlab-org/gitlab-workhorse) has special rules for handling uploads.
+To prevent occupying a ruby process on I/O operations, we process the upload in workhorse, where is cheaper.
+This process can also directly upload to object storage.
+
+## The problem description
+
+The following graph explains machine boundaries in a scalable GitLab installation. Without any workhorse optimization in place, we can expect incoming requests to follow the numbers on the arrows.
+
+```mermaid
+graph TB
+ subgraph "load balancers"
+ LB(HA Proxy)
+ end
+
+ subgraph "Shared storage"
+ nfs(NFS)
+ end
+
+ subgraph "redis cluster"
+ r(persisted redis)
+ end
+ LB-- 1 -->workhorse
+
+ subgraph "web or API fleet"
+ workhorse-- 2 -->rails
+ end
+ rails-- "3 (write files)" -->nfs
+ rails-- "4 (schedule a job)" -->r
+
+ subgraph sidekiq
+ s(sidekiq)
+ end
+ s-- "5 (fetch a job)" -->r
+ s-- "6 (read files)" -->nfs
+```
+
+We have three challenges here: performance, availability, and scalability.
+
+### Performance
+
+Rails process are expensive in terms of both CPU and memory. Ruby [global interpreter lock](https://en.wikipedia.org/wiki/Global_interpreter_lock) adds to cost too because the ruby process will spend time on I/O operations on step 3 causing incoming requests to pile up.
+
+In order to improve this, [workhorse disk acceleration](#workhorse-disk-acceleration) was implemented. With this, Rails no longer deals with writing uploaded files to disk.
+
+```mermaid
+graph TB
+ subgraph "load balancers"
+ LB(HA Proxy)
+ end
+
+ subgraph "Shared storage"
+ nfs(NFS)
+ end
+
+ subgraph "redis cluster"
+ r(persisted redis)
+ end
+ LB-- 1 -->workhorse
+
+ subgraph "web or API fleet"
+ workhorse-- "3 (without files)" -->rails
+ end
+ workhorse -- "2 (write files)" -->nfs
+ rails-- "4 (schedule a job)" -->r
+
+ subgraph sidekiq
+ s(sidekiq)
+ end
+ s-- "5 (fetch a job)" -->r
+ s-- "6 (read files)" -->nfs
+```
+
+### Availability
+
+There's also an availability problem in this setup, NFS is a [single point of failure](https://en.wikipedia.org/wiki/Single_point_of_failure).
+
+To address this problem an HA object storage can be used and it's supported by [workhorse object storage acceleration](#workhorse-object-storage-acceleration)
+
+### Scalability
+
+Scaling NFS is outside of our support scope, and NFS is not a part of cloud native installations.
+
+All features that require sidekiq and do not use object storage acceleration won't work without NFS. In Kubernetes, machine boundaries translate to PODs, and in this case the uploaded file will be written into the POD private disk. Since sidekiq POD cannot reach into other pods, the operation will fail to read it.
+
+## How to select the proper level of acceleration?
+
+Selecting the proper acceleration is a tradeoff between speed of development and operational costs.
+
+We can identify three major use-cases for an upload:
+
+1. **storage:** if we are uploading for storing a file (i.e. artifacts, packages, discussion attachments). In this case [object storage acceleration](#workhorse-object-storage-acceleration) is the proper level as it's the less resource-intensive operation. Additional information can be found on [File Storage in GitLab](file_storage.md).
+1. **in-controller/synchronous processing:** if we allow processing **small files** synchronously, using [disk acceleration](#workhorse-disk-acceleration) may speed up development.
+1. **sidekiq/asynchronous processing:** Async processing must implement [object storage acceleration](#workhorse-object-storage-acceleration), the reason being that it's the only way to support Cloud Native deployments without a shared NFS.
+
+For more details about currently broken feature see [epic &1802](https://gitlab.com/groups/gitlab-org/-/epics/1802).
+
+### Handling repository uploads
+
+Some features involves git repository uploads without using a regular git client.
+Some examples are uploading a repository file from the web interface and [design management](../user/project/issues/design_management.md).
+
+Those uploads requires the rails controller to act as a git client in lieu of the user.
+Those operation falls into _in-controller/synchronous processing_ category, but we have no warranties on the file size.
+
+In case of a LFS upload, the file pointer is committed synchronously, but file upload to object storage is performed asynchronously with sidekiq.
+
+## Upload encodings
+
+By upload encoding we mean how the file is included within the incoming request.
+
+We have three kinds of file encoding in our uploads:
+
+1. <i class="fa fa-check-circle"></i> **multipart**: `multipart/form-data` is the most common, a file is encoded as a part of a multipart encoded request.
+1. <i class="fa fa-check-circle"></i> **body**: some APIs uploads files as the whole request body.
+1. <i class="fa fa-times-circle"></i> **JSON**: some JSON API uploads files as base64 encoded strings. This requires [gitlab-workhorse#226](https://gitlab.com/gitlab-org/gitlab-workhorse/issues/226) to be implemented.
+
+## Uploading technologies
+
+By uploading technologies we mean how all the involved services interact with each other.
+
+GitLab supports 3 kinds of uploading technologies, here follows a brief description with a sequence diagram for each one. Diagrams are not meant to be exhaustive.
+
+### Regular rails upload
+
+This is the default kind of upload, and it's most expensive in terms of resources.
+
+In this case, workhorse is unaware of files being uploaded and acts as a regular proxy.
+
+When a multipart request reaches the rails application, `Rack::Multipart` leaves behind tempfiles in `/tmp` and uses valuable Ruby process time to copy files around.
+
+```mermaid
+sequenceDiagram
+ participant c as Client
+ participant w as Workhorse
+ participant r as Rails
+
+ activate c
+ c ->>+w: POST /some/url/upload
+ w->>+r: POST /some/url/upload
+
+ r->>r: save the incoming file on /tmp
+ r->>r: read the file for processing
+
+ r-->>-c: request result
+ deactivate c
+ deactivate w
+```
+
+### Workhorse disk acceleration
+
+This kind of upload avoids wasting resources caused by handling upload writes to `/tmp` in rails.
+
+This optimization is not active by default on REST API requests.
+
+When enabled, Workhorse looks for files in multipart MIME requests, uploading
+any it finds to a temporary file on shared storage. The MIME data in the request
+is replaced with the path to the corresponding file before it is forwarded to
+Rails.
+
+To prevent abuse of this feature, Workhorse signs the modified request with a
+special header, stating which entries it modified. Rails will ignore any
+unsigned path entries.
+
+```mermaid
+sequenceDiagram
+ participant c as Client
+ participant w as Workhorse
+ participant r as Rails
+ participant s as NFS
+
+ activate c
+ c ->>+w: POST /some/url/upload
+
+ w->>+s: save the incoming file on a temporary location
+ s-->>-w:
+
+ w->>+r: POST /some/url/upload
+ Note over w,r: file was replaced with its location<br>and other metadata
+
+ opt requires async processing
+ r->>+redis: schedule a job
+ redis-->>-r:
+ end
+
+ r-->>-c: request result
+ deactivate c
+ w->>-w: cleanup
+
+ opt requires async processing
+ activate sidekiq
+ sidekiq->>+redis: fetch a job
+ redis-->>-sidekiq: job
+
+ sidekiq->>+s: read file
+ s-->>-sidekiq: file
+
+ sidekiq->>sidekiq: process file
+
+ deactivate sidekiq
+ end
+```
+
+### Workhorse object storage acceleration
+
+This is the more advanced acceleration technique we have in place.
+
+Workhorse asks rails for temporary pre-signed object storage URLs and directly uploads to object storage.
+
+In this setup an extra rails route needs to be implemented in order to handle authorization,
+you can see an example of this in [`Projects::LfsStorageController`](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/controllers/projects/lfs_storage_controller.rb)
+and [its routes](https://gitlab.com/gitlab-org/gitlab-ce/blob/v12.2.0/config/routes/git_http.rb#L31-32).
+
+**note:** this will fallback to _Workhorse disk acceleration_ when object storage is not enabled in the gitlab instance. The answer to the `/authorize` call will only contain a file system path.
+
+```mermaid
+sequenceDiagram
+ participant c as Client
+ participant w as Workhorse
+ participant r as Rails
+ participant os as Object Storage
+
+ activate c
+ c ->>+w: POST /some/url/upload
+
+ w ->>+r: POST /some/url/upload/authorize
+ Note over w,r: this request has an empty body
+ r-->>-w: presigned OS URL
+
+ w->>+os: PUT file
+ Note over w,os: file is stored on a temporary location. Rails select the destination
+ os-->>-w:
+
+ w->>+r: POST /some/url/upload
+ Note over w,r: file was replaced with its location<br>and other metadata
+
+ r->>+os: move object to final destination
+ os-->>-r:
+
+ opt requires async processing
+ r->>+redis: schedule a job
+ redis-->>-r:
+ end
+
+ r-->>-c: request result
+ deactivate c
+ w->>-w: cleanup
+
+ opt requires async processing
+ activate sidekiq
+ sidekiq->>+redis: fetch a job
+ redis-->>-sidekiq: job
+
+ sidekiq->>+os: get object
+ os-->>-sidekiq: file
+
+ sidekiq->>sidekiq: process file
+
+ deactivate sidekiq
+ end
+```
+
+## What does the `direct_upload` setting mean?
+
+[Object storage setting](../administration/uploads.md#object-storage-settings) allows instance administators to enable `direct_upload`, this in an option that only affects the behavior of [workhorse object storage acceleration](#workhorse-object-storage-acceleration).
+
+This option affect the response to the `/authorize` call. When not enabled, the API response will not contain presigned URLs and workhorse will write the file the shared disk, on the path is provided by rails, acting like object storage was disabled.
+
+Once the request reachs rails, it will schedule an object storage upload as a sidekiq job.
+
diff --git a/doc/user/admin_area/monitoring/health_check.md b/doc/user/admin_area/monitoring/health_check.md
index 333d2fb42b3..a3f4bc774ce 100644
--- a/doc/user/admin_area/monitoring/health_check.md
+++ b/doc/user/admin_area/monitoring/health_check.md
@@ -21,28 +21,71 @@ traffic until the system is ready or restart the container as needed.
To access monitoring resources, the requesting client IP needs to be included in a whitelist.
For details, see [how to add IPs to a whitelist for the monitoring endpoints](../../../administration/monitoring/ip_whitelist.md).
-## Using the endpoints
+## Using the endpoints locally
With default whitelist settings, the probes can be accessed from localhost using the following URLs:
-- `http://localhost/-/health`
-- `http://localhost/-/readiness`
-- `http://localhost/-/liveness`
+```text
+GET http://localhost/-/health
+```
+```text
+GET http://localhost/-/readiness
+```
+```text
+GET http://localhost/-/liveness
+```text
+GET http://localhost/-/health
+```
+
+```text
+GET http://localhost/-/readiness
+```
-The first endpoint, `health`, only checks whether the application server is running. It does not verify the database or other services are running. A successful response will return a 200 status code with the following message:
+```text
+GET http://localhost/-/liveness
+```
+
+## Health
+
+Checks whether the application server is running. It does not verify the database or other services are running.
+
+```text
+GET /-/health
+```
+
+Example request:
+
+```sh
+curl 'https://gitlab.example.com/-/health'
+```
+
+Example response:
```text
GitLab OK
```
-The readiness and liveness probes will provide a report of system health in JSON format.
+## Readiness
+
+The readiness probe checks whether the Gitlab instance is ready to use. It checks the dependent services (Database, Redis, Gitaly etc.) and gives a status for each.
+
+```text
+GET /-/readiness
+```
+
+Example request:
+
+```sh
+curl 'https://gitlab.example.com/-/readiness'
+```
-`readiness` probe example output:
+Example response:
```json
{
"db_check":{
- "status":"ok"
+ "status":"failed",
+ "message": "unexpected Db check result: 0"
},
"redis_check":{
"status":"ok"
@@ -65,7 +108,23 @@ The readiness and liveness probes will provide a report of system health in JSON
}
```
-`liveness` probe example output:
+## Liveness
+
+The liveness probe checks whether the application server is alive. Unlike the [`health`](#health) check, this check hits the database.
+
+```text
+GET /-/liveness
+```
+
+Example request:
+
+```sh
+curl 'https://gitlab.example.com/-/liveness'
+```
+
+Example response:
+
+On success, the endpoint will return a valid successful HTTP status code, and a response like below.
```json
{
@@ -90,10 +149,7 @@ The readiness and liveness probes will provide a report of system health in JSON
}
```
-## Status
-
-On failure, the endpoint will return a `500` HTTP status code. On success, the endpoint
-will return a valid successful HTTP status code, and a `success` message.
+On failure, the endpoint will return a `500` HTTP status code.
## Access token (Deprecated)
diff --git a/lib/api/helpers/issues_helpers.rb b/lib/api/helpers/issues_helpers.rb
index 5b7199fddb0..a8480bb9339 100644
--- a/lib/api/helpers/issues_helpers.rb
+++ b/lib/api/helpers/issues_helpers.rb
@@ -27,6 +27,10 @@ module API
]
end
+ def self.sort_options
+ %w[created_at updated_at priority due_date relative_position label_priority milestone_due popularity]
+ end
+
def issue_finder(args = {})
args = declared_params.merge(args)
@@ -34,15 +38,14 @@ module API
args[:milestone_title] ||= args.delete(:milestone)
args[:label_name] ||= args.delete(:labels)
args[:scope] = args[:scope].underscore if args[:scope]
+ args[:sort] = "#{args[:order_by]}_#{args[:sort]}"
IssuesFinder.new(current_user, args)
end
def find_issues(args = {})
finder = issue_finder(args)
- issues = finder.execute.with_api_entity_associations
-
- issues.reorder(order_options_with_tie_breaker) # rubocop: disable CodeReuse/ActiveRecord
+ finder.execute.with_api_entity_associations
end
def issues_statistics(args = {})
diff --git a/lib/api/helpers/label_helpers.rb b/lib/api/helpers/label_helpers.rb
index 896b0aba52b..ec5b688dd1c 100644
--- a/lib/api/helpers/label_helpers.rb
+++ b/lib/api/helpers/label_helpers.rb
@@ -11,9 +11,9 @@ module API
optional :description, type: String, desc: 'The description of label to be created'
end
- def find_label(parent, id, include_ancestor_groups: true)
+ def find_label(parent, id_or_title, include_ancestor_groups: true)
labels = available_labels_for(parent, include_ancestor_groups: include_ancestor_groups)
- label = labels.find_by_id(id) || labels.find_by_title(id)
+ label = labels.find_by_id(id_or_title) || labels.find_by_title(id_or_title)
label || not_found!('Label')
end
@@ -35,12 +35,7 @@ module API
priority = params.delete(:priority)
label_params = declared_params(include_missing: false)
- label =
- if parent.is_a?(Project)
- ::Labels::CreateService.new(label_params).execute(project: parent)
- else
- ::Labels::CreateService.new(label_params).execute(group: parent)
- end
+ label = ::Labels::CreateService.new(label_params).execute(create_service_params(parent))
if label.persisted?
if parent.is_a?(Project)
@@ -56,10 +51,13 @@ module API
def update_label(parent, entity)
authorize! :admin_label, parent
- label = find_label(parent, params[:name], include_ancestor_groups: false)
+ label = find_label(parent, params_id_or_title, include_ancestor_groups: false)
update_priority = params.key?(:priority)
priority = params.delete(:priority)
+ # params is used to update the label so we need to remove this field here
+ params.delete(:label_id)
+
label = ::Labels::UpdateService.new(declared_params(include_missing: false)).execute(label)
render_validation_error!(label) unless label.valid?
@@ -77,10 +75,24 @@ module API
def delete_label(parent)
authorize! :admin_label, parent
- label = find_label(parent, params[:name], include_ancestor_groups: false)
+ label = find_label(parent, params_id_or_title, include_ancestor_groups: false)
destroy_conditionally!(label)
end
+
+ def params_id_or_title
+ @params_id_or_title ||= params[:label_id] || params[:name]
+ end
+
+ def create_service_params(parent)
+ if parent.is_a?(Project)
+ { project: parent }
+ elsif parent.is_a?(Group)
+ { group: parent }
+ else
+ raise TypeError, 'Parent type is not supported'
+ end
+ end
end
end
end
diff --git a/lib/api/helpers/notes_helpers.rb b/lib/api/helpers/notes_helpers.rb
index 6bf9057fad7..b2bf6bf7417 100644
--- a/lib/api/helpers/notes_helpers.rb
+++ b/lib/api/helpers/notes_helpers.rb
@@ -3,6 +3,8 @@
module API
module Helpers
module NotesHelpers
+ include ::RendersNotes
+
def self.noteable_types
# This is a method instead of a constant, allowing EE to more easily
# extend it.
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index 7819c2de515..e16eeef202c 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -44,7 +44,7 @@ module API
optional :with_labels_details, type: Boolean, desc: 'Return more label data than just lable title', default: false
optional :state, type: String, values: %w[opened closed all], default: 'all',
desc: 'Return opened, closed, or all issues'
- optional :order_by, type: String, values: %w[created_at updated_at], default: 'created_at',
+ optional :order_by, type: String, values: Helpers::IssuesHelpers.sort_options, default: 'created_at',
desc: 'Return issues ordered by `created_at` or `updated_at` fields.'
optional :sort, type: String, values: %w[asc desc], default: 'desc',
desc: 'Return issues sorted in `asc` or `desc` order.'
diff --git a/lib/api/labels.rb b/lib/api/labels.rb
index c183198d3c6..83d645ca07a 100644
--- a/lib/api/labels.rb
+++ b/lib/api/labels.rb
@@ -38,11 +38,13 @@ module API
success Entities::ProjectLabel
end
params do
- requires :name, type: String, desc: 'The name of the label to be updated'
+ optional :label_id, type: Integer, desc: 'The id of the label to be updated'
+ optional :name, type: String, desc: 'The name of the label to be updated'
optional :new_name, type: String, desc: 'The new name of the label'
optional :color, type: String, desc: "The new color of the label given in 6-digit hex notation with leading '#' sign (e.g. #FFAABB) or one of the allowed CSS color names"
optional :description, type: String, desc: 'The new description of label'
optional :priority, type: Integer, desc: 'The priority of the label', allow_blank: true
+ exactly_one_of :label_id, :name
at_least_one_of :new_name, :color, :description, :priority
end
put ':id/labels' do
@@ -53,7 +55,9 @@ module API
success Entities::ProjectLabel
end
params do
- requires :name, type: String, desc: 'The name of the label to be deleted'
+ optional :label_id, type: Integer, desc: 'The id of the label to be deleted'
+ optional :name, type: String, desc: 'The name of the label to be deleted'
+ exactly_one_of :label_id, :name
end
delete ':id/labels' do
delete_label(user_project)
diff --git a/lib/api/notes.rb b/lib/api/notes.rb
index 9381f045144..84563d66ee8 100644
--- a/lib/api/notes.rb
+++ b/lib/api/notes.rb
@@ -36,12 +36,13 @@ module API
# page can have less elements than :per_page even if
# there's more than one page.
raw_notes = noteable.notes.with_metadata.reorder(order_options_with_tie_breaker)
- notes =
- # paginate() only works with a relation. This could lead to a
- # mismatch between the pagination headers info and the actual notes
- # array returned, but this is really a edge-case.
- paginate(raw_notes)
- .reject { |n| n.cross_reference_not_visible_for?(current_user) }
+
+ # paginate() only works with a relation. This could lead to a
+ # mismatch between the pagination headers info and the actual notes
+ # array returned, but this is really a edge-case.
+ notes = paginate(raw_notes)
+ notes = prepare_notes_for_rendering(notes)
+ notes = notes.reject { |n| n.cross_reference_not_visible_for?(current_user) }
present notes, with: Entities::Note
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/lib/api/pipelines.rb b/lib/api/pipelines.rb
index 667bf1ec801..9e888368e7b 100644
--- a/lib/api/pipelines.rb
+++ b/lib/api/pipelines.rb
@@ -4,7 +4,7 @@ module API
class Pipelines < Grape::API
include PaginationParams
- before { authenticate! }
+ before { authenticate_non_get! }
params do
requires :id, type: String, desc: 'The project ID'
@@ -32,6 +32,7 @@ module API
end
get ':id/pipelines' do
authorize! :read_pipeline, user_project
+ authorize! :read_build, user_project
pipelines = PipelinesFinder.new(user_project, current_user, params).execute
present paginate(pipelines), with: Entities::PipelineBasic
diff --git a/lib/feature/gitaly.rb b/lib/feature/gitaly.rb
index be397a478cd..656becbffd3 100644
--- a/lib/feature/gitaly.rb
+++ b/lib/feature/gitaly.rb
@@ -10,6 +10,7 @@ class Feature
get_commit_signatures
cache_invalidator
inforef_uploadpack_cache
+ get_all_lfs_pointers_go
].freeze
DEFAULT_ON_FLAGS = Set.new([]).freeze
diff --git a/lib/gitlab/analytics/cycle_analytics/default_stages.rb b/lib/gitlab/analytics/cycle_analytics/default_stages.rb
new file mode 100644
index 00000000000..286c393005f
--- /dev/null
+++ b/lib/gitlab/analytics/cycle_analytics/default_stages.rb
@@ -0,0 +1,98 @@
+# frozen_string_literal: true
+
+# This module represents the default Cycle Analytics stages that are currently provided by CE
+# Each method returns a hash that can be used to build a new stage object.
+#
+# Example:
+#
+# params = Gitlab::Analytics::CycleAnalytics::DefaultStages.params_for_issue_stage
+# Analytics::CycleAnalytics::ProjectStage.new(params)
+module Gitlab
+ module Analytics
+ module CycleAnalytics
+ module DefaultStages
+ def self.all
+ [
+ params_for_issue_stage,
+ params_for_plan_stage,
+ params_for_code_stage,
+ params_for_test_stage,
+ params_for_review_stage,
+ params_for_staging_stage,
+ params_for_production_stage
+ ]
+ end
+
+ def self.params_for_issue_stage
+ {
+ name: 'issue',
+ custom: false, # this stage won't be customizable, we provide it as it is
+ relative_position: 1, # when opening the CycleAnalytics page in CE, this stage will be the first item
+ start_event_identifier: :issue_created, # IssueCreated class is used as start event
+ end_event_identifier: :issue_stage_end # IssueStageEnd class is used as end event
+ }
+ end
+
+ def self.params_for_plan_stage
+ {
+ name: 'plan',
+ custom: false,
+ relative_position: 2,
+ start_event_identifier: :plan_stage_start,
+ end_event_identifier: :issue_first_mentioned_in_commit
+ }
+ end
+
+ def self.params_for_code_stage
+ {
+ name: 'code',
+ custom: false,
+ relative_position: 3,
+ start_event_identifier: :code_stage_start,
+ end_event_identifier: :merge_request_created
+ }
+ end
+
+ def self.params_for_test_stage
+ {
+ name: 'test',
+ custom: false,
+ relative_position: 4,
+ start_event_identifier: :merge_request_last_build_started,
+ end_event_identifier: :merge_request_last_build_finished
+ }
+ end
+
+ def self.params_for_review_stage
+ {
+ name: 'review',
+ custom: false,
+ relative_position: 5,
+ start_event_identifier: :merge_request_created,
+ end_event_identifier: :merge_request_merged
+ }
+ end
+
+ def self.params_for_staging_stage
+ {
+ name: 'staging',
+ custom: false,
+ relative_position: 6,
+ start_event_identifier: :merge_request_merged,
+ end_event_identifier: :merge_request_first_deployed_to_production
+ }
+ end
+
+ def self.params_for_production_stage
+ {
+ name: 'production',
+ custom: false,
+ relative_position: 7,
+ start_event_identifier: :merge_request_merged,
+ end_event_identifier: :merge_request_first_deployed_to_production
+ }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/analytics/cycle_analytics/stage_events.rb b/lib/gitlab/analytics/cycle_analytics/stage_events.rb
new file mode 100644
index 00000000000..d21f344f483
--- /dev/null
+++ b/lib/gitlab/analytics/cycle_analytics/stage_events.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Analytics
+ module CycleAnalytics
+ module StageEvents
+ # Convention:
+ # Issue: < 100
+ # MergeRequest: >= 100 && < 1000
+ # Custom events for default stages: >= 1000 (legacy)
+ ENUM_MAPPING = {
+ StageEvents::IssueCreated => 1,
+ StageEvents::IssueFirstMentionedInCommit => 2,
+ StageEvents::MergeRequestCreated => 100,
+ StageEvents::MergeRequestFirstDeployedToProduction => 101,
+ StageEvents::MergeRequestLastBuildFinished => 102,
+ StageEvents::MergeRequestLastBuildStarted => 103,
+ StageEvents::MergeRequestMerged => 104,
+ StageEvents::CodeStageStart => 1_000,
+ StageEvents::IssueStageEnd => 1_001,
+ StageEvents::PlanStageStart => 1_002
+ }.freeze
+
+ EVENTS = ENUM_MAPPING.keys.freeze
+
+ # Defines which start_event and end_event pairs are allowed
+ PAIRING_RULES = {
+ StageEvents::PlanStageStart => [
+ StageEvents::IssueFirstMentionedInCommit
+ ],
+ StageEvents::CodeStageStart => [
+ StageEvents::MergeRequestCreated
+ ],
+ StageEvents::IssueCreated => [
+ StageEvents::IssueStageEnd
+ ],
+ StageEvents::MergeRequestCreated => [
+ StageEvents::MergeRequestMerged
+ ],
+ StageEvents::MergeRequestLastBuildStarted => [
+ StageEvents::MergeRequestLastBuildFinished
+ ],
+ StageEvents::MergeRequestMerged => [
+ StageEvents::MergeRequestFirstDeployedToProduction
+ ]
+ }.freeze
+
+ def [](identifier)
+ events.find { |e| e.identifier.to_s.eql?(identifier.to_s) } || raise(KeyError)
+ end
+
+ # hash for defining ActiveRecord enum: identifier => number
+ def to_enum
+ ENUM_MAPPING.each_with_object({}) { |(k, v), hash| hash[k.identifier] = v }
+ end
+
+ # will be overridden in EE with custom events
+ def pairing_rules
+ PAIRING_RULES
+ end
+
+ # will be overridden in EE with custom events
+ def events
+ EVENTS
+ end
+
+ module_function :[], :to_enum, :pairing_rules, :events
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/analytics/cycle_analytics/stage_events/code_stage_start.rb b/lib/gitlab/analytics/cycle_analytics/stage_events/code_stage_start.rb
new file mode 100644
index 00000000000..ff9c8a79225
--- /dev/null
+++ b/lib/gitlab/analytics/cycle_analytics/stage_events/code_stage_start.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Analytics
+ module CycleAnalytics
+ module StageEvents
+ class CodeStageStart < SimpleStageEvent
+ def self.name
+ s_("CycleAnalyticsEvent|Issue first mentioned in a commit")
+ end
+
+ def self.identifier
+ :code_stage_start
+ end
+
+ def object_type
+ MergeRequest
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/analytics/cycle_analytics/stage_events/issue_created.rb b/lib/gitlab/analytics/cycle_analytics/stage_events/issue_created.rb
new file mode 100644
index 00000000000..a601c9797f8
--- /dev/null
+++ b/lib/gitlab/analytics/cycle_analytics/stage_events/issue_created.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Analytics
+ module CycleAnalytics
+ module StageEvents
+ class IssueCreated < SimpleStageEvent
+ def self.name
+ s_("CycleAnalyticsEvent|Issue created")
+ end
+
+ def self.identifier
+ :issue_created
+ end
+
+ def object_type
+ Issue
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/analytics/cycle_analytics/stage_events/issue_first_mentioned_in_commit.rb b/lib/gitlab/analytics/cycle_analytics/stage_events/issue_first_mentioned_in_commit.rb
new file mode 100644
index 00000000000..7424043ef7b
--- /dev/null
+++ b/lib/gitlab/analytics/cycle_analytics/stage_events/issue_first_mentioned_in_commit.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Analytics
+ module CycleAnalytics
+ module StageEvents
+ class IssueFirstMentionedInCommit < SimpleStageEvent
+ def self.name
+ s_("CycleAnalyticsEvent|Issue first mentioned in a commit")
+ end
+
+ def self.identifier
+ :issue_first_mentioned_in_commit
+ end
+
+ def object_type
+ Issue
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/analytics/cycle_analytics/stage_events/issue_stage_end.rb b/lib/gitlab/analytics/cycle_analytics/stage_events/issue_stage_end.rb
new file mode 100644
index 00000000000..ceb229c552f
--- /dev/null
+++ b/lib/gitlab/analytics/cycle_analytics/stage_events/issue_stage_end.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Analytics
+ module CycleAnalytics
+ module StageEvents
+ class IssueStageEnd < SimpleStageEvent
+ def self.name
+ PlanStageStart.name
+ end
+
+ def self.identifier
+ :issue_stage_end
+ end
+
+ def object_type
+ Issue
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_created.rb b/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_created.rb
new file mode 100644
index 00000000000..8be00831b4f
--- /dev/null
+++ b/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_created.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Analytics
+ module CycleAnalytics
+ module StageEvents
+ class MergeRequestCreated < SimpleStageEvent
+ def self.name
+ s_("CycleAnalyticsEvent|Merge request created")
+ end
+
+ def self.identifier
+ :merge_request_created
+ end
+
+ def object_type
+ MergeRequest
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_first_deployed_to_production.rb b/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_first_deployed_to_production.rb
new file mode 100644
index 00000000000..6d7a2c023ff
--- /dev/null
+++ b/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_first_deployed_to_production.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Analytics
+ module CycleAnalytics
+ module StageEvents
+ class MergeRequestFirstDeployedToProduction < SimpleStageEvent
+ def self.name
+ s_("CycleAnalyticsEvent|Merge request first deployed to production")
+ end
+
+ def self.identifier
+ :merge_request_first_deployed_to_production
+ end
+
+ def object_type
+ MergeRequest
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_finished.rb b/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_finished.rb
new file mode 100644
index 00000000000..12d82fe2c62
--- /dev/null
+++ b/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_finished.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Analytics
+ module CycleAnalytics
+ module StageEvents
+ class MergeRequestLastBuildFinished < SimpleStageEvent
+ def self.name
+ s_("CycleAnalyticsEvent|Merge request last build finish time")
+ end
+
+ def self.identifier
+ :merge_request_last_build_finished
+ end
+
+ def object_type
+ MergeRequest
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_started.rb b/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_started.rb
new file mode 100644
index 00000000000..9e749b0fdfa
--- /dev/null
+++ b/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_started.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Analytics
+ module CycleAnalytics
+ module StageEvents
+ class MergeRequestLastBuildStarted < SimpleStageEvent
+ def self.name
+ s_("CycleAnalyticsEvent|Merge request last build start time")
+ end
+
+ def self.identifier
+ :merge_request_last_build_started
+ end
+
+ def object_type
+ MergeRequest
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_merged.rb b/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_merged.rb
new file mode 100644
index 00000000000..bbfb5d12992
--- /dev/null
+++ b/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_merged.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Analytics
+ module CycleAnalytics
+ module StageEvents
+ class MergeRequestMerged < SimpleStageEvent
+ def self.name
+ s_("CycleAnalyticsEvent|Merge request merged")
+ end
+
+ def self.identifier
+ :merge_request_merged
+ end
+
+ def object_type
+ MergeRequest
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/analytics/cycle_analytics/stage_events/plan_stage_start.rb b/lib/gitlab/analytics/cycle_analytics/stage_events/plan_stage_start.rb
new file mode 100644
index 00000000000..803317d8b55
--- /dev/null
+++ b/lib/gitlab/analytics/cycle_analytics/stage_events/plan_stage_start.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Analytics
+ module CycleAnalytics
+ module StageEvents
+ class PlanStageStart < SimpleStageEvent
+ def self.name
+ s_("CycleAnalyticsEvent|Issue first associated with a milestone or issue first added to a board")
+ end
+
+ def self.identifier
+ :plan_stage_start
+ end
+
+ def object_type
+ Issue
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/analytics/cycle_analytics/stage_events/simple_stage_event.rb b/lib/gitlab/analytics/cycle_analytics/stage_events/simple_stage_event.rb
new file mode 100644
index 00000000000..253c489d822
--- /dev/null
+++ b/lib/gitlab/analytics/cycle_analytics/stage_events/simple_stage_event.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Analytics
+ module CycleAnalytics
+ module StageEvents
+ # Represents a simple event that usually refers to one database column and does not require additional user input
+ class SimpleStageEvent < StageEvent
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event.rb b/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event.rb
new file mode 100644
index 00000000000..a55eee048c2
--- /dev/null
+++ b/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Analytics
+ module CycleAnalytics
+ module StageEvents
+ # Base class for expressing an event that can be used for a stage.
+ class StageEvent
+ def initialize(params)
+ @params = params
+ end
+
+ def self.name
+ raise NotImplementedError
+ end
+
+ def self.identifier
+ raise NotImplementedError
+ end
+
+ def object_type
+ raise NotImplementedError
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb
index 9bba4f6ce1e..57a413f8e04 100644
--- a/lib/gitlab/database/migration_helpers.rb
+++ b/lib/gitlab/database/migration_helpers.rb
@@ -470,7 +470,7 @@ module Gitlab
# We set the default value _after_ adding the column so we don't end up
# updating any existing data with the default value. This isn't
# necessary since we copy over old values further down.
- change_column_default(table, new, old_col.default) if old_col.default
+ change_column_default(table, new, old_col.default) unless old_col.default.nil?
install_rename_triggers(table, old, new)
@@ -482,6 +482,16 @@ module Gitlab
copy_foreign_keys(table, old, new)
end
+ def undo_rename_column_concurrently(table, old, new)
+ trigger_name = rename_trigger_name(table, old, new)
+
+ check_trigger_permissions!(table)
+
+ remove_rename_triggers_for_postgresql(table, trigger_name)
+
+ remove_column(table, new)
+ end
+
# Installs triggers in a table that keep a new column in sync with an old
# one.
#
@@ -547,6 +557,35 @@ module Gitlab
remove_column(table, old)
end
+ def undo_cleanup_concurrent_column_rename(table, old, new, type: nil)
+ if transaction_open?
+ raise 'undo_cleanup_concurrent_column_rename can not be run inside a transaction'
+ end
+
+ check_trigger_permissions!(table)
+
+ new_column = column_for(table, new)
+
+ add_column(table, old, type || new_column.type,
+ limit: new_column.limit,
+ precision: new_column.precision,
+ scale: new_column.scale)
+
+ # We set the default value _after_ adding the column so we don't end up
+ # updating any existing data with the default value. This isn't
+ # necessary since we copy over old values further down.
+ change_column_default(table, old, new_column.default) unless new_column.default.nil?
+
+ install_rename_triggers(table, old, new)
+
+ update_column_in_batches(table, old, Arel::Table.new(table)[new])
+
+ change_column_null(table, old, false) unless new_column.null
+
+ copy_indexes(table, new, old)
+ copy_foreign_keys(table, new, old)
+ end
+
# Changes the column type of a table using a background migration.
#
# Because this method uses a background migration it's more suitable for
@@ -747,6 +786,11 @@ module Gitlab
EOF
execute <<-EOF.strip_heredoc
+ DROP TRIGGER IF EXISTS #{trigger}
+ ON #{table}
+ EOF
+
+ execute <<-EOF.strip_heredoc
CREATE TRIGGER #{trigger}
BEFORE INSERT OR UPDATE
ON #{table}
diff --git a/lib/gitlab/database_importers/self_monitoring/project/create_service.rb b/lib/gitlab/database_importers/self_monitoring/project/create_service.rb
new file mode 100644
index 00000000000..164854e1e1a
--- /dev/null
+++ b/lib/gitlab/database_importers/self_monitoring/project/create_service.rb
@@ -0,0 +1,251 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module DatabaseImporters
+ module SelfMonitoring
+ module Project
+ include Stepable
+
+ class CreateService < ::BaseService
+ include Stepable
+
+ STEPS_ALLOWED_TO_FAIL = [
+ :validate_application_settings, :validate_project_created, :validate_admins
+ ].freeze
+
+ VISIBILITY_LEVEL = Gitlab::VisibilityLevel::INTERNAL
+ PROJECT_NAME = 'GitLab Instance Administration'
+
+ steps :validate_application_settings,
+ :validate_project_created,
+ :validate_admins,
+ :create_group,
+ :create_project,
+ :save_project_id,
+ :add_group_members,
+ :add_to_whitelist,
+ :add_prometheus_manual_configuration
+
+ def initialize
+ super(nil)
+ end
+
+ def execute!
+ result = execute_steps
+
+ if result[:status] == :success
+ result
+ elsif STEPS_ALLOWED_TO_FAIL.include?(result[:failed_step])
+ success
+ else
+ raise StandardError, result[:message]
+ end
+ end
+
+ private
+
+ def validate_application_settings
+ return success if application_settings
+
+ log_error(_('No application_settings found'))
+ error(_('No application_settings found'))
+ end
+
+ def validate_project_created
+ return success unless project_created?
+
+ log_error(_('Project already created'))
+ error(_('Project already created'))
+ end
+
+ def validate_admins
+ unless instance_admins.any?
+ log_error(_('No active admin user found'))
+ return error(_('No active admin user found'))
+ end
+
+ success
+ end
+
+ def create_group
+ if project_created?
+ log_info(_('Instance administrators group already exists'))
+ @group = application_settings.instance_administration_project.owner
+ return success(group: @group)
+ end
+
+ @group = ::Groups::CreateService.new(group_owner, create_group_params).execute
+
+ if @group.persisted?
+ success(group: @group)
+ else
+ error(_('Could not create group'))
+ end
+ end
+
+ def create_project
+ if project_created?
+ log_info(_('Instance administration project already exists'))
+ @project = application_settings.instance_administration_project
+ return success(project: project)
+ end
+
+ @project = ::Projects::CreateService.new(group_owner, create_project_params).execute
+
+ if project.persisted?
+ success(project: project)
+ else
+ log_error(_("Could not create instance administration project. Errors: %{errors}") % { errors: project.errors.full_messages })
+ error(_('Could not create project'))
+ end
+ end
+
+ def save_project_id
+ return success if project_created?
+
+ result = application_settings.update(instance_administration_project_id: @project.id)
+
+ if result
+ success
+ else
+ log_error(_("Could not save instance administration project ID, errors: %{errors}") % { errors: application_settings.errors.full_messages })
+ error(_('Could not save project ID'))
+ end
+ end
+
+ def add_group_members
+ members = @group.add_users(members_to_add, Gitlab::Access::MAINTAINER)
+ errors = members.flat_map { |member| member.errors.full_messages }
+
+ if errors.any?
+ log_error(_('Could not add admins as members to self-monitoring project. Errors: %{errors}') % { errors: errors })
+ error(_('Could not add admins as members'))
+ else
+ success
+ end
+ end
+
+ def add_to_whitelist
+ return success unless prometheus_enabled?
+ return success unless prometheus_listen_address.present?
+
+ uri = parse_url(internal_prometheus_listen_address_uri)
+ return error(_('Prometheus listen_address is not a valid URI')) unless uri
+
+ application_settings.add_to_outbound_local_requests_whitelist([uri.normalized_host])
+ result = application_settings.save
+
+ if result
+ # Expire the Gitlab::CurrentSettings cache after updating the whitelist.
+ # This happens automatically in an after_commit hook, but in migrations,
+ # the after_commit hook only runs at the end of the migration.
+ Gitlab::CurrentSettings.expire_current_application_settings
+ success
+ else
+ log_error(_("Could not add prometheus URL to whitelist, errors: %{errors}") % { errors: application_settings.errors.full_messages })
+ error(_('Could not add prometheus URL to whitelist'))
+ end
+ end
+
+ def add_prometheus_manual_configuration
+ return success unless prometheus_enabled?
+ return success unless prometheus_listen_address.present?
+
+ service = project.find_or_initialize_service('prometheus')
+
+ unless service.update(prometheus_service_attributes)
+ log_error(_('Could not save prometheus manual configuration for self-monitoring project. Errors: %{errors}') % { errors: service.errors.full_messages })
+ return error(_('Could not save prometheus manual configuration'))
+ end
+
+ success
+ end
+
+ def application_settings
+ @application_settings ||= ApplicationSetting.current_without_cache
+ end
+
+ def project_created?
+ application_settings.instance_administration_project.present?
+ end
+
+ def parse_url(uri_string)
+ Addressable::URI.parse(uri_string)
+ rescue Addressable::URI::InvalidURIError, TypeError
+ end
+
+ def prometheus_enabled?
+ Gitlab.config.prometheus.enable
+ rescue Settingslogic::MissingSetting
+ log_error(_('prometheus.enable is not present in gitlab.yml'))
+
+ false
+ end
+
+ def prometheus_listen_address
+ Gitlab.config.prometheus.listen_address
+ rescue Settingslogic::MissingSetting
+ log_error(_('prometheus.listen_address is not present in gitlab.yml'))
+
+ nil
+ end
+
+ def instance_admins
+ @instance_admins ||= User.admins.active
+ end
+
+ def group_owner
+ instance_admins.first
+ end
+
+ def members_to_add
+ # Exclude admins who are already members of group because
+ # `@group.add_users(users)` returns an error if the users parameter contains
+ # users who are already members of the group.
+ instance_admins - @group.members.collect(&:user)
+ end
+
+ def create_group_params
+ {
+ name: 'GitLab Instance Administrators',
+ path: "gitlab-instance-administrators-#{SecureRandom.hex(4)}",
+ visibility_level: VISIBILITY_LEVEL
+ }
+ end
+
+ def docs_path
+ Rails.application.routes.url_helpers.help_page_path(
+ 'administration/monitoring/gitlab_instance_administration_project/index'
+ )
+ end
+
+ def create_project_params
+ {
+ initialize_with_readme: true,
+ visibility_level: VISIBILITY_LEVEL,
+ name: PROJECT_NAME,
+ description: "This project is automatically generated and will be used to help monitor this GitLab instance. [More information](#{docs_path})",
+ namespace_id: @group.id
+ }
+ end
+
+ def internal_prometheus_listen_address_uri
+ if prometheus_listen_address.starts_with?('http')
+ prometheus_listen_address
+ else
+ 'http://' + prometheus_listen_address
+ end
+ end
+
+ def prometheus_service_attributes
+ {
+ api_url: internal_prometheus_listen_address_uri,
+ manual_configuration: true,
+ active: true
+ }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/gitaly_client.rb b/lib/gitlab/gitaly_client.rb
index e6cbfb00f60..201db9fec26 100644
--- a/lib/gitlab/gitaly_client.rb
+++ b/lib/gitlab/gitaly_client.rb
@@ -406,7 +406,8 @@ module Gitlab
def self.filesystem_id(storage)
response = Gitlab::GitalyClient::ServerService.new(storage).info
storage_status = response.storage_statuses.find { |status| status.storage_name == storage }
- storage_status.filesystem_id
+
+ storage_status&.filesystem_id
end
def self.filesystem_id_from_disk(storage)
diff --git a/lib/gitlab/profiler.rb b/lib/gitlab/profiler.rb
index ec7671f9a8b..425c30d67fe 100644
--- a/lib/gitlab/profiler.rb
+++ b/lib/gitlab/profiler.rb
@@ -97,7 +97,7 @@ module Gitlab
attr_reader :load_times_by_model, :private_token
def debug(message, *)
- message.gsub!(private_token, FILTERED_STRING) if private_token
+ message = message.gsub(private_token, FILTERED_STRING) if private_token
_, type, time = *message.match(/(\w+) Load \(([0-9.]+)ms\)/)
diff --git a/lib/gitlab/quick_actions/substitution_definition.rb b/lib/gitlab/quick_actions/substitution_definition.rb
index 2f78ea05cf0..0fda056a4fe 100644
--- a/lib/gitlab/quick_actions/substitution_definition.rb
+++ b/lib/gitlab/quick_actions/substitution_definition.rb
@@ -17,8 +17,9 @@ module Gitlab
return unless content
all_names.each do |a_name|
- content.gsub!(%r{/#{a_name} ?(.*)$}i, execute_block(action_block, context, '\1'))
+ content = content.gsub(%r{/#{a_name} ?(.*)$}i, execute_block(action_block, context, '\1'))
end
+
content
end
end
diff --git a/lib/tasks/gitlab/assets.rake b/lib/tasks/gitlab/assets.rake
index a07ae3a418a..7a42e4e92a0 100644
--- a/lib/tasks/gitlab/assets.rake
+++ b/lib/tasks/gitlab/assets.rake
@@ -10,15 +10,9 @@ namespace :gitlab do
rake:assets:precompile
webpack:compile
gitlab:assets:fix_urls
- gitlab:assets:compile_vrt
].each(&Gitlab::TaskHelpers.method(:invoke_and_time_task))
end
- desc 'GitLab | Assets | Compile visual review toolbar'
- task :compile_vrt do
- system 'yarn', 'webpack-vrt'
- end
-
desc 'GitLab | Assets | Clean up old compiled frontend assets'
task clean: ['rake:assets:clean']
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 4f3c8e8046d..61642fbbd59 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -3353,6 +3353,12 @@ msgstr ""
msgid "Copy token to clipboard"
msgstr ""
+msgid "Could not add admins as members"
+msgstr ""
+
+msgid "Could not add admins as members to self-monitoring project. Errors: %{errors}"
+msgstr ""
+
msgid "Could not add prometheus URL to whitelist"
msgstr ""
@@ -3371,6 +3377,9 @@ msgstr ""
msgid "Could not create Wiki Repository at this time. Please try again later."
msgstr ""
+msgid "Could not create group"
+msgstr ""
+
msgid "Could not create instance administration project. Errors: %{errors}"
msgstr ""
@@ -3398,6 +3407,12 @@ msgstr ""
msgid "Could not save project ID"
msgstr ""
+msgid "Could not save prometheus manual configuration"
+msgstr ""
+
+msgid "Could not save prometheus manual configuration for self-monitoring project. Errors: %{errors}"
+msgstr ""
+
msgid "Coverage"
msgstr ""
@@ -3602,6 +3617,30 @@ msgstr ""
msgid "Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project."
msgstr ""
+msgid "CycleAnalyticsEvent|Issue created"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Issue first associated with a milestone or issue first added to a board"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Issue first mentioned in a commit"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request created"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request first deployed to production"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request last build finish time"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request last build start time"
+msgstr ""
+
+msgid "CycleAnalyticsEvent|Merge request merged"
+msgstr ""
+
msgid "CycleAnalyticsStage|Code"
msgstr ""
@@ -7376,9 +7415,15 @@ msgstr ""
msgid "No Tag"
msgstr ""
+msgid "No active admin user found"
+msgstr ""
+
msgid "No activities found"
msgstr ""
+msgid "No application_settings found"
+msgstr ""
+
msgid "No available namespaces to fork the project."
msgstr ""
@@ -8002,7 +8047,7 @@ msgstr ""
msgid "PipelineSheduleIntervalPattern|Custom"
msgstr ""
-msgid "PipelineStatusTooltip|Commit: %{ci_status}"
+msgid "PipelineStatusTooltip|Pipeline: %{ciStatus}"
msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
@@ -8722,6 +8767,9 @@ msgstr ""
msgid "Project access must be granted explicitly to each user."
msgstr ""
+msgid "Project already created"
+msgstr ""
+
msgid "Project and wiki repositories"
msgstr ""
@@ -13919,6 +13967,9 @@ msgstr ""
msgid "pending comment"
msgstr ""
+msgid "pipeline"
+msgstr ""
+
msgid "private"
msgstr ""
@@ -13934,6 +13985,12 @@ msgstr ""
msgid "project avatar"
msgstr ""
+msgid "prometheus.enable is not present in gitlab.yml"
+msgstr ""
+
+msgid "prometheus.listen_address is not present in gitlab.yml"
+msgstr ""
+
msgid "quick actions"
msgstr ""
diff --git a/package.json b/package.json
index df5f758fa20..e076f9e6664 100644
--- a/package.json
+++ b/package.json
@@ -26,8 +26,7 @@
"stylelint-create-utility-map": "node scripts/frontend/stylelint/stylelint-utility-map.js",
"test": "node scripts/frontend/test",
"webpack": "NODE_OPTIONS=\"--max-old-space-size=3584\" webpack --config config/webpack.config.js",
- "webpack-prod": "NODE_OPTIONS=\"--max-old-space-size=3584\" NODE_ENV=production webpack --config config/webpack.config.js",
- "webpack-vrt": "NODE_OPTIONS=\"--max-old-space-size=3584\" NODE_ENV=production webpack --config config/webpack.config.review_toolbar.js"
+ "webpack-prod": "NODE_OPTIONS=\"--max-old-space-size=3584\" NODE_ENV=production webpack --config config/webpack.config.js"
},
"dependencies": {
"@babel/core": "^7.5.5",
@@ -38,8 +37,9 @@
"@babel/plugin-syntax-import-meta": "^7.2.0",
"@babel/preset-env": "^7.5.5",
"@gitlab/csslab": "^1.9.0",
- "@gitlab/svgs": "^1.68.0",
+ "@gitlab/svgs": "^1.70.0",
"@gitlab/ui": "5.18.0",
+ "@gitlab/visual-review-tools": "^1.0.0",
"apollo-cache-inmemory": "^1.5.1",
"apollo-client": "^2.5.1",
"apollo-link": "^1.2.11",
diff --git a/qa/qa/runtime/api/request.rb b/qa/qa/runtime/api/request.rb
index 310c1dfeeb4..724b499d32f 100644
--- a/qa/qa/runtime/api/request.rb
+++ b/qa/qa/runtime/api/request.rb
@@ -12,6 +12,10 @@ module QA
@session_address = Runtime::Address.new(api_client.address, request_path)
end
+ def mask_url
+ @session_address.address.sub(/private_token=.*/, "private_token=[****]")
+ end
+
def url
@session_address.address
end
diff --git a/qa/qa/runtime/fixtures.rb b/qa/qa/runtime/fixtures.rb
index 72004d5b00a..02cecffd4df 100644
--- a/qa/qa/runtime/fixtures.rb
+++ b/qa/qa/runtime/fixtures.rb
@@ -3,10 +3,19 @@
module QA
module Runtime
module Fixtures
+ include Support::Api
+
+ TemplateNotFoundError = Class.new(RuntimeError)
+
def fetch_template_from_api(api_path, key)
request = Runtime::API::Request.new(api_client, "/templates/#{api_path}/#{key}")
- get request.url
- json_body[:content]
+ response = get(request.url)
+
+ unless response.code == HTTP_STATUS_OK
+ raise TemplateNotFoundError, "Template at #{request.mask_url} could not be found (#{response.code}): `#{response}`."
+ end
+
+ parse_body(response)[:content]
end
private
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb
index 317e31feea8..cdb85902758 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb
@@ -1,7 +1,8 @@
# frozen_string_literal: true
module QA
- context 'Plan' do
+ # Failure issue https://gitlab.com/gitlab-org/quality/staging/issues/68
+ context 'Plan', :quarantine do
describe 'filter issue comments activities' do
let(:issue_title) { 'issue title' }
diff --git a/rubocop/cop/migration/add_limit_to_string_columns.rb b/rubocop/cop/migration/add_limit_to_string_columns.rb
new file mode 100644
index 00000000000..30affcbb089
--- /dev/null
+++ b/rubocop/cop/migration/add_limit_to_string_columns.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+require_relative '../../migration_helpers'
+
+module RuboCop
+ module Cop
+ module Migration
+ # Cop that enforces length constraints to string columns
+ class AddLimitToStringColumns < RuboCop::Cop::Cop
+ include MigrationHelpers
+
+ ADD_COLUMNS_METHODS = %i(add_column add_column_with_default).freeze
+
+ MSG = 'String columns should have a limit constraint. 255 is suggested'.freeze
+
+ def on_def(node)
+ return unless in_migration?(node)
+
+ node.each_descendant(:send) do |send_node|
+ next unless string_operation?(send_node)
+
+ add_offense(send_node, location: :selector) unless limit_on_string_column?(send_node)
+ end
+ end
+
+ private
+
+ def string_operation?(node)
+ modifier = node.children[0]
+ migration_method = node.children[1]
+
+ if migration_method == :string
+ modifier.type == :lvar
+ elsif ADD_COLUMNS_METHODS.include?(migration_method)
+ modifier.nil? && string_column?(node.children[4])
+ end
+ end
+
+ def string_column?(column_type)
+ column_type.type == :sym && column_type.value == :string
+ end
+
+ def limit_on_string_column?(node)
+ migration_method = node.children[1]
+
+ if migration_method == :string
+ limit_present?(node.children)
+ elsif ADD_COLUMNS_METHODS.include?(migration_method)
+ limit_present?(node)
+ end
+ end
+
+ def limit_present?(statement)
+ !(statement.to_s =~ /:limit/).nil?
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/rubocop.rb b/rubocop/rubocop.rb
index 58a7ead6f13..d1328c4eb38 100644
--- a/rubocop/rubocop.rb
+++ b/rubocop/rubocop.rb
@@ -17,6 +17,7 @@ require_relative 'cop/migration/add_column'
require_relative 'cop/migration/add_concurrent_foreign_key'
require_relative 'cop/migration/add_concurrent_index'
require_relative 'cop/migration/add_index'
+require_relative 'cop/migration/add_limit_to_string_columns'
require_relative 'cop/migration/add_reference'
require_relative 'cop/migration/add_timestamps'
require_relative 'cop/migration/datetime'
diff --git a/spec/factories/ci/job_artifacts.rb b/spec/factories/ci/job_artifacts.rb
index 2d68a8e9fe3..6f553cadfa3 100644
--- a/spec/factories/ci/job_artifacts.rb
+++ b/spec/factories/ci/job_artifacts.rb
@@ -8,6 +8,10 @@ FactoryBot.define do
file_type :archive
file_format :zip
+ trait :expired do
+ expire_at { Date.yesterday }
+ end
+
trait :remote_store do
file_store JobArtifactUploader::Store::REMOTE
end
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb
index 4e7b25115d7..902ecdcd3e8 100644
--- a/spec/features/boards/boards_spec.rb
+++ b/spec/features/boards/boards_spec.rb
@@ -236,6 +236,15 @@ describe 'Issue Boards', :js do
expect(find('.board:nth-child(2)')).to have_content(planning.title)
end
+ it 'dragging does not duplicate list' do
+ selector = '.board:not(.is-ghost) .board-header'
+ expect(page).to have_selector(selector, text: development.title, count: 1)
+
+ drag(list_from_index: 2, list_to_index: 1, selector: '.board-header', perform_drop: false)
+
+ expect(page).to have_selector(selector, text: development.title, count: 1)
+ end
+
it 'issue moves between lists' do
drag(list_from_index: 1, from_index: 1, list_to_index: 2)
@@ -576,7 +585,7 @@ describe 'Issue Boards', :js do
end
end
- def drag(selector: '.board-list', list_from_index: 0, from_index: 0, to_index: 0, list_to_index: 0)
+ def drag(selector: '.board-list', list_from_index: 0, from_index: 0, to_index: 0, list_to_index: 0, perform_drop: true)
# ensure there is enough horizontal space for four boards
resize_window(2000, 800)
@@ -585,7 +594,8 @@ describe 'Issue Boards', :js do
list_from_index: list_from_index,
from_index: from_index,
to_index: to_index,
- list_to_index: list_to_index)
+ list_to_index: list_to_index,
+ perform_drop: perform_drop)
end
def wait_for_board_cards(board_number, expected_cards)
diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb
index e2100c8562b..e4728f37217 100644
--- a/spec/features/dashboard/projects_spec.rb
+++ b/spec/features/dashboard/projects_spec.rb
@@ -169,7 +169,7 @@ describe 'Dashboard Projects' do
expect(page).to have_xpath("//a[@href='#{pipelines_project_commit_path(project, project.commit, ref: pipeline.ref)}']")
expect(page).to have_css('.ci-status-link')
expect(page).to have_css('.ci-status-icon-success')
- expect(page).to have_link('Commit: passed')
+ expect(page).to have_link('Pipeline: passed')
end
end
@@ -189,7 +189,7 @@ describe 'Dashboard Projects' do
expect(page).not_to have_xpath("//a[@href='#{pipelines_project_commit_path(project, project.commit, ref: pipeline.ref)}']")
expect(page).not_to have_css('.ci-status-link')
expect(page).not_to have_css('.ci-status-icon-success')
- expect(page).not_to have_link('Commit: passed')
+ expect(page).not_to have_link('Pipeline: passed')
end
end
end
diff --git a/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb b/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb
index a1cad261875..fdc238d55cf 100644
--- a/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb
+++ b/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb
@@ -18,7 +18,7 @@ describe 'Projects > Show > User sees last commit CI status' do
page.within '.blob-commit-info' do
expect(page).to have_content(project.commit.sha[0..6])
- expect(page).to have_link('Commit: skipped')
+ expect(page).to have_link('Pipeline: skipped')
end
end
end
diff --git a/spec/frontend/monitoring/embed/embed_spec.js b/spec/frontend/monitoring/embed/embed_spec.js
index 3b18a0f77c7..1ce14e2418a 100644
--- a/spec/frontend/monitoring/embed/embed_spec.js
+++ b/spec/frontend/monitoring/embed/embed_spec.js
@@ -1,7 +1,7 @@
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
import Embed from '~/monitoring/components/embed.vue';
-import MonitorAreaChart from '~/monitoring/components/charts/area.vue';
+import MonitorTimeSeriesChart from '~/monitoring/components/charts/time_series.vue';
import { TEST_HOST } from 'helpers/test_constants';
import { groups, initialState, metricsData, metricsWithData } from './mock_data';
@@ -55,7 +55,7 @@ describe('Embed', () => {
it('shows an empty state when no metrics are present', () => {
expect(wrapper.find('.metrics-embed').exists()).toBe(true);
- expect(wrapper.find(MonitorAreaChart).exists()).toBe(false);
+ expect(wrapper.find(MonitorTimeSeriesChart).exists()).toBe(false);
});
});
@@ -71,8 +71,8 @@ describe('Embed', () => {
it('shows a chart when metrics are present', () => {
wrapper.setProps({});
expect(wrapper.find('.metrics-embed').exists()).toBe(true);
- expect(wrapper.find(MonitorAreaChart).exists()).toBe(true);
- expect(wrapper.findAll(MonitorAreaChart).length).toBe(2);
+ expect(wrapper.find(MonitorTimeSeriesChart).exists()).toBe(true);
+ expect(wrapper.findAll(MonitorTimeSeriesChart).length).toBe(2);
});
});
});
diff --git a/spec/helpers/ci_status_helper_spec.rb b/spec/helpers/ci_status_helper_spec.rb
index bc2422aba90..4f665dc0514 100644
--- a/spec/helpers/ci_status_helper_spec.rb
+++ b/spec/helpers/ci_status_helper_spec.rb
@@ -53,4 +53,80 @@ describe CiStatusHelper do
expect(helper.pipeline_status_cache_key(pipeline_status)).to eq("pipeline-status/123abc-success")
end
end
+
+ describe "#render_status_with_link" do
+ subject { helper.render_status_with_link("success") }
+
+ it "renders a passed status icon" do
+ is_expected.to include("<span class=\"ci-status-link ci-status-icon-success d-inline-flex")
+ end
+
+ it "has 'Pipeline' as the status type in the title" do
+ is_expected.to include("title=\"Pipeline: passed\"")
+ end
+
+ it "has the success status icon" do
+ is_expected.to include("ci-status-icon-success")
+ end
+
+ context "when pipeline has commit path" do
+ subject { helper.render_status_with_link("success", "/commit-path") }
+
+ it "links to commit" do
+ is_expected.to include("href=\"/commit-path\"")
+ end
+
+ it "does not contain a span element" do
+ is_expected.not_to include("<span")
+ end
+
+ it "has 'Pipeline' as the status type in the title" do
+ is_expected.to include("title=\"Pipeline: passed\"")
+ end
+
+ it "has the correct status icon" do
+ is_expected.to include("ci-status-icon-success")
+ end
+ end
+
+ context "when different type than pipeline is provided" do
+ subject { helper.render_status_with_link("success", type: "commit") }
+
+ it "has the provided type in the title" do
+ is_expected.to include("title=\"Commit: passed\"")
+ end
+ end
+
+ context "when tooltip_placement is provided" do
+ subject { helper.render_status_with_link("success", tooltip_placement: "right") }
+
+ it "has the provided tooltip placement" do
+ is_expected.to include("data-placement=\"right\"")
+ end
+ end
+
+ context "when additional CSS classes are provided" do
+ subject { helper.render_status_with_link("success", cssclass: "extra-class") }
+
+ it "has appended extra class to icon classes" do
+ is_expected.to include("class=\"ci-status-link ci-status-icon-success d-inline-flex extra-class\"")
+ end
+ end
+
+ context "when container is provided" do
+ subject { helper.render_status_with_link("success", container: "my-container") }
+
+ it "has the provided container in data" do
+ is_expected.to include("data-container=\"my-container\"")
+ end
+ end
+
+ context "when icon_size is provided" do
+ subject { helper.render_status_with_link("success", icon_size: 24) }
+
+ it "has the svg class to change size" do
+ is_expected.to include("<svg class=\"s24\">")
+ end
+ end
+ end
end
diff --git a/spec/javascripts/monitoring/charts/area_spec.js b/spec/javascripts/monitoring/charts/area_spec.js
index 57f99a09002..1e49a955815 100644
--- a/spec/javascripts/monitoring/charts/area_spec.js
+++ b/spec/javascripts/monitoring/charts/area_spec.js
@@ -225,6 +225,14 @@ describe('Area component', () => {
});
describe('chartOptions', () => {
+ describe('dataZoom', () => {
+ it('contains an svg object within an array to properly render icon', () => {
+ const dataZoomObject = [{}];
+
+ expect(areaChart.vm.chartOptions.dataZoom).toEqual(dataZoomObject);
+ });
+ });
+
describe('yAxis formatter', () => {
let format;
diff --git a/spec/javascripts/monitoring/panel_type_spec.js b/spec/javascripts/monitoring/panel_type_spec.js
index 086be628093..a2366e74d43 100644
--- a/spec/javascripts/monitoring/panel_type_spec.js
+++ b/spec/javascripts/monitoring/panel_type_spec.js
@@ -1,7 +1,7 @@
import { shallowMount } from '@vue/test-utils';
import PanelType from '~/monitoring/components/panel_type.vue';
import EmptyChart from '~/monitoring/components/charts/empty_chart.vue';
-import AreaChart from '~/monitoring/components/charts/area.vue';
+import TimeSeriesChart from '~/monitoring/components/charts/time_series.vue';
import { graphDataPrometheusQueryRange } from './mock_data';
import { createStore } from '~/monitoring/stores';
@@ -62,9 +62,10 @@ describe('Panel Type component', () => {
});
});
- describe('Area Chart panel type', () => {
+ describe('Time Series Chart panel type', () => {
it('is rendered', () => {
- expect(panelType.find(AreaChart).exists()).toBe(true);
+ expect(panelType.find(TimeSeriesChart).isVueInstance()).toBe(true);
+ expect(panelType.find(TimeSeriesChart).exists()).toBe(true);
});
it('sets clipboard text on the dropdown', () => {
diff --git a/spec/lib/api/helpers/label_helpers_spec.rb b/spec/lib/api/helpers/label_helpers_spec.rb
new file mode 100644
index 00000000000..138e9a22d70
--- /dev/null
+++ b/spec/lib/api/helpers/label_helpers_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe API::Helpers::LabelHelpers do
+ describe 'create_service_params' do
+ let(:label_helper) do
+ Class.new do
+ include API::Helpers::LabelHelpers
+ end.new
+ end
+
+ context 'when a project is given' do
+ it 'returns the expected params' do
+ project = create(:project)
+ expect(label_helper.create_service_params(project)).to eq({ project: project })
+ end
+ end
+
+ context 'when a group is given' do
+ it 'returns the expected params' do
+ group = create(:group)
+ expect(label_helper.create_service_params(group)).to eq({ group: group })
+ end
+ end
+
+ context 'when something else is given' do
+ it 'raises a type error' do
+ expect { label_helper.create_service_params(Class.new) }.to raise_error(TypeError)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event_spec.rb
new file mode 100644
index 00000000000..29f4be76a65
--- /dev/null
+++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event_spec.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Analytics::CycleAnalytics::StageEvents::StageEvent do
+ it { expect(described_class).to respond_to(:name) }
+ it { expect(described_class).to respond_to(:identifier) }
+
+ it { expect(described_class.new({})).to respond_to(:object_type) }
+end
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index 2731fc8573f..cff4eb398bf 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -576,6 +576,38 @@ describe Gitlab::Database::MigrationHelpers do
model.rename_column_concurrently(:users, :old, :new)
end
+
+ context 'when default is false' do
+ let(:old_column) do
+ double(:column,
+ type: :boolean,
+ limit: nil,
+ default: false,
+ null: false,
+ precision: nil,
+ scale: nil)
+ end
+
+ it 'copies the default to the new column' do
+ expect(model).to receive(:change_column_default)
+ .with(:users, :new, old_column.default)
+
+ model.rename_column_concurrently(:users, :old, :new)
+ end
+ end
+ end
+ end
+
+ describe '#undo_rename_column_concurrently' do
+ it 'reverses the operations of rename_column_concurrently' do
+ expect(model).to receive(:check_trigger_permissions!).with(:users)
+
+ expect(model).to receive(:remove_rename_triggers_for_postgresql)
+ .with(:users, /trigger_.{12}/)
+
+ expect(model).to receive(:remove_column).with(:users, :new)
+
+ model.undo_rename_column_concurrently(:users, :old, :new)
end
end
@@ -592,6 +624,80 @@ describe Gitlab::Database::MigrationHelpers do
end
end
+ describe '#undo_cleanup_concurrent_column_rename' do
+ context 'in a transaction' do
+ it 'raises RuntimeError' do
+ allow(model).to receive(:transaction_open?).and_return(true)
+
+ expect { model.undo_cleanup_concurrent_column_rename(:users, :old, :new) }
+ .to raise_error(RuntimeError)
+ end
+ end
+
+ context 'outside a transaction' do
+ let(:new_column) do
+ double(:column,
+ type: :integer,
+ limit: 8,
+ default: 0,
+ null: false,
+ precision: 5,
+ scale: 1)
+ end
+
+ let(:trigger_name) { model.rename_trigger_name(:users, :old, :new) }
+
+ before do
+ allow(model).to receive(:transaction_open?).and_return(false)
+ allow(model).to receive(:column_for).and_return(new_column)
+ end
+
+ it 'reverses the operations of cleanup_concurrent_column_rename' do
+ expect(model).to receive(:check_trigger_permissions!).with(:users)
+
+ expect(model).to receive(:install_rename_triggers_for_postgresql)
+ .with(trigger_name, '"users"', '"old"', '"new"')
+
+ expect(model).to receive(:add_column)
+ .with(:users, :old, :integer,
+ limit: new_column.limit,
+ precision: new_column.precision,
+ scale: new_column.scale)
+
+ expect(model).to receive(:change_column_default)
+ .with(:users, :old, new_column.default)
+
+ expect(model).to receive(:update_column_in_batches)
+
+ expect(model).to receive(:change_column_null).with(:users, :old, false)
+
+ expect(model).to receive(:copy_indexes).with(:users, :new, :old)
+ expect(model).to receive(:copy_foreign_keys).with(:users, :new, :old)
+
+ model.undo_cleanup_concurrent_column_rename(:users, :old, :new)
+ end
+
+ context 'when default is false' do
+ let(:new_column) do
+ double(:column,
+ type: :boolean,
+ limit: nil,
+ default: false,
+ null: false,
+ precision: nil,
+ scale: nil)
+ end
+
+ it 'copies the default to the old column' do
+ expect(model).to receive(:change_column_default)
+ .with(:users, :old, new_column.default)
+
+ model.undo_cleanup_concurrent_column_rename(:users, :old, :new)
+ end
+ end
+ end
+ end
+
describe '#change_column_type_concurrently' do
it 'changes the column type' do
expect(model).to receive(:rename_column_concurrently)
@@ -619,10 +725,18 @@ describe Gitlab::Database::MigrationHelpers do
.with(/CREATE OR REPLACE FUNCTION foo()/m)
expect(model).to receive(:execute)
+ .with(/DROP TRIGGER IF EXISTS foo/m)
+
+ expect(model).to receive(:execute)
.with(/CREATE TRIGGER foo/m)
model.install_rename_triggers_for_postgresql('foo', :users, :old, :new)
end
+
+ it 'does not fail if trigger already exists' do
+ model.install_rename_triggers_for_postgresql('foo', :users, :old, :new)
+ model.install_rename_triggers_for_postgresql('foo', :users, :old, :new)
+ end
end
describe '#remove_rename_triggers_for_postgresql' do
diff --git a/spec/services/self_monitoring/project/create_service_spec.rb b/spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb
index def20448bd9..9bd0d800086 100644
--- a/spec/services/self_monitoring/project/create_service_spec.rb
+++ b/spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb
@@ -2,29 +2,48 @@
require 'spec_helper'
-describe SelfMonitoring::Project::CreateService do
+describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService do
describe '#execute' do
- let(:result) { subject.execute }
+ let(:result) { subject.execute! }
let(:prometheus_settings) do
- OpenStruct.new(
+ {
enable: true,
listen_address: 'localhost:9090'
- )
+ }
end
before do
- allow(Gitlab.config).to receive(:prometheus).and_return(prometheus_settings)
+ stub_config(prometheus: prometheus_settings)
+ end
+
+ context 'without application_settings' do
+ it 'does not fail' do
+ expect(subject).to receive(:log_error).and_call_original
+ expect(result).to eq(
+ status: :success
+ )
+
+ expect(Project.count).to eq(0)
+ expect(Group.count).to eq(0)
+ end
end
context 'without admin users' do
- it 'returns error' do
+ let(:application_setting) { Gitlab::CurrentSettings.current_application_settings }
+
+ before do
+ allow(ApplicationSetting).to receive(:current_without_cache) { application_setting }
+ end
+
+ it 'does not fail' do
expect(subject).to receive(:log_error).and_call_original
expect(result).to eq(
- status: :error,
- message: 'No active admin user found',
- failed_step: :validate_admins
+ status: :success
)
+
+ expect(Project.count).to eq(0)
+ expect(Group.count).to eq(0)
end
end
@@ -36,6 +55,7 @@ describe SelfMonitoring::Project::CreateService do
let!(:user) { create(:user, :admin) }
before do
+ allow(ApplicationSetting).to receive(:current_without_cache) { application_setting }
application_setting.allow_local_requests_from_web_hooks_and_services = true
end
@@ -56,8 +76,8 @@ describe SelfMonitoring::Project::CreateService do
it 'creates group' do
expect(result[:status]).to eq(:success)
expect(group).to be_persisted
- expect(group.name).to eq(described_class::GROUP_NAME)
- expect(group.path).to start_with(described_class::GROUP_PATH)
+ expect(group.name).to eq('GitLab Instance Administrators')
+ expect(group.path).to start_with('gitlab-instance-administrators')
expect(group.path.split('-').last.length).to eq(8)
expect(group.visibility_level).to eq(described_class::VISIBILITY_LEVEL)
end
@@ -77,9 +97,16 @@ describe SelfMonitoring::Project::CreateService do
end
it 'creates project with correct name and description' do
+ path = 'administration/monitoring/gitlab_instance_administration_project/index'
+ docs_path = Rails.application.routes.url_helpers.help_page_path(path)
+
expect(result[:status]).to eq(:success)
expect(project.name).to eq(described_class::PROJECT_NAME)
- expect(project.description).to eq(described_class::PROJECT_DESCRIPTION)
+ expect(project.description).to eq(
+ 'This project is automatically generated and will be used to help monitor this GitLab instance. ' \
+ "[More information](#{docs_path})"
+ )
+ expect(File).to exist("doc/#{path}.md")
end
it 'adds all admins as maintainers' do
@@ -105,19 +132,30 @@ describe SelfMonitoring::Project::CreateService do
it 'returns error when saving project ID fails' do
allow(application_setting).to receive(:update) { false }
- expect(result[:status]).to eq(:error)
- expect(result[:failed_step]).to eq(:save_project_id)
- expect(result[:message]).to eq('Could not save project ID')
+ expect { result }.to raise_error(StandardError, 'Could not save project ID')
end
- it 'does not fail when a project already exists' do
- expect(result[:status]).to eq(:success)
+ context 'when project already exists' do
+ let(:existing_group) { create(:group) }
+ let(:existing_project) { create(:project, namespace: existing_group) }
- second_result = subject.execute
+ before do
+ admin1 = create(:user, :admin)
+ admin2 = create(:user, :admin)
+
+ existing_group.add_owner(user)
+ existing_group.add_users([admin1, admin2], Gitlab::Access::MAINTAINER)
+
+ application_setting.instance_administration_project_id = existing_project.id
+ end
+
+ it 'does not fail' do
+ expect(subject).to receive(:log_error).and_call_original
+ expect(result[:status]).to eq(:success)
- expect(second_result[:status]).to eq(:success)
- expect(second_result[:project]).to eq(project)
- expect(second_result[:group]).to eq(group)
+ expect(Project.count).to eq(1)
+ expect(Group.count).to eq(1)
+ end
end
context 'when local requests from hooks and services are not allowed' do
@@ -138,8 +176,11 @@ describe SelfMonitoring::Project::CreateService do
end
context 'with non default prometheus address' do
- before do
- prometheus_settings.listen_address = 'https://localhost:9090'
+ let(:prometheus_settings) do
+ {
+ enable: true,
+ listen_address: 'https://localhost:9090'
+ }
end
it_behaves_like 'has prometheus service', 'https://localhost:9090'
@@ -157,8 +198,11 @@ describe SelfMonitoring::Project::CreateService do
end
context 'when prometheus setting is disabled in gitlab.yml' do
- before do
- prometheus_settings.enable = false
+ let(:prometheus_settings) do
+ {
+ enable: false,
+ listen_address: 'http://localhost:9090'
+ }
end
it 'does not configure prometheus' do
@@ -168,9 +212,7 @@ describe SelfMonitoring::Project::CreateService do
end
context 'when prometheus listen address is blank in gitlab.yml' do
- before do
- prometheus_settings.listen_address = ''
- end
+ let(:prometheus_settings) { { enable: true, listen_address: '' } }
it 'does not configure prometheus' do
expect(result).to include(status: :success)
@@ -192,11 +234,7 @@ describe SelfMonitoring::Project::CreateService do
it 'returns error' do
expect(subject).to receive(:log_error).and_call_original
- expect(result).to eq({
- status: :error,
- message: 'Could not create project',
- failed_step: :create_project
- })
+ expect { result }.to raise_error(StandardError, 'Could not create project')
end
end
@@ -207,26 +245,21 @@ describe SelfMonitoring::Project::CreateService do
it 'returns error' do
expect(subject).to receive(:log_error).and_call_original
- expect(result).to eq({
- status: :error,
- message: 'Could not add admins as members',
- failed_step: :add_group_members
- })
+ expect { result }.to raise_error(StandardError, 'Could not add admins as members')
end
end
context 'when prometheus manual configuration cannot be saved' do
- before do
- prometheus_settings.listen_address = 'httpinvalid://localhost:9090'
+ let(:prometheus_settings) do
+ {
+ enable: true,
+ listen_address: 'httpinvalid://localhost:9090'
+ }
end
it 'returns error' do
expect(subject).to receive(:log_error).and_call_original
- expect(result).to eq(
- status: :error,
- message: 'Could not save prometheus manual configuration',
- failed_step: :add_prometheus_manual_configuration
- )
+ expect { result }.to raise_error(StandardError, 'Could not save prometheus manual configuration')
end
end
end
diff --git a/spec/lib/gitlab/gitaly_client_spec.rb b/spec/lib/gitlab/gitaly_client_spec.rb
index e9fb6c0125c..99d563e03ec 100644
--- a/spec/lib/gitlab/gitaly_client_spec.rb
+++ b/spec/lib/gitlab/gitaly_client_spec.rb
@@ -27,6 +27,16 @@ describe Gitlab::GitalyClient do
end
end
+ describe '.filesystem_id' do
+ it 'returns an empty string when the storage is not found in the response' do
+ response = double("response")
+ allow(response).to receive(:storage_statuses).and_return([])
+ allow_any_instance_of(Gitlab::GitalyClient::ServerService).to receive(:info).and_return(response)
+
+ expect(described_class.filesystem_id('default')).to eq(nil)
+ end
+ end
+
describe '.stub_class' do
it 'returns the gRPC health check stub' do
expect(described_class.stub_class(:health_check)).to eq(::Grpc::Health::V1::Health::Stub)
diff --git a/spec/lib/gitlab/legacy_github_import/release_formatter_spec.rb b/spec/lib/gitlab/legacy_github_import/release_formatter_spec.rb
index 534cf219520..2cf4b367c0b 100644
--- a/spec/lib/gitlab/legacy_github_import/release_formatter_spec.rb
+++ b/spec/lib/gitlab/legacy_github_import/release_formatter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::LegacyGithubImport::ReleaseFormatter do
diff --git a/spec/lib/gitlab/legacy_github_import/user_formatter_spec.rb b/spec/lib/gitlab/legacy_github_import/user_formatter_spec.rb
index 3cd096eb0ad..919847fe061 100644
--- a/spec/lib/gitlab/legacy_github_import/user_formatter_spec.rb
+++ b/spec/lib/gitlab/legacy_github_import/user_formatter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::LegacyGithubImport::UserFormatter do
diff --git a/spec/lib/gitlab/legacy_github_import/wiki_formatter_spec.rb b/spec/lib/gitlab/legacy_github_import/wiki_formatter_spec.rb
index 7519707293c..639fb9d80eb 100644
--- a/spec/lib/gitlab/legacy_github_import/wiki_formatter_spec.rb
+++ b/spec/lib/gitlab/legacy_github_import/wiki_formatter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::LegacyGithubImport::WikiFormatter do
diff --git a/spec/lib/gitlab/loop_helpers_spec.rb b/spec/lib/gitlab/loop_helpers_spec.rb
index e17a0342d64..7e59b41d5b9 100644
--- a/spec/lib/gitlab/loop_helpers_spec.rb
+++ b/spec/lib/gitlab/loop_helpers_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::LoopHelpers do
diff --git a/spec/lib/gitlab/manifest_import/manifest_spec.rb b/spec/lib/gitlab/manifest_import/manifest_spec.rb
index ded93e23c08..c1135f710ea 100644
--- a/spec/lib/gitlab/manifest_import/manifest_spec.rb
+++ b/spec/lib/gitlab/manifest_import/manifest_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ManifestImport::Manifest do
diff --git a/spec/lib/gitlab/manifest_import/project_creator_spec.rb b/spec/lib/gitlab/manifest_import/project_creator_spec.rb
index a7487972f51..a8cfcfb41d3 100644
--- a/spec/lib/gitlab/manifest_import/project_creator_spec.rb
+++ b/spec/lib/gitlab/manifest_import/project_creator_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ManifestImport::ProjectCreator do
diff --git a/spec/lib/gitlab/markup_helper_spec.rb b/spec/lib/gitlab/markup_helper_spec.rb
index 09e518ff989..b93538cae5a 100644
--- a/spec/lib/gitlab/markup_helper_spec.rb
+++ b/spec/lib/gitlab/markup_helper_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::MarkupHelper do
diff --git a/spec/lib/gitlab/metrics/background_transaction_spec.rb b/spec/lib/gitlab/metrics/background_transaction_spec.rb
index 17445fe6de5..d87d2c839ad 100644
--- a/spec/lib/gitlab/metrics/background_transaction_spec.rb
+++ b/spec/lib/gitlab/metrics/background_transaction_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::BackgroundTransaction do
diff --git a/spec/lib/gitlab/metrics/delta_spec.rb b/spec/lib/gitlab/metrics/delta_spec.rb
index 718387cdee1..9bb011dc8fc 100644
--- a/spec/lib/gitlab/metrics/delta_spec.rb
+++ b/spec/lib/gitlab/metrics/delta_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Delta do
diff --git a/spec/lib/gitlab/metrics/instrumentation_spec.rb b/spec/lib/gitlab/metrics/instrumentation_spec.rb
index 977bc250049..0e2f274f157 100644
--- a/spec/lib/gitlab/metrics/instrumentation_spec.rb
+++ b/spec/lib/gitlab/metrics/instrumentation_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Instrumentation do
diff --git a/spec/lib/gitlab/metrics/method_call_spec.rb b/spec/lib/gitlab/metrics/method_call_spec.rb
index d9379cfe674..3b5e04e2df5 100644
--- a/spec/lib/gitlab/metrics/method_call_spec.rb
+++ b/spec/lib/gitlab/metrics/method_call_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::MethodCall do
diff --git a/spec/lib/gitlab/metrics/methods_spec.rb b/spec/lib/gitlab/metrics/methods_spec.rb
index 9d41ed2442b..bca94deb1d8 100644
--- a/spec/lib/gitlab/metrics/methods_spec.rb
+++ b/spec/lib/gitlab/metrics/methods_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Methods do
diff --git a/spec/lib/gitlab/metrics/metric_spec.rb b/spec/lib/gitlab/metrics/metric_spec.rb
index d240b8a01fd..611b59231ba 100644
--- a/spec/lib/gitlab/metrics/metric_spec.rb
+++ b/spec/lib/gitlab/metrics/metric_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Metric do
diff --git a/spec/lib/gitlab/metrics/prometheus_spec.rb b/spec/lib/gitlab/metrics/prometheus_spec.rb
index 3d4dd5fdf01..b37624982e2 100644
--- a/spec/lib/gitlab/metrics/prometheus_spec.rb
+++ b/spec/lib/gitlab/metrics/prometheus_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Prometheus, :prometheus do
diff --git a/spec/lib/gitlab/metrics/rack_middleware_spec.rb b/spec/lib/gitlab/metrics/rack_middleware_spec.rb
index b84387204ee..1c1681cc5ab 100644
--- a/spec/lib/gitlab/metrics/rack_middleware_spec.rb
+++ b/spec/lib/gitlab/metrics/rack_middleware_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::RackMiddleware do
diff --git a/spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb b/spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb
index ebe66948a91..c29db3a93ec 100644
--- a/spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb
+++ b/spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::RequestsRackMiddleware do
diff --git a/spec/lib/gitlab/metrics/samplers/influx_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/influx_sampler_spec.rb
index 2923048f742..2d4b27a6ac1 100644
--- a/spec/lib/gitlab/metrics/samplers/influx_sampler_spec.rb
+++ b/spec/lib/gitlab/metrics/samplers/influx_sampler_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Samplers::InfluxSampler do
diff --git a/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
index 5005a5d9ebc..8c4071a7ed1 100644
--- a/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
+++ b/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Samplers::RubySampler do
diff --git a/spec/lib/gitlab/metrics/samplers/unicorn_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/unicorn_sampler_spec.rb
index 4b697b2ba0f..cdfd95e3885 100644
--- a/spec/lib/gitlab/metrics/samplers/unicorn_sampler_spec.rb
+++ b/spec/lib/gitlab/metrics/samplers/unicorn_sampler_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Samplers::UnicornSampler do
diff --git a/spec/lib/gitlab/metrics/sidekiq_metrics_exporter_spec.rb b/spec/lib/gitlab/metrics/sidekiq_metrics_exporter_spec.rb
index 61eb059a731..9eea3eb79dc 100644
--- a/spec/lib/gitlab/metrics/sidekiq_metrics_exporter_spec.rb
+++ b/spec/lib/gitlab/metrics/sidekiq_metrics_exporter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::SidekiqMetricsExporter do
diff --git a/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb b/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb
index ae1d8b47fe9..bb95d5ab2ad 100644
--- a/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb
+++ b/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::SidekiqMiddleware do
diff --git a/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb b/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb
index 9f3af1acef7..25c0e7b695a 100644
--- a/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb
+++ b/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Subscribers::ActionView do
diff --git a/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb b/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb
index ee6d6fc961f..1624cea8bda 100644
--- a/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb
+++ b/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Subscribers::ActiveRecord do
diff --git a/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb b/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb
index e04056b3450..ab0d89b2683 100644
--- a/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb
+++ b/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::Subscribers::RailsCache do
diff --git a/spec/lib/gitlab/metrics/system_spec.rb b/spec/lib/gitlab/metrics/system_spec.rb
index 3b434a02f63..6d2764a06f2 100644
--- a/spec/lib/gitlab/metrics/system_spec.rb
+++ b/spec/lib/gitlab/metrics/system_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::System do
diff --git a/spec/lib/gitlab/metrics/web_transaction_spec.rb b/spec/lib/gitlab/metrics/web_transaction_spec.rb
index 0b3b23e930f..2b35f07cc0d 100644
--- a/spec/lib/gitlab/metrics/web_transaction_spec.rb
+++ b/spec/lib/gitlab/metrics/web_transaction_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics::WebTransaction do
diff --git a/spec/lib/gitlab/metrics_spec.rb b/spec/lib/gitlab/metrics_spec.rb
index 03c185ddc07..f0ba12c1cd0 100644
--- a/spec/lib/gitlab/metrics_spec.rb
+++ b/spec/lib/gitlab/metrics_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Metrics do
diff --git a/spec/lib/gitlab/middleware/basic_health_check_spec.rb b/spec/lib/gitlab/middleware/basic_health_check_spec.rb
index 86bdc479b66..07fda691ac8 100644
--- a/spec/lib/gitlab/middleware/basic_health_check_spec.rb
+++ b/spec/lib/gitlab/middleware/basic_health_check_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Middleware::BasicHealthCheck do
diff --git a/spec/lib/gitlab/middleware/multipart_spec.rb b/spec/lib/gitlab/middleware/multipart_spec.rb
index 3f6ada6832a..33797817578 100644
--- a/spec/lib/gitlab/middleware/multipart_spec.rb
+++ b/spec/lib/gitlab/middleware/multipart_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'tempfile'
diff --git a/spec/lib/gitlab/middleware/rails_queue_duration_spec.rb b/spec/lib/gitlab/middleware/rails_queue_duration_spec.rb
index 14f2c3cb86f..31359abdce3 100644
--- a/spec/lib/gitlab/middleware/rails_queue_duration_spec.rb
+++ b/spec/lib/gitlab/middleware/rails_queue_duration_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Middleware::RailsQueueDuration do
diff --git a/spec/lib/gitlab/middleware/read_only_spec.rb b/spec/lib/gitlab/middleware/read_only_spec.rb
index 24d49a049b6..d2c8f4ab0bd 100644
--- a/spec/lib/gitlab/middleware/read_only_spec.rb
+++ b/spec/lib/gitlab/middleware/read_only_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Middleware::ReadOnly do
diff --git a/spec/lib/gitlab/middleware/release_env_spec.rb b/spec/lib/gitlab/middleware/release_env_spec.rb
index 5e3aa877409..3ca40f4ebd0 100644
--- a/spec/lib/gitlab/middleware/release_env_spec.rb
+++ b/spec/lib/gitlab/middleware/release_env_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Middleware::ReleaseEnv do
diff --git a/spec/lib/gitlab/multi_collection_paginator_spec.rb b/spec/lib/gitlab/multi_collection_paginator_spec.rb
index 28cd704b05a..f2049884b83 100644
--- a/spec/lib/gitlab/multi_collection_paginator_spec.rb
+++ b/spec/lib/gitlab/multi_collection_paginator_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::MultiCollectionPaginator do
diff --git a/spec/lib/gitlab/object_hierarchy_spec.rb b/spec/lib/gitlab/object_hierarchy_spec.rb
index bfd456cdd7e..b16eccbcb2c 100644
--- a/spec/lib/gitlab/object_hierarchy_spec.rb
+++ b/spec/lib/gitlab/object_hierarchy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ObjectHierarchy do
diff --git a/spec/lib/gitlab/octokit/middleware_spec.rb b/spec/lib/gitlab/octokit/middleware_spec.rb
index 43f6d13f7ba..8aa6d17ac9e 100644
--- a/spec/lib/gitlab/octokit/middleware_spec.rb
+++ b/spec/lib/gitlab/octokit/middleware_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Octokit::Middleware do
diff --git a/spec/lib/gitlab/omniauth_initializer_spec.rb b/spec/lib/gitlab/omniauth_initializer_spec.rb
index ef5c93e5c6b..99684bb2ab2 100644
--- a/spec/lib/gitlab/omniauth_initializer_spec.rb
+++ b/spec/lib/gitlab/omniauth_initializer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::OmniauthInitializer do
diff --git a/spec/lib/gitlab/optimistic_locking_spec.rb b/spec/lib/gitlab/optimistic_locking_spec.rb
index 6fdf61ee0a7..9dfcb775dfa 100644
--- a/spec/lib/gitlab/optimistic_locking_spec.rb
+++ b/spec/lib/gitlab/optimistic_locking_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::OptimisticLocking do
diff --git a/spec/lib/gitlab/other_markup_spec.rb b/spec/lib/gitlab/other_markup_spec.rb
index e26f39e193e..b5cf5b0999d 100644
--- a/spec/lib/gitlab/other_markup_spec.rb
+++ b/spec/lib/gitlab/other_markup_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::OtherMarkup do
diff --git a/spec/lib/gitlab/otp_key_rotator_spec.rb b/spec/lib/gitlab/otp_key_rotator_spec.rb
index 6e6e9ce29ac..f5a567d5ea0 100644
--- a/spec/lib/gitlab/otp_key_rotator_spec.rb
+++ b/spec/lib/gitlab/otp_key_rotator_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::OtpKeyRotator do
diff --git a/spec/lib/gitlab/pages_client_spec.rb b/spec/lib/gitlab/pages_client_spec.rb
index da6d26f4aee..84381843221 100644
--- a/spec/lib/gitlab/pages_client_spec.rb
+++ b/spec/lib/gitlab/pages_client_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::PagesClient do
diff --git a/spec/lib/gitlab/path_regex_spec.rb b/spec/lib/gitlab/path_regex_spec.rb
index 84b2e2dc823..7dcdad7ff92 100644
--- a/spec/lib/gitlab/path_regex_spec.rb
+++ b/spec/lib/gitlab/path_regex_spec.rb
@@ -1,4 +1,6 @@
# coding: utf-8
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::PathRegex do
diff --git a/spec/lib/gitlab/performance_bar_spec.rb b/spec/lib/gitlab/performance_bar_spec.rb
index 71c109db1f1..8d8ac2aebbe 100644
--- a/spec/lib/gitlab/performance_bar_spec.rb
+++ b/spec/lib/gitlab/performance_bar_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::PerformanceBar do
diff --git a/spec/lib/gitlab/phabricator_import/importer_spec.rb b/spec/lib/gitlab/phabricator_import/importer_spec.rb
index bf14010a187..99a6e4dad6b 100644
--- a/spec/lib/gitlab/phabricator_import/importer_spec.rb
+++ b/spec/lib/gitlab/phabricator_import/importer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::PhabricatorImport::Importer do
diff --git a/spec/lib/gitlab/phabricator_import/user_finder_spec.rb b/spec/lib/gitlab/phabricator_import/user_finder_spec.rb
index 096321cda5f..918ff28c8f5 100644
--- a/spec/lib/gitlab/phabricator_import/user_finder_spec.rb
+++ b/spec/lib/gitlab/phabricator_import/user_finder_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::PhabricatorImport::UserFinder, :clean_gitlab_redis_cache do
diff --git a/spec/lib/gitlab/phabricator_import/worker_state_spec.rb b/spec/lib/gitlab/phabricator_import/worker_state_spec.rb
index a44947445c9..b6f2524a9d0 100644
--- a/spec/lib/gitlab/phabricator_import/worker_state_spec.rb
+++ b/spec/lib/gitlab/phabricator_import/worker_state_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::PhabricatorImport::WorkerState, :clean_gitlab_redis_shared_state do
diff --git a/spec/lib/gitlab/plugin_spec.rb b/spec/lib/gitlab/plugin_spec.rb
index 33dd4f79130..a8ddd774f3f 100644
--- a/spec/lib/gitlab/plugin_spec.rb
+++ b/spec/lib/gitlab/plugin_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Plugin do
diff --git a/spec/lib/gitlab/polling_interval_spec.rb b/spec/lib/gitlab/polling_interval_spec.rb
index eb8e618156b..979164269bd 100644
--- a/spec/lib/gitlab/polling_interval_spec.rb
+++ b/spec/lib/gitlab/polling_interval_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::PollingInterval do
diff --git a/spec/lib/gitlab/popen/runner_spec.rb b/spec/lib/gitlab/popen/runner_spec.rb
index 2e2cb4ca28f..de19106eaee 100644
--- a/spec/lib/gitlab/popen/runner_spec.rb
+++ b/spec/lib/gitlab/popen/runner_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Popen::Runner do
diff --git a/spec/lib/gitlab/popen_spec.rb b/spec/lib/gitlab/popen_spec.rb
index c1b84e9f077..29afd9df74e 100644
--- a/spec/lib/gitlab/popen_spec.rb
+++ b/spec/lib/gitlab/popen_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Popen do
diff --git a/spec/lib/gitlab/profiler_spec.rb b/spec/lib/gitlab/profiler_spec.rb
index 5af52db7a1f..a19392f4bcb 100644
--- a/spec/lib/gitlab/profiler_spec.rb
+++ b/spec/lib/gitlab/profiler_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Profiler do
diff --git a/spec/lib/gitlab/project_authorizations_spec.rb b/spec/lib/gitlab/project_authorizations_spec.rb
index 75e2d5e1319..82ccb42f8a6 100644
--- a/spec/lib/gitlab/project_authorizations_spec.rb
+++ b/spec/lib/gitlab/project_authorizations_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ProjectAuthorizations do
diff --git a/spec/lib/gitlab/project_search_results_spec.rb b/spec/lib/gitlab/project_search_results_spec.rb
index c7462500c82..0dbfcf96124 100644
--- a/spec/lib/gitlab/project_search_results_spec.rb
+++ b/spec/lib/gitlab/project_search_results_spec.rb
@@ -1,4 +1,6 @@
# coding: utf-8
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ProjectSearchResults do
diff --git a/spec/lib/gitlab/project_template_spec.rb b/spec/lib/gitlab/project_template_spec.rb
index c7c82d07508..83acd979a80 100644
--- a/spec/lib/gitlab/project_template_spec.rb
+++ b/spec/lib/gitlab/project_template_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ProjectTemplate do
diff --git a/spec/lib/gitlab/project_transfer_spec.rb b/spec/lib/gitlab/project_transfer_spec.rb
index 0b9b1f537b5..d54817ea02b 100644
--- a/spec/lib/gitlab/project_transfer_spec.rb
+++ b/spec/lib/gitlab/project_transfer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ProjectTransfer do
diff --git a/spec/lib/gitlab/prometheus/additional_metrics_parser_spec.rb b/spec/lib/gitlab/prometheus/additional_metrics_parser_spec.rb
index 1a108003bc2..3f97a69b5eb 100644
--- a/spec/lib/gitlab/prometheus/additional_metrics_parser_spec.rb
+++ b/spec/lib/gitlab/prometheus/additional_metrics_parser_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Prometheus::AdditionalMetricsParser do
diff --git a/spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb b/spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb
index c7169717fc1..4bdc57c8c04 100644
--- a/spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb
+++ b/spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Prometheus::Queries::AdditionalMetricsDeploymentQuery do
diff --git a/spec/lib/gitlab/prometheus/queries/additional_metrics_environment_query_spec.rb b/spec/lib/gitlab/prometheus/queries/additional_metrics_environment_query_spec.rb
index a6589f0c0a3..35dbdd55cfa 100644
--- a/spec/lib/gitlab/prometheus/queries/additional_metrics_environment_query_spec.rb
+++ b/spec/lib/gitlab/prometheus/queries/additional_metrics_environment_query_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Prometheus::Queries::AdditionalMetricsEnvironmentQuery do
diff --git a/spec/lib/gitlab/prometheus/queries/deployment_query_spec.rb b/spec/lib/gitlab/prometheus/queries/deployment_query_spec.rb
index ffe3ad85baa..0ad2de218fe 100644
--- a/spec/lib/gitlab/prometheus/queries/deployment_query_spec.rb
+++ b/spec/lib/gitlab/prometheus/queries/deployment_query_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Prometheus::Queries::DeploymentQuery do
diff --git a/spec/lib/gitlab/prometheus/queries/matched_metric_query_spec.rb b/spec/lib/gitlab/prometheus/queries/matched_metric_query_spec.rb
index 936447b8474..35034d814bf 100644
--- a/spec/lib/gitlab/prometheus/queries/matched_metric_query_spec.rb
+++ b/spec/lib/gitlab/prometheus/queries/matched_metric_query_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Prometheus::Queries::MatchedMetricQuery do
diff --git a/spec/lib/gitlab/prometheus_client_spec.rb b/spec/lib/gitlab/prometheus_client_spec.rb
index 0a4e8dbced5..86a1c14ed3f 100644
--- a/spec/lib/gitlab/prometheus_client_spec.rb
+++ b/spec/lib/gitlab/prometheus_client_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::PrometheusClient do
diff --git a/spec/lib/gitlab/query_limiting/active_support_subscriber_spec.rb b/spec/lib/gitlab/query_limiting/active_support_subscriber_spec.rb
index f8faeffb935..2db6d2fb60f 100644
--- a/spec/lib/gitlab/query_limiting/active_support_subscriber_spec.rb
+++ b/spec/lib/gitlab/query_limiting/active_support_subscriber_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::QueryLimiting::ActiveSupportSubscriber do
diff --git a/spec/lib/gitlab/query_limiting/middleware_spec.rb b/spec/lib/gitlab/query_limiting/middleware_spec.rb
index a04bcdecb4b..fb1c30118c2 100644
--- a/spec/lib/gitlab/query_limiting/middleware_spec.rb
+++ b/spec/lib/gitlab/query_limiting/middleware_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::QueryLimiting::Middleware do
diff --git a/spec/lib/gitlab/query_limiting/transaction_spec.rb b/spec/lib/gitlab/query_limiting/transaction_spec.rb
index b72b8574174..39d5a575efc 100644
--- a/spec/lib/gitlab/query_limiting/transaction_spec.rb
+++ b/spec/lib/gitlab/query_limiting/transaction_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::QueryLimiting::Transaction do
diff --git a/spec/lib/gitlab/query_limiting_spec.rb b/spec/lib/gitlab/query_limiting_spec.rb
index 42877b1e2dd..f0d0340cd6e 100644
--- a/spec/lib/gitlab/query_limiting_spec.rb
+++ b/spec/lib/gitlab/query_limiting_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::QueryLimiting do
diff --git a/spec/lib/gitlab/quick_actions/command_definition_spec.rb b/spec/lib/gitlab/quick_actions/command_definition_spec.rb
index 21f2c87a755..45b710adf07 100644
--- a/spec/lib/gitlab/quick_actions/command_definition_spec.rb
+++ b/spec/lib/gitlab/quick_actions/command_definition_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::QuickActions::CommandDefinition do
diff --git a/spec/lib/gitlab/quick_actions/dsl_spec.rb b/spec/lib/gitlab/quick_actions/dsl_spec.rb
index 78b9b3804c3..c98c36622f5 100644
--- a/spec/lib/gitlab/quick_actions/dsl_spec.rb
+++ b/spec/lib/gitlab/quick_actions/dsl_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::QuickActions::Dsl do
diff --git a/spec/lib/gitlab/quick_actions/extractor_spec.rb b/spec/lib/gitlab/quick_actions/extractor_spec.rb
index 873bb359d6e..f1acb5b7049 100644
--- a/spec/lib/gitlab/quick_actions/extractor_spec.rb
+++ b/spec/lib/gitlab/quick_actions/extractor_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::QuickActions::Extractor do
diff --git a/spec/lib/gitlab/quick_actions/spend_time_and_date_separator_spec.rb b/spec/lib/gitlab/quick_actions/spend_time_and_date_separator_spec.rb
index 8b58f0b3725..fd149cd1114 100644
--- a/spec/lib/gitlab/quick_actions/spend_time_and_date_separator_spec.rb
+++ b/spec/lib/gitlab/quick_actions/spend_time_and_date_separator_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::QuickActions::SpendTimeAndDateSeparator do
diff --git a/spec/lib/gitlab/quick_actions/substitution_definition_spec.rb b/spec/lib/gitlab/quick_actions/substitution_definition_spec.rb
index 1bb8bc51c96..e4f25bc35a9 100644
--- a/spec/lib/gitlab/quick_actions/substitution_definition_spec.rb
+++ b/spec/lib/gitlab/quick_actions/substitution_definition_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::QuickActions::SubstitutionDefinition do
diff --git a/spec/lib/gitlab/redis/cache_spec.rb b/spec/lib/gitlab/redis/cache_spec.rb
index 5a4f17cfcf6..0718998f981 100644
--- a/spec/lib/gitlab/redis/cache_spec.rb
+++ b/spec/lib/gitlab/redis/cache_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Redis::Cache do
diff --git a/spec/lib/gitlab/redis/queues_spec.rb b/spec/lib/gitlab/redis/queues_spec.rb
index 01ca25635a9..93207b6f469 100644
--- a/spec/lib/gitlab/redis/queues_spec.rb
+++ b/spec/lib/gitlab/redis/queues_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Redis::Queues do
diff --git a/spec/lib/gitlab/redis/shared_state_spec.rb b/spec/lib/gitlab/redis/shared_state_spec.rb
index 24b73745dc5..aa61fd99eb5 100644
--- a/spec/lib/gitlab/redis/shared_state_spec.rb
+++ b/spec/lib/gitlab/redis/shared_state_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Redis::SharedState do
diff --git a/spec/lib/gitlab/redis/wrapper_spec.rb b/spec/lib/gitlab/redis/wrapper_spec.rb
index 0c22a0d62cc..e4cc42130db 100644
--- a/spec/lib/gitlab/redis/wrapper_spec.rb
+++ b/spec/lib/gitlab/redis/wrapper_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Redis::Wrapper do
diff --git a/spec/lib/gitlab/reference_counter_spec.rb b/spec/lib/gitlab/reference_counter_spec.rb
index b2344d1870a..f9361d08faf 100644
--- a/spec/lib/gitlab/reference_counter_spec.rb
+++ b/spec/lib/gitlab/reference_counter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ReferenceCounter do
diff --git a/spec/lib/gitlab/regex_spec.rb b/spec/lib/gitlab/regex_spec.rb
index ba295386a55..e19210d8fbf 100644
--- a/spec/lib/gitlab/regex_spec.rb
+++ b/spec/lib/gitlab/regex_spec.rb
@@ -1,4 +1,6 @@
# coding: utf-8
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Regex do
diff --git a/spec/lib/gitlab/repo_path_spec.rb b/spec/lib/gitlab/repo_path_spec.rb
index 8fbda929064..cffd7cc89e7 100644
--- a/spec/lib/gitlab/repo_path_spec.rb
+++ b/spec/lib/gitlab/repo_path_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe ::Gitlab::RepoPath do
diff --git a/spec/lib/gitlab/repository_cache_adapter_spec.rb b/spec/lib/gitlab/repository_cache_adapter_spec.rb
index 04fc24b6205..fd1338b55a6 100644
--- a/spec/lib/gitlab/repository_cache_adapter_spec.rb
+++ b/spec/lib/gitlab/repository_cache_adapter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::RepositoryCacheAdapter do
diff --git a/spec/lib/gitlab/repository_cache_spec.rb b/spec/lib/gitlab/repository_cache_spec.rb
index 741ee12633f..6a684595eb8 100644
--- a/spec/lib/gitlab/repository_cache_spec.rb
+++ b/spec/lib/gitlab/repository_cache_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::RepositoryCache do
diff --git a/spec/lib/gitlab/repository_set_cache_spec.rb b/spec/lib/gitlab/repository_set_cache_spec.rb
index 9695e13d842..87e51f801e5 100644
--- a/spec/lib/gitlab/repository_set_cache_spec.rb
+++ b/spec/lib/gitlab/repository_set_cache_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::RepositorySetCache, :clean_gitlab_redis_cache do
diff --git a/spec/lib/gitlab/request_context_spec.rb b/spec/lib/gitlab/request_context_spec.rb
index 23e45aff1c5..a744f48da1f 100644
--- a/spec/lib/gitlab/request_context_spec.rb
+++ b/spec/lib/gitlab/request_context_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::RequestContext do
diff --git a/spec/lib/gitlab/request_forgery_protection_spec.rb b/spec/lib/gitlab/request_forgery_protection_spec.rb
index 305de613866..b7a3dc16eff 100644
--- a/spec/lib/gitlab/request_forgery_protection_spec.rb
+++ b/spec/lib/gitlab/request_forgery_protection_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::RequestForgeryProtection, :allow_forgery_protection do
diff --git a/spec/lib/gitlab/request_profiler/profile_spec.rb b/spec/lib/gitlab/request_profiler/profile_spec.rb
index b37ee558e1a..a75f3c66156 100644
--- a/spec/lib/gitlab/request_profiler/profile_spec.rb
+++ b/spec/lib/gitlab/request_profiler/profile_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
describe Gitlab::RequestProfiler::Profile do
diff --git a/spec/lib/gitlab/request_profiler_spec.rb b/spec/lib/gitlab/request_profiler_spec.rb
index 498c045b6cd..f157189a72d 100644
--- a/spec/lib/gitlab/request_profiler_spec.rb
+++ b/spec/lib/gitlab/request_profiler_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::RequestProfiler do
diff --git a/spec/lib/gitlab/route_map_spec.rb b/spec/lib/gitlab/route_map_spec.rb
index a39c774429e..d5e70b91fb4 100644
--- a/spec/lib/gitlab/route_map_spec.rb
+++ b/spec/lib/gitlab/route_map_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::RouteMap do
diff --git a/spec/lib/gitlab/routing_spec.rb b/spec/lib/gitlab/routing_spec.rb
index 01d5acfc15b..965564cb83b 100644
--- a/spec/lib/gitlab/routing_spec.rb
+++ b/spec/lib/gitlab/routing_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Routing do
diff --git a/spec/lib/gitlab/sanitizers/exif_spec.rb b/spec/lib/gitlab/sanitizers/exif_spec.rb
index bd5f330c7a1..22c5f27dc6d 100644
--- a/spec/lib/gitlab/sanitizers/exif_spec.rb
+++ b/spec/lib/gitlab/sanitizers/exif_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sanitizers::Exif do
diff --git a/spec/lib/gitlab/sanitizers/svg_spec.rb b/spec/lib/gitlab/sanitizers/svg_spec.rb
index df46a874528..a8c7495376d 100644
--- a/spec/lib/gitlab/sanitizers/svg_spec.rb
+++ b/spec/lib/gitlab/sanitizers/svg_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sanitizers::SVG do
diff --git a/spec/lib/gitlab/search/found_blob_spec.rb b/spec/lib/gitlab/search/found_blob_spec.rb
index da263bc7523..3496fb29836 100644
--- a/spec/lib/gitlab/search/found_blob_spec.rb
+++ b/spec/lib/gitlab/search/found_blob_spec.rb
@@ -1,4 +1,5 @@
# coding: utf-8
+# frozen_string_literal: true
require 'spec_helper'
@@ -108,7 +109,7 @@ describe Gitlab::Search::FoundBlob do
end
context 'with ISO-8859-1' do
- let(:search_result) { "master:encoding/iso8859.txt\x001\x00\xC4\xFC\nmaster:encoding/iso8859.txt\x002\x00\nmaster:encoding/iso8859.txt\x003\x00foo\n".force_encoding(Encoding::ASCII_8BIT) }
+ let(:search_result) { (+"master:encoding/iso8859.txt\x001\x00\xC4\xFC\nmaster:encoding/iso8859.txt\x002\x00\nmaster:encoding/iso8859.txt\x003\x00foo\n").force_encoding(Encoding::ASCII_8BIT) }
it 'returns results as UTF-8' do
expect(subject.filename).to eq('encoding/iso8859.txt')
diff --git a/spec/lib/gitlab/search/query_spec.rb b/spec/lib/gitlab/search/query_spec.rb
index 2d00428fffa..112e9a59f04 100644
--- a/spec/lib/gitlab/search/query_spec.rb
+++ b/spec/lib/gitlab/search/query_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Search::Query do
diff --git a/spec/lib/gitlab/search_results_spec.rb b/spec/lib/gitlab/search_results_spec.rb
index c287da19343..5621c686b8a 100644
--- a/spec/lib/gitlab/search_results_spec.rb
+++ b/spec/lib/gitlab/search_results_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SearchResults do
diff --git a/spec/lib/gitlab/sentry_spec.rb b/spec/lib/gitlab/sentry_spec.rb
index a48cc0d128a..9c4f3b8f42e 100644
--- a/spec/lib/gitlab/sentry_spec.rb
+++ b/spec/lib/gitlab/sentry_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sentry do
diff --git a/spec/lib/gitlab/serializer/ci/variables_spec.rb b/spec/lib/gitlab/serializer/ci/variables_spec.rb
index 1d1fd5b0763..900508420c9 100644
--- a/spec/lib/gitlab/serializer/ci/variables_spec.rb
+++ b/spec/lib/gitlab/serializer/ci/variables_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
describe Gitlab::Serializer::Ci::Variables do
diff --git a/spec/lib/gitlab/serializer/pagination_spec.rb b/spec/lib/gitlab/serializer/pagination_spec.rb
index c54be78f050..1e7f441f258 100644
--- a/spec/lib/gitlab/serializer/pagination_spec.rb
+++ b/spec/lib/gitlab/serializer/pagination_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Serializer::Pagination do
diff --git a/spec/lib/gitlab/shard_health_cache_spec.rb b/spec/lib/gitlab/shard_health_cache_spec.rb
index e1a69261939..f747849b5e9 100644
--- a/spec/lib/gitlab/shard_health_cache_spec.rb
+++ b/spec/lib/gitlab/shard_health_cache_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::ShardHealthCache, :clean_gitlab_redis_cache do
diff --git a/spec/lib/gitlab/shell_spec.rb b/spec/lib/gitlab/shell_spec.rb
index bce2e754176..0ba16b93ee7 100644
--- a/spec/lib/gitlab/shell_spec.rb
+++ b/spec/lib/gitlab/shell_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'stringio'
diff --git a/spec/lib/gitlab/sherlock/collection_spec.rb b/spec/lib/gitlab/sherlock/collection_spec.rb
index 873ed14f804..bdc89c3d3cf 100644
--- a/spec/lib/gitlab/sherlock/collection_spec.rb
+++ b/spec/lib/gitlab/sherlock/collection_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sherlock::Collection do
diff --git a/spec/lib/gitlab/sherlock/file_sample_spec.rb b/spec/lib/gitlab/sherlock/file_sample_spec.rb
index 394421504e0..b09ba5c62dc 100644
--- a/spec/lib/gitlab/sherlock/file_sample_spec.rb
+++ b/spec/lib/gitlab/sherlock/file_sample_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sherlock::FileSample do
diff --git a/spec/lib/gitlab/sherlock/line_profiler_spec.rb b/spec/lib/gitlab/sherlock/line_profiler_spec.rb
index f2f8040fa0b..c1997606839 100644
--- a/spec/lib/gitlab/sherlock/line_profiler_spec.rb
+++ b/spec/lib/gitlab/sherlock/line_profiler_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sherlock::LineProfiler do
diff --git a/spec/lib/gitlab/sherlock/line_sample_spec.rb b/spec/lib/gitlab/sherlock/line_sample_spec.rb
index 5f02f6a3213..b68e8cc0266 100644
--- a/spec/lib/gitlab/sherlock/line_sample_spec.rb
+++ b/spec/lib/gitlab/sherlock/line_sample_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sherlock::LineSample do
diff --git a/spec/lib/gitlab/sherlock/location_spec.rb b/spec/lib/gitlab/sherlock/location_spec.rb
index b295a624b35..7b40c84c2d1 100644
--- a/spec/lib/gitlab/sherlock/location_spec.rb
+++ b/spec/lib/gitlab/sherlock/location_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sherlock::Location do
diff --git a/spec/lib/gitlab/sherlock/middleware_spec.rb b/spec/lib/gitlab/sherlock/middleware_spec.rb
index 2016023df06..8d6e362f622 100644
--- a/spec/lib/gitlab/sherlock/middleware_spec.rb
+++ b/spec/lib/gitlab/sherlock/middleware_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sherlock::Middleware do
diff --git a/spec/lib/gitlab/sherlock/query_spec.rb b/spec/lib/gitlab/sherlock/query_spec.rb
index 426071c7f92..13c7e6f8f8b 100644
--- a/spec/lib/gitlab/sherlock/query_spec.rb
+++ b/spec/lib/gitlab/sherlock/query_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sherlock::Query do
diff --git a/spec/lib/gitlab/sherlock/transaction_spec.rb b/spec/lib/gitlab/sherlock/transaction_spec.rb
index 4a14dfbec56..2245c3ee8e2 100644
--- a/spec/lib/gitlab/sherlock/transaction_spec.rb
+++ b/spec/lib/gitlab/sherlock/transaction_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Sherlock::Transaction do
diff --git a/spec/lib/gitlab/sidekiq_config_spec.rb b/spec/lib/gitlab/sidekiq_config_spec.rb
index 0c66d764851..1e8ccb447b1 100644
--- a/spec/lib/gitlab/sidekiq_config_spec.rb
+++ b/spec/lib/gitlab/sidekiq_config_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'rails_helper'
describe Gitlab::SidekiqConfig do
diff --git a/spec/lib/gitlab/sidekiq_logging/json_formatter_spec.rb b/spec/lib/gitlab/sidekiq_logging/json_formatter_spec.rb
index fed9aeba30c..a2cb38ec5b1 100644
--- a/spec/lib/gitlab/sidekiq_logging/json_formatter_spec.rb
+++ b/spec/lib/gitlab/sidekiq_logging/json_formatter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SidekiqLogging::JSONFormatter do
diff --git a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
index c09db4af8d8..1b89c094a6b 100644
--- a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
+++ b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SidekiqLogging::StructuredLogger do
diff --git a/spec/lib/gitlab/sidekiq_middleware/memory_killer_spec.rb b/spec/lib/gitlab/sidekiq_middleware/memory_killer_spec.rb
index 1de9a644610..bf3bc8e1add 100644
--- a/spec/lib/gitlab/sidekiq_middleware/memory_killer_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware/memory_killer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SidekiqMiddleware::MemoryKiller do
diff --git a/spec/lib/gitlab/sidekiq_signals_spec.rb b/spec/lib/gitlab/sidekiq_signals_spec.rb
index 77ecd1840d2..10f1bad32cd 100644
--- a/spec/lib/gitlab/sidekiq_signals_spec.rb
+++ b/spec/lib/gitlab/sidekiq_signals_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SidekiqSignals do
diff --git a/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb b/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb
index 37d9e1d3e6b..1ca8cea66fc 100644
--- a/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb
+++ b/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SidekiqStatus::ClientMiddleware do
diff --git a/spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb b/spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb
index 04e09d3dec8..40bcb49d1d3 100644
--- a/spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb
+++ b/spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SidekiqStatus::ServerMiddleware do
diff --git a/spec/lib/gitlab/sidekiq_status_spec.rb b/spec/lib/gitlab/sidekiq_status_spec.rb
index 884f27b212c..7b5c75b2f3b 100644
--- a/spec/lib/gitlab/sidekiq_status_spec.rb
+++ b/spec/lib/gitlab/sidekiq_status_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SidekiqStatus do
diff --git a/spec/lib/gitlab/sidekiq_versioning/manager_spec.rb b/spec/lib/gitlab/sidekiq_versioning/manager_spec.rb
index 7debf70a16f..2aa7d1fd6d8 100644
--- a/spec/lib/gitlab/sidekiq_versioning/manager_spec.rb
+++ b/spec/lib/gitlab/sidekiq_versioning/manager_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SidekiqVersioning::Manager do
diff --git a/spec/lib/gitlab/sidekiq_versioning_spec.rb b/spec/lib/gitlab/sidekiq_versioning_spec.rb
index fa6d42e730d..dade5961775 100644
--- a/spec/lib/gitlab/sidekiq_versioning_spec.rb
+++ b/spec/lib/gitlab/sidekiq_versioning_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SidekiqVersioning, :sidekiq, :redis do
diff --git a/spec/lib/gitlab/slash_commands/command_spec.rb b/spec/lib/gitlab/slash_commands/command_spec.rb
index eceacac58af..c4ea8cbf2b1 100644
--- a/spec/lib/gitlab/slash_commands/command_spec.rb
+++ b/spec/lib/gitlab/slash_commands/command_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::Command do
diff --git a/spec/lib/gitlab/slash_commands/deploy_spec.rb b/spec/lib/gitlab/slash_commands/deploy_spec.rb
index 25f3e8a0409..93a724d8e12 100644
--- a/spec/lib/gitlab/slash_commands/deploy_spec.rb
+++ b/spec/lib/gitlab/slash_commands/deploy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::Deploy do
diff --git a/spec/lib/gitlab/slash_commands/issue_move_spec.rb b/spec/lib/gitlab/slash_commands/issue_move_spec.rb
index 9a990e1fad7..962ac3668bc 100644
--- a/spec/lib/gitlab/slash_commands/issue_move_spec.rb
+++ b/spec/lib/gitlab/slash_commands/issue_move_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::IssueMove, service: true do
diff --git a/spec/lib/gitlab/slash_commands/issue_new_spec.rb b/spec/lib/gitlab/slash_commands/issue_new_spec.rb
index 59de11766d8..90f0518a63e 100644
--- a/spec/lib/gitlab/slash_commands/issue_new_spec.rb
+++ b/spec/lib/gitlab/slash_commands/issue_new_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::IssueNew do
diff --git a/spec/lib/gitlab/slash_commands/issue_search_spec.rb b/spec/lib/gitlab/slash_commands/issue_search_spec.rb
index 47787307990..b766a9a1361 100644
--- a/spec/lib/gitlab/slash_commands/issue_search_spec.rb
+++ b/spec/lib/gitlab/slash_commands/issue_search_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::IssueSearch do
diff --git a/spec/lib/gitlab/slash_commands/issue_show_spec.rb b/spec/lib/gitlab/slash_commands/issue_show_spec.rb
index 5c4ba2736ba..e53f79dcd86 100644
--- a/spec/lib/gitlab/slash_commands/issue_show_spec.rb
+++ b/spec/lib/gitlab/slash_commands/issue_show_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::IssueShow do
diff --git a/spec/lib/gitlab/slash_commands/presenters/access_spec.rb b/spec/lib/gitlab/slash_commands/presenters/access_spec.rb
index ef3d217f7be..286fec892e6 100644
--- a/spec/lib/gitlab/slash_commands/presenters/access_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/access_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::Presenters::Access do
diff --git a/spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb b/spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb
index d16d122c64e..9c2e9ab982f 100644
--- a/spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::Presenters::Deploy do
diff --git a/spec/lib/gitlab/slash_commands/presenters/issue_move_spec.rb b/spec/lib/gitlab/slash_commands/presenters/issue_move_spec.rb
index 58c341a284e..56b64d32192 100644
--- a/spec/lib/gitlab/slash_commands/presenters/issue_move_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/issue_move_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::Presenters::IssueMove do
diff --git a/spec/lib/gitlab/slash_commands/presenters/issue_new_spec.rb b/spec/lib/gitlab/slash_commands/presenters/issue_new_spec.rb
index 76e4bad88fd..f926783fbea 100644
--- a/spec/lib/gitlab/slash_commands/presenters/issue_new_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/issue_new_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::Presenters::IssueNew do
diff --git a/spec/lib/gitlab/slash_commands/presenters/issue_search_spec.rb b/spec/lib/gitlab/slash_commands/presenters/issue_search_spec.rb
index 5a7ec0685fe..e1c011133c4 100644
--- a/spec/lib/gitlab/slash_commands/presenters/issue_search_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/issue_search_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::Presenters::IssueSearch do
diff --git a/spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb b/spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb
index 8f607d7a9c9..56d6bf1c788 100644
--- a/spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SlashCommands::Presenters::IssueShow do
diff --git a/spec/lib/gitlab/snippet_search_results_spec.rb b/spec/lib/gitlab/snippet_search_results_spec.rb
index 35df38f052b..89d290aaa81 100644
--- a/spec/lib/gitlab/snippet_search_results_spec.rb
+++ b/spec/lib/gitlab/snippet_search_results_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SnippetSearchResults do
diff --git a/spec/lib/gitlab/sql/cte_spec.rb b/spec/lib/gitlab/sql/cte_spec.rb
index 5d2164491b5..e6194924f5a 100644
--- a/spec/lib/gitlab/sql/cte_spec.rb
+++ b/spec/lib/gitlab/sql/cte_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SQL::CTE do
diff --git a/spec/lib/gitlab/sql/glob_spec.rb b/spec/lib/gitlab/sql/glob_spec.rb
index 3147b52dcc5..83eed309ecc 100644
--- a/spec/lib/gitlab/sql/glob_spec.rb
+++ b/spec/lib/gitlab/sql/glob_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SQL::Glob do
diff --git a/spec/lib/gitlab/sql/pattern_spec.rb b/spec/lib/gitlab/sql/pattern_spec.rb
index 98838712eae..31944d51b3c 100644
--- a/spec/lib/gitlab/sql/pattern_spec.rb
+++ b/spec/lib/gitlab/sql/pattern_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SQL::Pattern do
diff --git a/spec/lib/gitlab/sql/recursive_cte_spec.rb b/spec/lib/gitlab/sql/recursive_cte_spec.rb
index 407a4d8a247..20e36c224b0 100644
--- a/spec/lib/gitlab/sql/recursive_cte_spec.rb
+++ b/spec/lib/gitlab/sql/recursive_cte_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SQL::RecursiveCTE do
diff --git a/spec/lib/gitlab/sql/union_spec.rb b/spec/lib/gitlab/sql/union_spec.rb
index fe6422c32b6..f8f6da19fa5 100644
--- a/spec/lib/gitlab/sql/union_spec.rb
+++ b/spec/lib/gitlab/sql/union_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SQL::Union do
diff --git a/spec/lib/gitlab/ssh_public_key_spec.rb b/spec/lib/gitlab/ssh_public_key_spec.rb
index a6ea07e8b6d..f8becb0c796 100644
--- a/spec/lib/gitlab/ssh_public_key_spec.rb
+++ b/spec/lib/gitlab/ssh_public_key_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::SSHPublicKey, lib: true do
diff --git a/spec/lib/gitlab/string_placeholder_replacer_spec.rb b/spec/lib/gitlab/string_placeholder_replacer_spec.rb
index 7a03ea4154c..0295bf1265f 100644
--- a/spec/lib/gitlab/string_placeholder_replacer_spec.rb
+++ b/spec/lib/gitlab/string_placeholder_replacer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::StringPlaceholderReplacer do
diff --git a/spec/lib/gitlab/string_range_marker_spec.rb b/spec/lib/gitlab/string_range_marker_spec.rb
index 6bc02459dbd..7ed43db3d10 100644
--- a/spec/lib/gitlab/string_range_marker_spec.rb
+++ b/spec/lib/gitlab/string_range_marker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::StringRangeMarker do
diff --git a/spec/lib/gitlab/string_regex_marker_spec.rb b/spec/lib/gitlab/string_regex_marker_spec.rb
index 37b1298b962..2b19edbe7f9 100644
--- a/spec/lib/gitlab/string_regex_marker_spec.rb
+++ b/spec/lib/gitlab/string_regex_marker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::StringRegexMarker do
diff --git a/spec/lib/gitlab/tcp_checker_spec.rb b/spec/lib/gitlab/tcp_checker_spec.rb
index 4acf0334496..49f04f269ae 100644
--- a/spec/lib/gitlab/tcp_checker_spec.rb
+++ b/spec/lib/gitlab/tcp_checker_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::TcpChecker do
diff --git a/spec/lib/gitlab/template/finders/global_template_finder_spec.rb b/spec/lib/gitlab/template/finders/global_template_finder_spec.rb
index c7f58fbd2a5..082ffa855b7 100644
--- a/spec/lib/gitlab/template/finders/global_template_finder_spec.rb
+++ b/spec/lib/gitlab/template/finders/global_template_finder_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Template::Finders::GlobalTemplateFinder do
diff --git a/spec/lib/gitlab/template/finders/repo_template_finders_spec.rb b/spec/lib/gitlab/template/finders/repo_template_finders_spec.rb
index e329d55d837..c8f2a37c5d6 100644
--- a/spec/lib/gitlab/template/finders/repo_template_finders_spec.rb
+++ b/spec/lib/gitlab/template/finders/repo_template_finders_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Template::Finders::RepoTemplateFinder do
diff --git a/spec/lib/gitlab/template/gitignore_template_spec.rb b/spec/lib/gitlab/template/gitignore_template_spec.rb
index 97797f42aaa..e8f632889ad 100644
--- a/spec/lib/gitlab/template/gitignore_template_spec.rb
+++ b/spec/lib/gitlab/template/gitignore_template_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Template::GitignoreTemplate do
diff --git a/spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb b/spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb
index 5f0a7e925ca..52e100768a7 100644
--- a/spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb
+++ b/spec/lib/gitlab/template/gitlab_ci_yml_template_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Template::GitlabCiYmlTemplate do
diff --git a/spec/lib/gitlab/template/issue_template_spec.rb b/spec/lib/gitlab/template/issue_template_spec.rb
index 7098499f996..54e46d3a9ec 100644
--- a/spec/lib/gitlab/template/issue_template_spec.rb
+++ b/spec/lib/gitlab/template/issue_template_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Template::IssueTemplate do
diff --git a/spec/lib/gitlab/template/merge_request_template_spec.rb b/spec/lib/gitlab/template/merge_request_template_spec.rb
index bd7ff64aa8a..bbc184d4dfc 100644
--- a/spec/lib/gitlab/template/merge_request_template_spec.rb
+++ b/spec/lib/gitlab/template/merge_request_template_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Template::MergeRequestTemplate do
diff --git a/spec/lib/gitlab/themes_spec.rb b/spec/lib/gitlab/themes_spec.rb
index a8213988f70..e0278eb9c7f 100644
--- a/spec/lib/gitlab/themes_spec.rb
+++ b/spec/lib/gitlab/themes_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Themes, lib: true do
diff --git a/spec/lib/gitlab/tree_summary_spec.rb b/spec/lib/gitlab/tree_summary_spec.rb
index e22f898dc4c..e15463ed0eb 100644
--- a/spec/lib/gitlab/tree_summary_spec.rb
+++ b/spec/lib/gitlab/tree_summary_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::TreeSummary do
diff --git a/spec/lib/gitlab/untrusted_regexp/ruby_syntax_spec.rb b/spec/lib/gitlab/untrusted_regexp/ruby_syntax_spec.rb
index f1882e03581..68402e64012 100644
--- a/spec/lib/gitlab/untrusted_regexp/ruby_syntax_spec.rb
+++ b/spec/lib/gitlab/untrusted_regexp/ruby_syntax_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
require 'support/shared_examples/malicious_regexp_shared_examples'
require 'support/helpers/stub_feature_flags'
diff --git a/spec/lib/gitlab/untrusted_regexp_spec.rb b/spec/lib/gitlab/untrusted_regexp_spec.rb
index 9d483f13a5e..4cc21e94a83 100644
--- a/spec/lib/gitlab/untrusted_regexp_spec.rb
+++ b/spec/lib/gitlab/untrusted_regexp_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
require 'support/shared_examples/malicious_regexp_shared_examples'
diff --git a/spec/lib/gitlab/uploads_transfer_spec.rb b/spec/lib/gitlab/uploads_transfer_spec.rb
index 4275e7b015b..16560fc8f12 100644
--- a/spec/lib/gitlab/uploads_transfer_spec.rb
+++ b/spec/lib/gitlab/uploads_transfer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::UploadsTransfer do
diff --git a/spec/lib/gitlab/url_blocker_spec.rb b/spec/lib/gitlab/url_blocker_spec.rb
index 45d9022abeb..df8a1f82f81 100644
--- a/spec/lib/gitlab/url_blocker_spec.rb
+++ b/spec/lib/gitlab/url_blocker_spec.rb
@@ -1,4 +1,6 @@
# coding: utf-8
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::UrlBlocker do
diff --git a/spec/lib/gitlab/url_builder_spec.rb b/spec/lib/gitlab/url_builder_spec.rb
index bbcb92608d8..08d3c638f9e 100644
--- a/spec/lib/gitlab/url_builder_spec.rb
+++ b/spec/lib/gitlab/url_builder_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::UrlBuilder do
diff --git a/spec/lib/gitlab/url_sanitizer_spec.rb b/spec/lib/gitlab/url_sanitizer_spec.rb
index 7242255d535..b39609c594b 100644
--- a/spec/lib/gitlab/url_sanitizer_spec.rb
+++ b/spec/lib/gitlab/url_sanitizer_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::UrlSanitizer do
diff --git a/spec/lib/gitlab/user_access_spec.rb b/spec/lib/gitlab/user_access_spec.rb
index 9da06bb40f4..c25bd14fcba 100644
--- a/spec/lib/gitlab/user_access_spec.rb
+++ b/spec/lib/gitlab/user_access_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::UserAccess do
diff --git a/spec/lib/gitlab/utils/deep_size_spec.rb b/spec/lib/gitlab/utils/deep_size_spec.rb
index 1e619a15980..47dfc04f46f 100644
--- a/spec/lib/gitlab/utils/deep_size_spec.rb
+++ b/spec/lib/gitlab/utils/deep_size_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Utils::DeepSize do
diff --git a/spec/lib/gitlab/utils/merge_hash_spec.rb b/spec/lib/gitlab/utils/merge_hash_spec.rb
index 4fa7bb31301..72620e549a9 100644
--- a/spec/lib/gitlab/utils/merge_hash_spec.rb
+++ b/spec/lib/gitlab/utils/merge_hash_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Utils::MergeHash do
describe '.crush' do
diff --git a/spec/lib/gitlab/utils/override_spec.rb b/spec/lib/gitlab/utils/override_spec.rb
index 9e7c97f8095..5855c4374a9 100644
--- a/spec/lib/gitlab/utils/override_spec.rb
+++ b/spec/lib/gitlab/utils/override_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
describe Gitlab::Utils::Override do
diff --git a/spec/lib/gitlab/utils/sanitize_node_link_spec.rb b/spec/lib/gitlab/utils/sanitize_node_link_spec.rb
index 064c2707d06..80b0935a7ed 100644
--- a/spec/lib/gitlab/utils/sanitize_node_link_spec.rb
+++ b/spec/lib/gitlab/utils/sanitize_node_link_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Utils::SanitizeNodeLink do
diff --git a/spec/lib/gitlab/utils/strong_memoize_spec.rb b/spec/lib/gitlab/utils/strong_memoize_spec.rb
index 473f8100771..26baaf873a8 100644
--- a/spec/lib/gitlab/utils/strong_memoize_spec.rb
+++ b/spec/lib/gitlab/utils/strong_memoize_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Utils::StrongMemoize do
diff --git a/spec/lib/gitlab/utils_spec.rb b/spec/lib/gitlab/utils_spec.rb
index 0c20b3aa4c8..890918d4a7c 100644
--- a/spec/lib/gitlab/utils_spec.rb
+++ b/spec/lib/gitlab/utils_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Utils do
diff --git a/spec/lib/gitlab/verify/job_artifacts_spec.rb b/spec/lib/gitlab/verify/job_artifacts_spec.rb
index 6e916a56564..b50ec1528d4 100644
--- a/spec/lib/gitlab/verify/job_artifacts_spec.rb
+++ b/spec/lib/gitlab/verify/job_artifacts_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Verify::JobArtifacts do
diff --git a/spec/lib/gitlab/verify/lfs_objects_spec.rb b/spec/lib/gitlab/verify/lfs_objects_spec.rb
index 2feaedd6f14..c27c9b6efa1 100644
--- a/spec/lib/gitlab/verify/lfs_objects_spec.rb
+++ b/spec/lib/gitlab/verify/lfs_objects_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Verify::LfsObjects do
diff --git a/spec/lib/gitlab/verify/uploads_spec.rb b/spec/lib/gitlab/verify/uploads_spec.rb
index 38c30fab1ba..a3d3f5d46f3 100644
--- a/spec/lib/gitlab/verify/uploads_spec.rb
+++ b/spec/lib/gitlab/verify/uploads_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Verify::Uploads do
diff --git a/spec/lib/gitlab/version_info_spec.rb b/spec/lib/gitlab/version_info_spec.rb
index 30035c79e58..8c14b187410 100644
--- a/spec/lib/gitlab/version_info_spec.rb
+++ b/spec/lib/gitlab/version_info_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe 'Gitlab::VersionInfo' do
diff --git a/spec/lib/gitlab/view/presenter/base_spec.rb b/spec/lib/gitlab/view/presenter/base_spec.rb
index 02c2fd47197..e196ab23482 100644
--- a/spec/lib/gitlab/view/presenter/base_spec.rb
+++ b/spec/lib/gitlab/view/presenter/base_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::View::Presenter::Base do
diff --git a/spec/lib/gitlab/view/presenter/delegated_spec.rb b/spec/lib/gitlab/view/presenter/delegated_spec.rb
index 940a2ce6ebd..0a21cd1358e 100644
--- a/spec/lib/gitlab/view/presenter/delegated_spec.rb
+++ b/spec/lib/gitlab/view/presenter/delegated_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::View::Presenter::Delegated do
diff --git a/spec/lib/gitlab/view/presenter/factory_spec.rb b/spec/lib/gitlab/view/presenter/factory_spec.rb
index 6120bafb2e3..515a1b0a8e4 100644
--- a/spec/lib/gitlab/view/presenter/factory_spec.rb
+++ b/spec/lib/gitlab/view/presenter/factory_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::View::Presenter::Factory do
diff --git a/spec/lib/gitlab/view/presenter/simple_spec.rb b/spec/lib/gitlab/view/presenter/simple_spec.rb
index 1795ed2405b..70e2b170a36 100644
--- a/spec/lib/gitlab/view/presenter/simple_spec.rb
+++ b/spec/lib/gitlab/view/presenter/simple_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::View::Presenter::Simple do
diff --git a/spec/lib/gitlab/visibility_level_spec.rb b/spec/lib/gitlab/visibility_level_spec.rb
index 0a170a157fe..75dc7d8e6d1 100644
--- a/spec/lib/gitlab/visibility_level_spec.rb
+++ b/spec/lib/gitlab/visibility_level_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::VisibilityLevel do
diff --git a/spec/lib/gitlab/wiki_file_finder_spec.rb b/spec/lib/gitlab/wiki_file_finder_spec.rb
index 025d1203dc5..fdd95d5e6e6 100644
--- a/spec/lib/gitlab/wiki_file_finder_spec.rb
+++ b/spec/lib/gitlab/wiki_file_finder_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::WikiFileFinder do
diff --git a/spec/lib/gitlab/workhorse_spec.rb b/spec/lib/gitlab/workhorse_spec.rb
index 451e18ed91b..5c5ff46112f 100644
--- a/spec/lib/gitlab/workhorse_spec.rb
+++ b/spec/lib/gitlab/workhorse_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Gitlab::Workhorse do
diff --git a/spec/lib/gitlab_spec.rb b/spec/lib/gitlab_spec.rb
index c293f58c9cb..cbc5649fc09 100644
--- a/spec/lib/gitlab_spec.rb
+++ b/spec/lib/gitlab_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
require_dependency 'gitlab'
diff --git a/spec/lib/google_api/auth_spec.rb b/spec/lib/google_api/auth_spec.rb
index 87a3f43274f..a25004ac385 100644
--- a/spec/lib/google_api/auth_spec.rb
+++ b/spec/lib/google_api/auth_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe GoogleApi::Auth do
diff --git a/spec/lib/google_api/cloud_platform/client_spec.rb b/spec/lib/google_api/cloud_platform/client_spec.rb
index 1fefc947636..c24998d32f8 100644
--- a/spec/lib/google_api/cloud_platform/client_spec.rb
+++ b/spec/lib/google_api/cloud_platform/client_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe GoogleApi::CloudPlatform::Client do
diff --git a/spec/lib/json_web_token/rsa_token_spec.rb b/spec/lib/json_web_token/rsa_token_spec.rb
index a3c54651e80..a127c787e28 100644
--- a/spec/lib/json_web_token/rsa_token_spec.rb
+++ b/spec/lib/json_web_token/rsa_token_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
describe JSONWebToken::RSAToken do
let(:rsa_key) do
OpenSSL::PKey::RSA.new <<-eos.strip_heredoc
diff --git a/spec/lib/json_web_token/token_spec.rb b/spec/lib/json_web_token/token_spec.rb
index d7e7560d962..916d11ce0ed 100644
--- a/spec/lib/json_web_token/token_spec.rb
+++ b/spec/lib/json_web_token/token_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
describe JSONWebToken::Token do
let(:token) { described_class.new }
diff --git a/spec/lib/mattermost/client_spec.rb b/spec/lib/mattermost/client_spec.rb
index dc11a414717..5fe35eb5f93 100644
--- a/spec/lib/mattermost/client_spec.rb
+++ b/spec/lib/mattermost/client_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Mattermost::Client do
diff --git a/spec/lib/mattermost/command_spec.rb b/spec/lib/mattermost/command_spec.rb
index 7c194749dfb..f8c451a1522 100644
--- a/spec/lib/mattermost/command_spec.rb
+++ b/spec/lib/mattermost/command_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Mattermost::Command do
diff --git a/spec/lib/mattermost/session_spec.rb b/spec/lib/mattermost/session_spec.rb
index 346455067a7..ea12bd76c8d 100644
--- a/spec/lib/mattermost/session_spec.rb
+++ b/spec/lib/mattermost/session_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Mattermost::Session, type: :request do
diff --git a/spec/lib/mattermost/team_spec.rb b/spec/lib/mattermost/team_spec.rb
index 030aa5d06a8..2823dab67c9 100644
--- a/spec/lib/mattermost/team_spec.rb
+++ b/spec/lib/mattermost/team_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe Mattermost::Team do
diff --git a/spec/lib/microsoft_teams/activity_spec.rb b/spec/lib/microsoft_teams/activity_spec.rb
index 7890ae2e7b0..3fad2437f3e 100644
--- a/spec/lib/microsoft_teams/activity_spec.rb
+++ b/spec/lib/microsoft_teams/activity_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe MicrosoftTeams::Activity do
diff --git a/spec/lib/microsoft_teams/notifier_spec.rb b/spec/lib/microsoft_teams/notifier_spec.rb
index 2aaa7c24ad8..64ab8d85807 100644
--- a/spec/lib/microsoft_teams/notifier_spec.rb
+++ b/spec/lib/microsoft_teams/notifier_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe MicrosoftTeams::Notifier do
diff --git a/spec/lib/milestone_array_spec.rb b/spec/lib/milestone_array_spec.rb
index df91677b925..375cb87dde6 100644
--- a/spec/lib/milestone_array_spec.rb
+++ b/spec/lib/milestone_array_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe MilestoneArray do
diff --git a/spec/lib/object_storage/direct_upload_spec.rb b/spec/lib/object_storage/direct_upload_spec.rb
index 8ccbd90ddb8..fae0c636bdc 100644
--- a/spec/lib/object_storage/direct_upload_spec.rb
+++ b/spec/lib/object_storage/direct_upload_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe ObjectStorage::DirectUpload do
diff --git a/spec/lib/omni_auth/strategies/jwt_spec.rb b/spec/lib/omni_auth/strategies/jwt_spec.rb
index c1eaf0bb0bf..bdf3ea6be98 100644
--- a/spec/lib/omni_auth/strategies/jwt_spec.rb
+++ b/spec/lib/omni_auth/strategies/jwt_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe OmniAuth::Strategies::Jwt do
diff --git a/spec/lib/rspec_flaky/config_spec.rb b/spec/lib/rspec_flaky/config_spec.rb
index 4a71b1feebd..13b2219267b 100644
--- a/spec/lib/rspec_flaky/config_spec.rb
+++ b/spec/lib/rspec_flaky/config_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe RspecFlaky::Config, :aggregate_failures do
diff --git a/spec/lib/rspec_flaky/example_spec.rb b/spec/lib/rspec_flaky/example_spec.rb
index 5b4fd5ddf3e..4679dd818db 100644
--- a/spec/lib/rspec_flaky/example_spec.rb
+++ b/spec/lib/rspec_flaky/example_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe RspecFlaky::Example do
diff --git a/spec/lib/rspec_flaky/flaky_example_spec.rb b/spec/lib/rspec_flaky/flaky_example_spec.rb
index d19c34bebb3..092bbc781a5 100644
--- a/spec/lib/rspec_flaky/flaky_example_spec.rb
+++ b/spec/lib/rspec_flaky/flaky_example_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe RspecFlaky::FlakyExample, :aggregate_failures do
diff --git a/spec/lib/rspec_flaky/flaky_examples_collection_spec.rb b/spec/lib/rspec_flaky/flaky_examples_collection_spec.rb
index 6731a27ed17..2e224cda61b 100644
--- a/spec/lib/rspec_flaky/flaky_examples_collection_spec.rb
+++ b/spec/lib/rspec_flaky/flaky_examples_collection_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe RspecFlaky::FlakyExamplesCollection, :aggregate_failures do
diff --git a/spec/lib/rspec_flaky/listener_spec.rb b/spec/lib/rspec_flaky/listener_spec.rb
index ef085445081..44b8d99b74f 100644
--- a/spec/lib/rspec_flaky/listener_spec.rb
+++ b/spec/lib/rspec_flaky/listener_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe RspecFlaky::Listener, :aggregate_failures do
diff --git a/spec/lib/rspec_flaky/report_spec.rb b/spec/lib/rspec_flaky/report_spec.rb
index 7d57d99f7e5..6a98a7a4e6b 100644
--- a/spec/lib/rspec_flaky/report_spec.rb
+++ b/spec/lib/rspec_flaky/report_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe RspecFlaky::Report, :aggregate_failures do
diff --git a/spec/lib/safe_zip/entry_spec.rb b/spec/lib/safe_zip/entry_spec.rb
index 115e28c5994..0974f732188 100644
--- a/spec/lib/safe_zip/entry_spec.rb
+++ b/spec/lib/safe_zip/entry_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe SafeZip::Entry do
diff --git a/spec/lib/safe_zip/extract_params_spec.rb b/spec/lib/safe_zip/extract_params_spec.rb
index 85e22cfa495..f66d3de89ee 100644
--- a/spec/lib/safe_zip/extract_params_spec.rb
+++ b/spec/lib/safe_zip/extract_params_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe SafeZip::ExtractParams do
diff --git a/spec/lib/safe_zip/extract_spec.rb b/spec/lib/safe_zip/extract_spec.rb
index b75a8fede00..3b8c64c1c9f 100644
--- a/spec/lib/safe_zip/extract_spec.rb
+++ b/spec/lib/safe_zip/extract_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe SafeZip::Extract do
diff --git a/spec/lib/serializers/json_spec.rb b/spec/lib/serializers/json_spec.rb
index 847a01d186c..a8d82d70e89 100644
--- a/spec/lib/serializers/json_spec.rb
+++ b/spec/lib/serializers/json_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'fast_spec_helper'
describe Serializers::JSON do
diff --git a/spec/lib/system_check/app/git_user_default_ssh_config_check_spec.rb b/spec/lib/system_check/app/git_user_default_ssh_config_check_spec.rb
index a0fb86345f3..f132f608ab6 100644
--- a/spec/lib/system_check/app/git_user_default_ssh_config_check_spec.rb
+++ b/spec/lib/system_check/app/git_user_default_ssh_config_check_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe SystemCheck::App::GitUserDefaultSSHConfigCheck do
diff --git a/spec/lib/system_check/base_check_spec.rb b/spec/lib/system_check/base_check_spec.rb
index faf8c99e772..ccb7b483bdc 100644
--- a/spec/lib/system_check/base_check_spec.rb
+++ b/spec/lib/system_check/base_check_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe SystemCheck::BaseCheck do
diff --git a/spec/lib/system_check/orphans/namespace_check_spec.rb b/spec/lib/system_check/orphans/namespace_check_spec.rb
index 2a61ff3ad65..f7491e40438 100644
--- a/spec/lib/system_check/orphans/namespace_check_spec.rb
+++ b/spec/lib/system_check/orphans/namespace_check_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'rake_helper'
diff --git a/spec/lib/system_check/orphans/repository_check_spec.rb b/spec/lib/system_check/orphans/repository_check_spec.rb
index b0c2267d177..a5e06f30e75 100644
--- a/spec/lib/system_check/orphans/repository_check_spec.rb
+++ b/spec/lib/system_check/orphans/repository_check_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'rake_helper'
diff --git a/spec/lib/system_check/simple_executor_spec.rb b/spec/lib/system_check/simple_executor_spec.rb
index e71e9da369d..94094343ec6 100644
--- a/spec/lib/system_check/simple_executor_spec.rb
+++ b/spec/lib/system_check/simple_executor_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'rake_helper'
diff --git a/spec/lib/system_check_spec.rb b/spec/lib/system_check_spec.rb
index 4d9e17fa6ec..f3ed6ca31c9 100644
--- a/spec/lib/system_check_spec.rb
+++ b/spec/lib/system_check_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
require 'rake_helper'
diff --git a/spec/lib/uploaded_file_spec.rb b/spec/lib/uploaded_file_spec.rb
index a2f5c2e7121..2cb4727bd4b 100644
--- a/spec/lib/uploaded_file_spec.rb
+++ b/spec/lib/uploaded_file_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require 'spec_helper'
describe UploadedFile do
diff --git a/spec/migrations/add_gitlab_instance_administration_project_spec.rb b/spec/migrations/add_gitlab_instance_administration_project_spec.rb
new file mode 100644
index 00000000000..08e20a4e8ff
--- /dev/null
+++ b/spec/migrations/add_gitlab_instance_administration_project_spec.rb
@@ -0,0 +1,252 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20190801072937_add_gitlab_instance_administration_project.rb')
+
+describe AddGitlabInstanceAdministrationProject, :migration do
+ let(:application_settings) { table(:application_settings) }
+ let(:users) { table(:users) }
+ let(:projects) { table(:projects) }
+ let(:namespaces) { table(:namespaces) }
+ let(:members) { table(:members) }
+
+ let(:service_class) do
+ Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService
+ end
+
+ let(:prometheus_settings) do
+ {
+ enable: true,
+ listen_address: 'localhost:9090'
+ }
+ end
+
+ before do
+ stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
+
+ stub_config(prometheus: prometheus_settings)
+ end
+
+ describe 'down' do
+ let!(:application_setting) { application_settings.create! }
+ let!(:user) { users.create!(admin: true, email: 'admin1@example.com', projects_limit: 10, state: :active) }
+
+ it 'deletes group and project' do
+ migrate!
+
+ expect(Project.count).to eq(1)
+ expect(Group.count).to eq(1)
+
+ schema_migrate_down!
+
+ expect(Project.count).to eq(0)
+ expect(Group.count).to eq(0)
+ end
+ end
+
+ describe 'up' do
+ context 'without application_settings' do
+ it 'does not fail' do
+ migrate!
+
+ expect(Project.count).to eq(0)
+ end
+ end
+
+ context 'without admin users' do
+ let!(:application_setting) { application_settings.create! }
+
+ it 'does not fail' do
+ migrate!
+
+ expect(Project.count).to eq(0)
+ end
+ end
+
+ context 'with admin users' do
+ let(:project) { Project.last }
+ let(:group) { Group.last }
+ let!(:application_setting) { application_settings.create! }
+ let!(:user) { users.create!(admin: true, email: 'admin1@example.com', projects_limit: 10, state: :active) }
+
+ before do
+ stub_application_setting(allow_local_requests_from_web_hooks_and_services: true)
+ end
+
+ shared_examples 'has prometheus service' do |listen_address|
+ it do
+ migrate!
+
+ prometheus = project.prometheus_service
+ expect(prometheus).to be_persisted
+ expect(prometheus).not_to eq(nil)
+ expect(prometheus.api_url).to eq(listen_address)
+ expect(prometheus.active).to eq(true)
+ expect(prometheus.manual_configuration).to eq(true)
+ end
+ end
+
+ it_behaves_like 'has prometheus service', 'http://localhost:9090'
+
+ it 'creates GitLab Instance Administrator group' do
+ migrate!
+
+ expect(group).to be_persisted
+ expect(group.name).to eq('GitLab Instance Administrators')
+ expect(group.path).to start_with('gitlab-instance-administrators')
+ expect(group.path.split('-').last.length).to eq(8)
+ expect(group.visibility_level).to eq(service_class::VISIBILITY_LEVEL)
+ end
+
+ it 'creates project with internal visibility' do
+ migrate!
+
+ expect(project.visibility_level).to eq(Gitlab::VisibilityLevel::INTERNAL)
+ expect(project).to be_persisted
+ end
+
+ it 'creates project with correct name and description' do
+ migrate!
+
+ path = 'administration/monitoring/gitlab_instance_administration_project/index'
+ docs_path = Rails.application.routes.url_helpers.help_page_path(path)
+
+ expect(project.name).to eq(service_class::PROJECT_NAME)
+ expect(project.description).to eq(
+ 'This project is automatically generated and will be used to help monitor this GitLab instance. ' \
+ "[More information](#{docs_path})"
+ )
+ expect(File).to exist("doc/#{path}.md")
+ end
+
+ it 'adds all admins as maintainers' do
+ admin1 = users.create!(admin: true, email: 'admin2@example.com', projects_limit: 10, state: :active)
+ admin2 = users.create!(admin: true, email: 'admin3@example.com', projects_limit: 10, state: :active)
+ users.create!(email: 'nonadmin1@example.com', projects_limit: 10, state: :active)
+
+ migrate!
+
+ expect(project.owner).to eq(group)
+ expect(group.members.collect(&:user).collect(&:id)).to contain_exactly(user.id, admin1.id, admin2.id)
+ expect(group.members.collect(&:access_level)).to contain_exactly(
+ Gitlab::Access::OWNER,
+ Gitlab::Access::MAINTAINER,
+ Gitlab::Access::MAINTAINER
+ )
+ end
+
+ it 'saves the project id' do
+ migrate!
+
+ application_setting.reload
+ expect(application_setting.instance_administration_project_id).to eq(project.id)
+ end
+
+ it 'does not fail when a project already exists' do
+ group = namespaces.create!(
+ path: 'gitlab-instance-administrators',
+ name: 'GitLab Instance Administrators',
+ type: 'Group'
+ )
+ project = projects.create!(
+ namespace_id: group.id,
+ name: 'GitLab Instance Administration'
+ )
+
+ admin1 = users.create!(admin: true, email: 'admin4@example.com', projects_limit: 10, state: :active)
+ admin2 = users.create!(admin: true, email: 'admin5@example.com', projects_limit: 10, state: :active)
+
+ members.create!(
+ user_id: admin1.id,
+ source_id: group.id,
+ source_type: 'Namespace',
+ type: 'GroupMember',
+ access_level: GroupMember::MAINTAINER,
+ notification_level: NotificationSetting.levels[:global]
+ )
+ members.create!(
+ user_id: admin2.id,
+ source_id: group.id,
+ source_type: 'Namespace',
+ type: 'GroupMember',
+ access_level: GroupMember::MAINTAINER,
+ notification_level: NotificationSetting.levels[:global]
+ )
+
+ stub_application_setting(instance_administration_project: project)
+
+ migrate!
+
+ expect(Project.last.id).to eq(project.id)
+ expect(Group.last.id).to eq(group.id)
+ end
+
+ context 'when local requests from hooks and services are not allowed' do
+ before do
+ stub_application_setting(allow_local_requests_from_web_hooks_and_services: false)
+ end
+
+ it_behaves_like 'has prometheus service', 'http://localhost:9090'
+
+ it 'does not overwrite the existing whitelist' do
+ application_setting.update!(outbound_local_requests_whitelist: ['example.com'])
+
+ migrate!
+
+ application_setting.reload
+ expect(application_setting.outbound_local_requests_whitelist).to contain_exactly(
+ 'example.com', 'localhost'
+ )
+ end
+ end
+
+ context 'with non default prometheus address' do
+ let(:prometheus_settings) do
+ {
+ enable: true,
+ listen_address: 'https://localhost:9090'
+ }
+ end
+
+ it_behaves_like 'has prometheus service', 'https://localhost:9090'
+ end
+
+ context 'when prometheus setting is not present in gitlab.yml' do
+ before do
+ allow(Gitlab.config).to receive(:prometheus).and_raise(Settingslogic::MissingSetting)
+ end
+
+ it 'does not fail' do
+ migrate!
+
+ expect(project.prometheus_service).to be_nil
+ end
+ end
+
+ context 'when prometheus setting is disabled in gitlab.yml' do
+ let(:prometheus_settings) do
+ {
+ enable: false,
+ listen_address: 'localhost:9090'
+ }
+ end
+
+ it 'does not configure prometheus' do
+ migrate!
+
+ expect(project.prometheus_service).to be_nil
+ end
+ end
+
+ context 'when prometheus listen address is blank in gitlab.yml' do
+ let(:prometheus_settings) { { enable: true, listen_address: '' } }
+
+ it 'does not configure prometheus' do
+ migrate!
+
+ expect(project.prometheus_service).to be_nil
+ end
+ end
+ end
+ end
+end
diff --git a/spec/models/analytics/cycle_analytics/project_stage_spec.rb b/spec/models/analytics/cycle_analytics/project_stage_spec.rb
index 4e3923e82b1..83d6ff754c5 100644
--- a/spec/models/analytics/cycle_analytics/project_stage_spec.rb
+++ b/spec/models/analytics/cycle_analytics/project_stage_spec.rb
@@ -6,4 +6,18 @@ describe Analytics::CycleAnalytics::ProjectStage do
describe 'associations' do
it { is_expected.to belong_to(:project) }
end
+
+ it 'default stages must be valid' do
+ project = create(:project)
+
+ Gitlab::Analytics::CycleAnalytics::DefaultStages.all.each do |params|
+ stage = described_class.new(params.merge(project: project))
+ expect(stage).to be_valid
+ end
+ end
+
+ it_behaves_like "cycle analytics stage" do
+ let(:parent) { create(:project) }
+ let(:parent_name) { :project }
+ end
end
diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb
index d4e631f109b..51ed8e9421b 100644
--- a/spec/models/deployment_spec.rb
+++ b/spec/models/deployment_spec.rb
@@ -322,4 +322,30 @@ describe Deployment do
end
end
end
+
+ describe '#deployed_by' do
+ it 'returns the deployment user if there is no deployable' do
+ deployment_user = create(:user)
+ deployment = create(:deployment, deployable: nil, user: deployment_user)
+
+ expect(deployment.deployed_by).to eq(deployment_user)
+ end
+
+ it 'returns the deployment user if the deployable have no user' do
+ deployment_user = create(:user)
+ build = create(:ci_build, user: nil)
+ deployment = create(:deployment, deployable: build, user: deployment_user)
+
+ expect(deployment.deployed_by).to eq(deployment_user)
+ end
+
+ it 'returns the deployable user if there is one' do
+ build_user = create(:user)
+ deployment_user = create(:user)
+ build = create(:ci_build, user: build_user)
+ deployment = create(:deployment, deployable: build, user: deployment_user)
+
+ expect(deployment.deployed_by).to eq(build_user)
+ end
+ end
end
diff --git a/spec/requests/api/discussions_spec.rb b/spec/requests/api/discussions_spec.rb
index ef09c6effbb..0420201efe3 100644
--- a/spec/requests/api/discussions_spec.rb
+++ b/spec/requests/api/discussions_spec.rb
@@ -9,59 +9,11 @@ describe API::Discussions do
project.add_developer(user)
end
- context 'with cross-reference system notes', :request_store do
- let(:merge_request) { create(:merge_request) }
- let(:project) { merge_request.project }
- let(:new_merge_request) { create(:merge_request) }
- let(:commit) { new_merge_request.project.commit }
- let!(:note) { create(:system_note, noteable: merge_request, project: project, note: cross_reference) }
- let!(:note_metadata) { create(:system_note_metadata, note: note, action: 'cross_reference') }
- let(:cross_reference) { "test commit #{commit.to_reference(project)}" }
- let(:pat) { create(:personal_access_token, user: user) }
-
+ context 'when discussions have cross-reference system notes' do
let(:url) { "/projects/#{project.id}/merge_requests/#{merge_request.iid}/discussions" }
+ let(:notes_in_response) { json_response.first['notes'] }
- before do
- project.add_developer(user)
- new_merge_request.project.add_developer(user)
- end
-
- it 'returns only the note that the user should see' do
- hidden_merge_request = create(:merge_request)
- new_cross_reference = "test commit #{hidden_merge_request.project.commit}"
- new_note = create(:system_note, noteable: merge_request, project: project, note: new_cross_reference)
- create(:system_note_metadata, note: new_note, action: 'cross_reference')
-
- get api(url, user, personal_access_token: pat)
- expect(response).to have_gitlab_http_status(200)
- expect(json_response.count).to eq(1)
- expect(json_response.first['notes'].count).to eq(1)
-
- parsed_note = json_response.first['notes'].first
- expect(parsed_note['id']).to eq(note.id)
- expect(parsed_note['body']).to eq(cross_reference)
- expect(parsed_note['system']).to be true
- end
-
- it 'avoids Git calls and N+1 SQL queries' do
- expect_any_instance_of(Repository).not_to receive(:find_commit).with(commit.id)
-
- control = ActiveRecord::QueryRecorder.new do
- get api(url, user, personal_access_token: pat)
- end
-
- expect(response).to have_gitlab_http_status(200)
-
- RequestStore.clear!
-
- new_note = create(:system_note, noteable: merge_request, project: project, note: cross_reference)
- create(:system_note_metadata, note: new_note, action: 'cross_reference')
-
- RequestStore.clear!
-
- expect { get api(url, user, personal_access_token: pat) }.not_to exceed_query_limit(control)
- expect(response).to have_gitlab_http_status(200)
- end
+ it_behaves_like 'with cross-reference system notes'
end
context 'when noteable is an Issue' do
diff --git a/spec/requests/api/issues/issues_spec.rb b/spec/requests/api/issues/issues_spec.rb
index 27cf66629fe..f19c2dcc6fe 100644
--- a/spec/requests/api/issues/issues_spec.rb
+++ b/spec/requests/api/issues/issues_spec.rb
@@ -607,6 +607,22 @@ describe API::Issues do
expect_paginated_array_response([closed_issue.id, issue.id])
end
+ context 'with issues list sort options' do
+ it 'accepts only predefined order by params' do
+ API::Helpers::IssuesHelpers.sort_options.each do |sort_opt|
+ get api('/issues', user), params: { order_by: sort_opt, sort: 'asc' }
+ expect(response).to have_gitlab_http_status(200)
+ end
+ end
+
+ it 'fails to sort with non predefined options' do
+ %w(milestone title abracadabra).each do |sort_opt|
+ get api('/issues', user), params: { order_by: sort_opt, sort: 'asc' }
+ expect(response).to have_gitlab_http_status(400)
+ end
+ end
+ end
+
it 'matches V4 response schema' do
get api('/issues', user)
diff --git a/spec/requests/api/labels_spec.rb b/spec/requests/api/labels_spec.rb
index ad0974f55a3..f6640fe41d0 100644
--- a/spec/requests/api/labels_spec.rb
+++ b/spec/requests/api/labels_spec.rb
@@ -6,6 +6,180 @@ describe API::Labels do
let!(:label1) { create(:label, title: 'label1', project: project) }
let!(:priority_label) { create(:label, title: 'bug', project: project, priority: 3) }
+ shared_examples 'label update API' do
+ it 'returns 200 if name is changed' do
+ request_params = {
+ new_name: 'New Label'
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response['name']).to eq('New Label')
+ expect(json_response['color']).to eq(label1.color)
+ end
+
+ it 'returns 200 if colors is changed' do
+ request_params = {
+ color: '#FFFFFF'
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response['name']).to eq(label1.name)
+ expect(json_response['color']).to eq('#FFFFFF')
+ end
+
+ it 'returns 200 if a priority is added' do
+ request_params = {
+ priority: 3
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response.status).to eq(200)
+ expect(json_response['name']).to eq(label1.name)
+ expect(json_response['priority']).to eq(3)
+ end
+
+ it 'returns 400 if no new parameters given' do
+ put api("/projects/#{project.id}/labels", user), params: spec_params
+
+ expect(response).to have_gitlab_http_status(400)
+ expect(json_response['error']).to eq('new_name, color, description, priority are missing, '\
+ 'at least one parameter must be provided')
+ end
+
+ it 'returns 400 when color code is too short' do
+ request_params = {
+ color: '#FF'
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response).to have_gitlab_http_status(400)
+ expect(json_response['message']['color']).to eq(['must be a valid color code'])
+ end
+
+ it 'returns 400 for too long color code' do
+ request_params = {
+ color: '#FFAAFFFF'
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response).to have_gitlab_http_status(400)
+ expect(json_response['message']['color']).to eq(['must be a valid color code'])
+ end
+
+ it 'returns 400 for invalid priority' do
+ request_params = {
+ priority: 'foo'
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response).to have_gitlab_http_status(400)
+ end
+
+ it 'returns 200 if name and colors and description are changed' do
+ request_params = {
+ new_name: 'New Label',
+ color: '#FFFFFF',
+ description: 'test'
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response['name']).to eq('New Label')
+ expect(json_response['color']).to eq('#FFFFFF')
+ expect(json_response['description']).to eq('test')
+ end
+
+ it 'returns 400 for invalid name' do
+ request_params = {
+ new_name: ',',
+ color: '#FFFFFF'
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response).to have_gitlab_http_status(400)
+ expect(json_response['message']['title']).to eq(['is invalid'])
+ end
+
+ it 'returns 200 if description is changed' do
+ request_params = {
+ description: 'test'
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response['id']).to eq(expected_response_label_id)
+ expect(json_response['description']).to eq('test')
+ end
+
+ it 'returns 200 if priority is changed' do
+ request_params = {
+ priority: 10
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response.status).to eq(200)
+ expect(json_response['id']).to eq(expected_response_label_id)
+ expect(json_response['priority']).to eq(10)
+ end
+
+ it 'returns 200 if a priority is removed' do
+ label = find_by_spec_params(spec_params)
+ expect(label).not_to be_nil
+
+ label.priorities.create(project: label.project, priority: 1)
+ label.save!
+
+ request_params = {
+ priority: nil
+ }.merge(spec_params)
+
+ put api("/projects/#{project.id}/labels", user),
+ params: request_params
+
+ expect(response.status).to eq(200)
+ expect(json_response['id']).to eq(expected_response_label_id)
+ expect(json_response['priority']).to be_nil
+ end
+
+ def find_by_spec_params(params)
+ if params.key?(:label_id)
+ Label.find(params[:label_id])
+ else
+ Label.find_by(name: params[:name])
+ end
+ end
+ end
+
+ shared_examples 'label delete API' do
+ it 'returns 204 for existing label' do
+ delete api("/projects/#{project.id}/labels", user), params: spec_params
+
+ expect(response).to have_gitlab_http_status(204)
+ end
+ end
+
before do
project.add_maintainer(user)
end
@@ -208,174 +382,92 @@ describe API::Labels do
end
describe 'DELETE /projects/:id/labels' do
- it 'returns 204 for existing label' do
- delete api("/projects/#{project.id}/labels", user), params: { name: 'label1' }
+ it_behaves_like 'label delete API' do
+ let(:spec_params) { { name: 'label1' } }
+ end
- expect(response).to have_gitlab_http_status(204)
+ it_behaves_like 'label delete API' do
+ let(:spec_params) { { label_id: label1.id } }
end
it 'returns 404 for non existing label' do
delete api("/projects/#{project.id}/labels", user), params: { name: 'label2' }
+
expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Label Not Found')
end
it 'returns 400 for wrong parameters' do
delete api("/projects/#{project.id}/labels", user)
- expect(response).to have_gitlab_http_status(400)
- end
-
- it_behaves_like '412 response' do
- let(:request) { api("/projects/#{project.id}/labels", user) }
- let(:params) { { name: 'label1' } }
- end
- end
- describe 'PUT /projects/:id/labels' do
- it 'returns 200 if name and colors and description are changed' do
- put api("/projects/#{project.id}/labels", user),
- params: {
- name: 'label1',
- new_name: 'New Label',
- color: '#FFFFFF',
- description: 'test'
- }
- expect(response).to have_gitlab_http_status(200)
- expect(json_response['name']).to eq('New Label')
- expect(json_response['color']).to eq('#FFFFFF')
- expect(json_response['description']).to eq('test')
+ expect(response).to have_gitlab_http_status(400)
end
- it 'returns 200 if name is changed' do
- put api("/projects/#{project.id}/labels", user),
+ it 'fails if label_id and name are given in params' do
+ delete api("/projects/#{project.id}/labels", user),
params: {
- name: 'label1',
- new_name: 'New Label'
+ label_id: label1.id,
+ name: priority_label.name
}
- expect(response).to have_gitlab_http_status(200)
- expect(json_response['name']).to eq('New Label')
- expect(json_response['color']).to eq(label1.color)
- end
- it 'returns 200 if colors is changed' do
- put api("/projects/#{project.id}/labels", user),
- params: {
- name: 'label1',
- color: '#FFFFFF'
- }
- expect(response).to have_gitlab_http_status(200)
- expect(json_response['name']).to eq(label1.name)
- expect(json_response['color']).to eq('#FFFFFF')
+ expect(response).to have_gitlab_http_status(400)
end
- it 'returns 200 if description is changed' do
- put api("/projects/#{project.id}/labels", user),
- params: {
- name: 'bug',
- description: 'test'
- }
-
- expect(response).to have_gitlab_http_status(200)
- expect(json_response['name']).to eq(priority_label.name)
- expect(json_response['description']).to eq('test')
- expect(json_response['priority']).to eq(3)
+ it_behaves_like '412 response' do
+ let(:request) { api("/projects/#{project.id}/labels", user) }
+ let(:params) { { name: 'label1' } }
end
+ end
- it 'returns 200 if priority is changed' do
- put api("/projects/#{project.id}/labels", user),
- params: {
- name: 'bug',
- priority: 10
- }
-
- expect(response.status).to eq(200)
- expect(json_response['name']).to eq(priority_label.name)
- expect(json_response['priority']).to eq(10)
+ describe 'PUT /projects/:id/labels' do
+ context 'when using name' do
+ it_behaves_like 'label update API' do
+ let(:spec_params) { { name: 'label1' } }
+ let(:expected_response_label_id) { label1.id }
+ end
end
- it 'returns 200 if a priority is added' do
- put api("/projects/#{project.id}/labels", user),
- params: {
- name: 'label1',
- priority: 3
- }
-
- expect(response.status).to eq(200)
- expect(json_response['name']).to eq(label1.name)
- expect(json_response['priority']).to eq(3)
+ context 'when using label_id' do
+ it_behaves_like 'label update API' do
+ let(:spec_params) { { label_id: label1.id } }
+ let(:expected_response_label_id) { label1.id }
+ end
end
- it 'returns 200 if the priority is removed' do
+ it 'returns 404 if label does not exist' do
put api("/projects/#{project.id}/labels", user),
params: {
- name: priority_label.name,
- priority: nil
+ name: 'label2',
+ new_name: 'label3'
}
- expect(response.status).to eq(200)
- expect(json_response['name']).to eq(priority_label.name)
- expect(json_response['priority']).to be_nil
+ expect(response).to have_gitlab_http_status(404)
end
- it 'returns 404 if label does not exist' do
+ it 'returns 404 if label by id does not exist' do
put api("/projects/#{project.id}/labels", user),
params: {
- name: 'label2',
+ label_id: 0,
new_name: 'label3'
}
+
expect(response).to have_gitlab_http_status(404)
end
- it 'returns 400 if no label name given' do
+ it 'returns 400 if no label name and id is given' do
put api("/projects/#{project.id}/labels", user), params: { new_name: 'label2' }
- expect(response).to have_gitlab_http_status(400)
- expect(json_response['error']).to eq('name is missing')
- end
-
- it 'returns 400 if no new parameters given' do
- put api("/projects/#{project.id}/labels", user), params: { name: 'label1' }
- expect(response).to have_gitlab_http_status(400)
- expect(json_response['error']).to eq('new_name, color, description, priority are missing, '\
- 'at least one parameter must be provided')
- end
- it 'returns 400 for invalid name' do
- put api("/projects/#{project.id}/labels", user),
- params: {
- name: 'label1',
- new_name: ',',
- color: '#FFFFFF'
- }
expect(response).to have_gitlab_http_status(400)
- expect(json_response['message']['title']).to eq(['is invalid'])
+ expect(json_response['error']).to eq('label_id, name are missing, exactly one parameter must be provided')
end
- it 'returns 400 when color code is too short' do
+ it 'fails if label_id and name are given in params' do
put api("/projects/#{project.id}/labels", user),
params: {
- name: 'label1',
- color: '#FF'
+ label_id: label1.id,
+ name: priority_label.name,
+ new_name: 'New Label'
}
- expect(response).to have_gitlab_http_status(400)
- expect(json_response['message']['color']).to eq(['must be a valid color code'])
- end
-
- it 'returns 400 for too long color code' do
- put api("/projects/#{project.id}/labels", user),
- params: {
- name: 'label1',
- color: '#FFAAFFFF'
- }
- expect(response).to have_gitlab_http_status(400)
- expect(json_response['message']['color']).to eq(['must be a valid color code'])
- end
-
- it 'returns 400 for invalid priority' do
- put api("/projects/#{project.id}/labels", user),
- params: {
- name: 'label1',
- priority: 'foo'
- }
expect(response).to have_gitlab_http_status(400)
end
diff --git a/spec/requests/api/notes_spec.rb b/spec/requests/api/notes_spec.rb
index 424f0a82e43..6c1e30791d2 100644
--- a/spec/requests/api/notes_spec.rb
+++ b/spec/requests/api/notes_spec.rb
@@ -9,6 +9,13 @@ describe API::Notes do
project.add_reporter(user)
end
+ context 'when there are cross-reference system notes' do
+ let(:url) { "/projects/#{project.id}/merge_requests/#{merge_request.iid}/notes" }
+ let(:notes_in_response) { json_response }
+
+ it_behaves_like 'with cross-reference system notes'
+ end
+
context "when noteable is an Issue" do
let!(:issue) { create(:issue, project: project, author: user) }
let!(:issue_note) { create(:note, noteable: issue, project: project, author: user) }
diff --git a/spec/requests/api/pipelines_spec.rb b/spec/requests/api/pipelines_spec.rb
index 35b3dd219f7..174b3214d13 100644
--- a/spec/requests/api/pipelines_spec.rb
+++ b/spec/requests/api/pipelines_spec.rb
@@ -17,6 +17,8 @@ describe API::Pipelines do
end
describe 'GET /projects/:id/pipelines ' do
+ it_behaves_like 'pipelines visibility table'
+
context 'authorized user' do
it 'returns project pipelines' do
get api("/projects/#{project.id}/pipelines", user)
@@ -401,6 +403,15 @@ describe API::Pipelines do
end
describe 'GET /projects/:id/pipelines/:pipeline_id' do
+ it_behaves_like 'pipelines visibility table' do
+ let(:pipelines_api_path) do
+ "/projects/#{project.id}/pipelines/#{pipeline.id}"
+ end
+
+ let(:api_response) { response_status == 200 ? response : json_response }
+ let(:response_200) { match_response_schema('public_api/v4/pipeline/detail') }
+ end
+
context 'authorized user' do
it 'exposes known attributes' do
get api("/projects/#{project.id}/pipelines/#{pipeline.id}", user)
diff --git a/spec/requests/jwt_controller_spec.rb b/spec/requests/jwt_controller_spec.rb
index bba473f1c20..8b2c698fee1 100644
--- a/spec/requests/jwt_controller_spec.rb
+++ b/spec/requests/jwt_controller_spec.rb
@@ -108,6 +108,14 @@ describe JwtController do
end
end
end
+
+ it 'does not cause session based checks to be activated' do
+ expect(Gitlab::Session).not_to receive(:with_session)
+
+ get '/jwt/auth', params: parameters, headers: headers
+
+ expect(response).to have_gitlab_http_status(200)
+ end
end
context 'using invalid login' do
diff --git a/spec/rubocop/cop/migration/add_limit_to_string_columns_spec.rb b/spec/rubocop/cop/migration/add_limit_to_string_columns_spec.rb
new file mode 100644
index 00000000000..97a3ae8f2bc
--- /dev/null
+++ b/spec/rubocop/cop/migration/add_limit_to_string_columns_spec.rb
@@ -0,0 +1,268 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'rubocop'
+require 'rubocop/rspec/support'
+
+require_relative '../../../../rubocop/cop/migration/add_limit_to_string_columns'
+
+describe RuboCop::Cop::Migration::AddLimitToStringColumns do
+ include CopHelper
+
+ subject(:cop) { described_class.new }
+
+ context 'in migration' do
+ before do
+ allow(cop).to receive(:in_migration?).and_return(true)
+
+ inspect_source(migration)
+ end
+
+ context 'when creating a table' do
+ context 'with string columns and limit' do
+ let(:migration) do
+ %q(
+ class CreateUsers < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ create_table :users do |t|
+ t.string :username, null: false, limit: 255
+ t.timestamps_with_timezone null: true
+ end
+ end
+ end
+ )
+ end
+
+ it 'register no offense' do
+ expect(cop.offenses.size).to eq(0)
+ end
+
+ context 'with limit in a different position' do
+ let(:migration) do
+ %q(
+ class CreateUsers < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ create_table :users do |t|
+ t.string :username, limit: 255, null: false
+ t.timestamps_with_timezone null: true
+ end
+ end
+ end
+ )
+ end
+
+ it 'registers an offense' do
+ expect(cop.offenses.size).to eq(0)
+ end
+ end
+ end
+
+ context 'with string columns and no limit' do
+ let(:migration) do
+ %q(
+ class CreateUsers < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ create_table :users do |t|
+ t.string :username, null: false
+ t.timestamps_with_timezone null: true
+ end
+ end
+ end
+ )
+ end
+
+ it 'registers an offense' do
+ expect(cop.offenses.size).to eq(1)
+ expect(cop.offenses.first.message)
+ .to eq('String columns should have a limit constraint. 255 is suggested')
+ end
+ end
+
+ context 'with no string columns' do
+ let(:migration) do
+ %q(
+ class CreateMilestoneReleases < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ create_table :milestone_releases do |t|
+ t.integer :milestone_id
+ t.integer :release_id
+ end
+ end
+ end
+ )
+ end
+
+ it 'register no offense' do
+ expect(cop.offenses.size).to eq(0)
+ end
+ end
+ end
+
+ context 'when adding columns' do
+ context 'with string columns with limit' do
+ let(:migration) do
+ %q(
+ class AddEmailToUsers < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ add_column :users, :email, :string, limit: 255
+ end
+ end
+ )
+ end
+
+ it 'registers no offense' do
+ expect(cop.offenses.size).to eq(0)
+ end
+
+ context 'with limit in a different position' do
+ let(:migration) do
+ %q(
+ class AddEmailToUsers < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ add_column :users, :email, :string, limit: 255, default: 'example@email.com'
+ end
+ end
+ )
+ end
+
+ it 'registers no offense' do
+ expect(cop.offenses.size).to eq(0)
+ end
+ end
+ end
+
+ context 'with string columns with no limit' do
+ let(:migration) do
+ %q(
+ class AddEmailToUsers < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ add_column :users, :email, :string
+ end
+ end
+ )
+ end
+
+ it 'registers offense' do
+ expect(cop.offenses.size).to eq(1)
+ expect(cop.offenses.first.message)
+ .to eq('String columns should have a limit constraint. 255 is suggested')
+ end
+ end
+
+ context 'with no string columns' do
+ let(:migration) do
+ %q(
+ class AddEmailToUsers < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ add_column :users, :active, :boolean, default: false
+ end
+ end
+ )
+ end
+
+ it 'registers no offense' do
+ expect(cop.offenses.size).to eq(0)
+ end
+ end
+ end
+
+ context 'with add_column_with_default' do
+ context 'with a limit' do
+ let(:migration) do
+ %q(
+ class AddRuleTypeToApprovalMergeRequestRules < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ add_column_with_default(:approval_merge_request_rules, :rule_type, :string, limit: 2, default: 1)
+ end
+ end
+ )
+ end
+
+ it 'registers no offense' do
+ expect(cop.offenses.size).to eq(0)
+ end
+ end
+
+ context 'without a limit' do
+ let(:migration) do
+ %q(
+ class AddRuleTypeToApprovalMergeRequestRules < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ add_column_with_default(:approval_merge_request_rules, :rule_type, :string, default: 1)
+ end
+ end
+ )
+ end
+
+ it 'registers an offense' do
+ expect(cop.offenses.size).to eq(1)
+ end
+ end
+ end
+
+ context 'with methods' do
+ let(:migration) do
+ %q(
+ class AddEmailToUsers < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ add_column_if_table_not_exists :users, :first_name, :string, limit: 255
+ search_namespace(user_name)
+ end
+
+ def add_column_if_not_exists(table, name, *args)
+ add_column(table, name, *args) unless column_exists?(table, name)
+ end
+
+ def search_namespace(username)
+ Uniquify.new.string(username) do |str|
+ query = "SELECT id FROM namespaces WHERE parent_id IS NULL AND path='#{str}' LIMIT 1"
+ connection.exec_query(query)
+ end
+ end
+ end
+ )
+ end
+
+ it 'registers no offense' do
+ expect(cop.offenses.size).to eq(0)
+ end
+ end
+ end
+
+ context 'outside of migrations' do
+ let(:active_record_model) do
+ %q(
+ class User < ApplicationRecord
+ end
+ )
+ end
+
+ it 'registers no offense' do
+ inspect_source(active_record_model)
+
+ expect(cop.offenses.size).to eq(0)
+ end
+ end
+end
diff --git a/spec/support/helpers/drag_to_helper.rb b/spec/support/helpers/drag_to_helper.rb
index 6099f87323f..2e9932f2e8a 100644
--- a/spec/support/helpers/drag_to_helper.rb
+++ b/spec/support/helpers/drag_to_helper.rb
@@ -1,8 +1,23 @@
# frozen_string_literal: true
module DragTo
- def drag_to(list_from_index: 0, from_index: 0, to_index: 0, list_to_index: 0, selector: '', scrollable: 'body', duration: 1000)
- evaluate_script("simulateDrag({scrollable: $('#{scrollable}').get(0), duration: #{duration}, from: {el: $('#{selector}').eq(#{list_from_index}).get(0), index: #{from_index}}, to: {el: $('#{selector}').eq(#{list_to_index}).get(0), index: #{to_index}}});")
+ def drag_to(list_from_index: 0, from_index: 0, to_index: 0, list_to_index: 0, selector: '', scrollable: 'body', duration: 1000, perform_drop: true)
+ js = <<~JS
+ simulateDrag({
+ scrollable: document.querySelector('#{scrollable}'),
+ duration: #{duration},
+ from: {
+ el: document.querySelectorAll('#{selector}')[#{list_from_index}],
+ index: #{from_index}
+ },
+ to: {
+ el: document.querySelectorAll('#{selector}')[#{list_to_index}],
+ index: #{to_index}
+ },
+ performDrop: #{perform_drop}
+ });
+ JS
+ evaluate_script(js)
Timeout.timeout(Capybara.default_max_wait_time) do
loop while drag_active?
diff --git a/spec/support/helpers/stub_configuration.rb b/spec/support/helpers/stub_configuration.rb
index c8b2bf040e6..dec7898d8d2 100644
--- a/spec/support/helpers/stub_configuration.rb
+++ b/spec/support/helpers/stub_configuration.rb
@@ -30,6 +30,10 @@ module StubConfiguration
allow(Gitlab.config.gitlab).to receive_messages(to_settings(messages))
end
+ def stub_config(messages)
+ allow(Gitlab.config).to receive_messages(to_settings(messages))
+ end
+
def stub_default_url_options(host: "localhost", protocol: "http")
url_options = { host: host, protocol: protocol }
allow(Rails.application.routes).to receive(:default_url_options).and_return(url_options)
diff --git a/spec/support/shared_examples/cycle_analytics_stage_examples.rb b/spec/support/shared_examples/cycle_analytics_stage_examples.rb
new file mode 100644
index 00000000000..151f5325e84
--- /dev/null
+++ b/spec/support/shared_examples/cycle_analytics_stage_examples.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+shared_examples_for 'cycle analytics stage' do
+ let(:valid_params) do
+ {
+ name: 'My Stage',
+ parent: parent,
+ start_event_identifier: :merge_request_created,
+ end_event_identifier: :merge_request_merged
+ }
+ end
+
+ describe 'validation' do
+ it 'is valid' do
+ expect(described_class.new(valid_params)).to be_valid
+ end
+
+ it 'validates presence of parent' do
+ stage = described_class.new(valid_params.except(:parent))
+
+ expect(stage).not_to be_valid
+ expect(stage.errors.details[parent_name]).to eq([{ error: :blank }])
+ end
+
+ it 'validates presence of start_event_identifier' do
+ stage = described_class.new(valid_params.except(:start_event_identifier))
+
+ expect(stage).not_to be_valid
+ expect(stage.errors.details[:start_event_identifier]).to eq([{ error: :blank }])
+ end
+
+ it 'validates presence of end_event_identifier' do
+ stage = described_class.new(valid_params.except(:end_event_identifier))
+
+ expect(stage).not_to be_valid
+ expect(stage.errors.details[:end_event_identifier]).to eq([{ error: :blank }])
+ end
+
+ it 'is invalid when end_event is not allowed for the given start_event' do
+ invalid_params = valid_params.merge(
+ start_event_identifier: :merge_request_merged,
+ end_event_identifier: :merge_request_created
+ )
+ stage = described_class.new(invalid_params)
+
+ expect(stage).not_to be_valid
+ expect(stage.errors.details[:end_event]).to eq([{ error: :not_allowed_for_the_given_start_event }])
+ end
+ end
+
+ describe '#subject_model' do
+ it 'infers the model from the start event' do
+ stage = described_class.new(valid_params)
+
+ expect(stage.subject_model).to eq(MergeRequest)
+ end
+ end
+
+ describe '#start_event' do
+ it 'builds start_event object based on start_event_identifier' do
+ stage = described_class.new(start_event_identifier: 'merge_request_created')
+
+ expect(stage.start_event).to be_a_kind_of(Gitlab::Analytics::CycleAnalytics::StageEvents::MergeRequestCreated)
+ end
+ end
+
+ describe '#end_event' do
+ it 'builds end_event object based on end_event_identifier' do
+ stage = described_class.new(end_event_identifier: 'merge_request_merged')
+
+ expect(stage.end_event).to be_a_kind_of(Gitlab::Analytics::CycleAnalytics::StageEvents::MergeRequestMerged)
+ end
+ end
+end
diff --git a/spec/support/shared_examples/requests/api/discussions.rb b/spec/support/shared_examples/requests/api/discussions.rb
index fc72287f265..a36bc2dc9b5 100644
--- a/spec/support/shared_examples/requests/api/discussions.rb
+++ b/spec/support/shared_examples/requests/api/discussions.rb
@@ -1,5 +1,59 @@
# frozen_string_literal: true
+shared_examples 'with cross-reference system notes' do
+ let(:merge_request) { create(:merge_request) }
+ let(:project) { merge_request.project }
+ let(:new_merge_request) { create(:merge_request) }
+ let(:commit) { new_merge_request.project.commit }
+ let!(:note) { create(:system_note, noteable: merge_request, project: project, note: cross_reference) }
+ let!(:note_metadata) { create(:system_note_metadata, note: note, action: 'cross_reference') }
+ let(:cross_reference) { "test commit #{commit.to_reference(project)}" }
+ let(:pat) { create(:personal_access_token, user: user) }
+
+ before do
+ project.add_developer(user)
+ new_merge_request.project.add_developer(user)
+
+ hidden_merge_request = create(:merge_request)
+ new_cross_reference = "test commit #{hidden_merge_request.project.commit}"
+ new_note = create(:system_note, noteable: merge_request, project: project, note: new_cross_reference)
+ create(:system_note_metadata, note: new_note, action: 'cross_reference')
+ end
+
+ it 'returns only the note that the user should see' do
+ get api(url, user, personal_access_token: pat)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response.count).to eq(1)
+ expect(notes_in_response.count).to eq(1)
+
+ parsed_note = notes_in_response.first
+ expect(parsed_note['id']).to eq(note.id)
+ expect(parsed_note['body']).to eq(cross_reference)
+ expect(parsed_note['system']).to be true
+ end
+
+ it 'avoids Git calls and N+1 SQL queries', :request_store do
+ expect_any_instance_of(Repository).not_to receive(:find_commit).with(commit.id)
+
+ control = ActiveRecord::QueryRecorder.new do
+ get api(url, user, personal_access_token: pat)
+ end
+
+ expect(response).to have_gitlab_http_status(200)
+
+ RequestStore.clear!
+
+ new_note = create(:system_note, noteable: merge_request, project: project, note: cross_reference)
+ create(:system_note_metadata, note: new_note, action: 'cross_reference')
+
+ RequestStore.clear!
+
+ expect { get api(url, user, personal_access_token: pat) }.not_to exceed_query_limit(control)
+ expect(response).to have_gitlab_http_status(200)
+ end
+end
+
shared_examples 'discussions API' do |parent_type, noteable_type, id_name, can_reply_to_individual_notes: false|
describe "GET /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions" do
it "returns an array of discussions" do
diff --git a/spec/support/shared_examples/requests/api/pipelines/visibility_table_examples.rb b/spec/support/shared_examples/requests/api/pipelines/visibility_table_examples.rb
new file mode 100644
index 00000000000..dfd07176b1c
--- /dev/null
+++ b/spec/support/shared_examples/requests/api/pipelines/visibility_table_examples.rb
@@ -0,0 +1,235 @@
+# frozen_string_literal: true
+
+shared_examples 'pipelines visibility table' do
+ using RSpec::Parameterized::TableSyntax
+
+ let(:ci_user) { create(:user) }
+ let(:api_user) { user_role && ci_user }
+
+ let(:pipelines_api_path) do
+ "/projects/#{project.id}/pipelines"
+ end
+
+ let(:response_200) do
+ a_collection_containing_exactly(
+ a_hash_including('sha', 'ref', 'status', 'web_url', 'id' => pipeline.id)
+ )
+ end
+
+ let(:response_40x) do
+ a_hash_including('message')
+ end
+
+ let(:expected_response) do
+ if response_status == 200
+ response_200
+ else
+ response_40x
+ end
+ end
+
+ let(:api_response) { json_response }
+
+ let(:visibility_levels) do
+ {
+ private: Gitlab::VisibilityLevel::PRIVATE,
+ internal: Gitlab::VisibilityLevel::INTERNAL,
+ public: Gitlab::VisibilityLevel::PUBLIC
+ }
+ end
+
+ let(:builds_access_levels) do
+ {
+ enabled: ProjectFeature::ENABLED,
+ private: ProjectFeature::PRIVATE
+ }
+ end
+
+ let(:project_attributes) do
+ {
+ visibility_level: visibility_levels[visibility_level],
+ public_builds: public_builds
+ }
+ end
+
+ let(:project_feature_attributes) do
+ {
+ builds_access_level: builds_access_levels[builds_access_level]
+ }
+ end
+
+ where(:visibility_level, :builds_access_level, :public_builds, :is_admin, :user_role, :response_status) do
+ :private | :enabled | true | true | :non_member | 200
+ :private | :enabled | true | true | :guest | 200
+ :private | :enabled | true | true | :reporter | 200
+ :private | :enabled | true | true | :developer | 200
+ :private | :enabled | true | true | :maintainer | 200
+
+ :private | :enabled | true | false | nil | 404
+ :private | :enabled | true | false | :non_member | 404
+ :private | :enabled | true | false | :guest | 200
+ :private | :enabled | true | false | :reporter | 200
+ :private | :enabled | true | false | :developer | 200
+ :private | :enabled | true | false | :maintainer | 200
+
+ :private | :enabled | false | true | :non_member | 200
+ :private | :enabled | false | true | :guest | 200
+ :private | :enabled | false | true | :reporter | 200
+ :private | :enabled | false | true | :developer | 200
+ :private | :enabled | false | true | :maintainer | 200
+
+ :private | :enabled | false | false | nil | 404
+ :private | :enabled | false | false | :non_member | 404
+ :private | :enabled | false | false | :guest | 403
+ :private | :enabled | false | false | :reporter | 200
+ :private | :enabled | false | false | :developer | 200
+ :private | :enabled | false | false | :maintainer | 200
+
+ :private | :private | true | true | :non_member | 200
+ :private | :private | true | true | :guest | 200
+ :private | :private | true | true | :reporter | 200
+ :private | :private | true | true | :developer | 200
+ :private | :private | true | true | :maintainer | 200
+
+ :private | :private | true | false | nil | 404
+ :private | :private | true | false | :non_member | 404
+ :private | :private | true | false | :guest | 200
+ :private | :private | true | false | :reporter | 200
+ :private | :private | true | false | :developer | 200
+ :private | :private | true | false | :maintainer | 200
+
+ :private | :private | false | true | :non_member | 200
+ :private | :private | false | true | :guest | 200
+ :private | :private | false | true | :reporter | 200
+ :private | :private | false | true | :developer | 200
+ :private | :private | false | true | :maintainer | 200
+
+ :private | :private | false | false | nil | 404
+ :private | :private | false | false | :non_member | 404
+ :private | :private | false | false | :guest | 403
+ :private | :private | false | false | :reporter | 200
+ :private | :private | false | false | :developer | 200
+ :private | :private | false | false | :maintainer | 200
+
+ :internal | :enabled | true | true | :non_member | 200
+ :internal | :enabled | true | true | :guest | 200
+ :internal | :enabled | true | true | :reporter | 200
+ :internal | :enabled | true | true | :developer | 200
+ :internal | :enabled | true | true | :maintainer | 200
+
+ :internal | :enabled | true | false | nil | 404
+ :internal | :enabled | true | false | :non_member | 200
+ :internal | :enabled | true | false | :guest | 200
+ :internal | :enabled | true | false | :reporter | 200
+ :internal | :enabled | true | false | :developer | 200
+ :internal | :enabled | true | false | :maintainer | 200
+
+ :internal | :enabled | false | true | :non_member | 200
+ :internal | :enabled | false | true | :guest | 200
+ :internal | :enabled | false | true | :reporter | 200
+ :internal | :enabled | false | true | :developer | 200
+ :internal | :enabled | false | true | :maintainer | 200
+
+ :internal | :enabled | false | false | nil | 404
+ :internal | :enabled | false | false | :non_member | 403
+ :internal | :enabled | false | false | :guest | 403
+ :internal | :enabled | false | false | :reporter | 200
+ :internal | :enabled | false | false | :developer | 200
+ :internal | :enabled | false | false | :maintainer | 200
+
+ :internal | :private | true | true | :non_member | 200
+ :internal | :private | true | true | :guest | 200
+ :internal | :private | true | true | :reporter | 200
+ :internal | :private | true | true | :developer | 200
+ :internal | :private | true | true | :maintainer | 200
+
+ :internal | :private | true | false | nil | 404
+ :internal | :private | true | false | :non_member | 403
+ :internal | :private | true | false | :guest | 200
+ :internal | :private | true | false | :reporter | 200
+ :internal | :private | true | false | :developer | 200
+ :internal | :private | true | false | :maintainer | 200
+
+ :internal | :private | false | true | :non_member | 200
+ :internal | :private | false | true | :guest | 200
+ :internal | :private | false | true | :reporter | 200
+ :internal | :private | false | true | :developer | 200
+ :internal | :private | false | true | :maintainer | 200
+
+ :internal | :private | false | false | nil | 404
+ :internal | :private | false | false | :non_member | 403
+ :internal | :private | false | false | :guest | 403
+ :internal | :private | false | false | :reporter | 200
+ :internal | :private | false | false | :developer | 200
+ :internal | :private | false | false | :maintainer | 200
+
+ :public | :enabled | true | true | :non_member | 200
+ :public | :enabled | true | true | :guest | 200
+ :public | :enabled | true | true | :reporter | 200
+ :public | :enabled | true | true | :developer | 200
+ :public | :enabled | true | true | :maintainer | 200
+
+ :public | :enabled | true | false | nil | 200
+ :public | :enabled | true | false | :non_member | 200
+ :public | :enabled | true | false | :guest | 200
+ :public | :enabled | true | false | :reporter | 200
+ :public | :enabled | true | false | :developer | 200
+ :public | :enabled | true | false | :maintainer | 200
+
+ :public | :enabled | false | true | :non_member | 200
+ :public | :enabled | false | true | :guest | 200
+ :public | :enabled | false | true | :reporter | 200
+ :public | :enabled | false | true | :developer | 200
+ :public | :enabled | false | true | :maintainer | 200
+
+ :public | :enabled | false | false | nil | 403
+ :public | :enabled | false | false | :non_member | 403
+ :public | :enabled | false | false | :guest | 403
+ :public | :enabled | false | false | :reporter | 200
+ :public | :enabled | false | false | :developer | 200
+ :public | :enabled | false | false | :maintainer | 200
+
+ :public | :private | true | true | :non_member | 200
+ :public | :private | true | true | :guest | 200
+ :public | :private | true | true | :reporter | 200
+ :public | :private | true | true | :developer | 200
+ :public | :private | true | true | :maintainer | 200
+
+ :public | :private | true | false | nil | 403
+ :public | :private | true | false | :non_member | 403
+ :public | :private | true | false | :guest | 200
+ :public | :private | true | false | :reporter | 200
+ :public | :private | true | false | :developer | 200
+ :public | :private | true | false | :maintainer | 200
+
+ :public | :private | false | true | :non_member | 200
+ :public | :private | false | true | :guest | 200
+ :public | :private | false | true | :reporter | 200
+ :public | :private | false | true | :developer | 200
+ :public | :private | false | true | :maintainer | 200
+
+ :public | :private | false | false | nil | 403
+ :public | :private | false | false | :non_member | 403
+ :public | :private | false | false | :guest | 403
+ :public | :private | false | false | :reporter | 200
+ :public | :private | false | false | :developer | 200
+ :public | :private | false | false | :maintainer | 200
+ end
+
+ with_them do
+ before do
+ ci_user.update!(admin: is_admin) if user_role
+
+ project.update!(project_attributes)
+ project.project_feature.update!(project_feature_attributes)
+ project.add_role(ci_user, user_role) if user_role && user_role != :non_member
+
+ get api(pipelines_api_path, api_user)
+ end
+
+ it do
+ expect(response).to have_gitlab_http_status(response_status)
+ expect(api_response).to match(expected_response)
+ end
+ end
+end
diff --git a/yarn.lock b/yarn.lock
index 4489b10815a..ef66861488c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -998,10 +998,10 @@
dependencies:
vue-eslint-parser "^6.0.4"
-"@gitlab/svgs@^1.68.0":
- version "1.68.0"
- resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.68.0.tgz#d631bd84ea7907592240d8417e82ba66d6a54c0c"
- integrity sha512-3JmIq0bHg4InjLooM+kQFPfg3d7B1Pye67pN9+12kZXIa0nRGuwKEq3WSbcS+ACdg5jcVPNPYqStItEO4teHdw==
+"@gitlab/svgs@^1.70.0":
+ version "1.70.0"
+ resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.70.0.tgz#bdae478148c15d955fc06e69fd5d5ecae8298943"
+ integrity sha512-0uV9fgTwe17Fyy0hTcrsGX2jJuCrz3uRIe8yffuqc6pbQrSfYJyN66mfCCB45wq8lKTgOB5q0qcUyJx3RQEcKg==
"@gitlab/ui@5.18.0":
version "5.18.0"
@@ -1021,6 +1021,11 @@
vue "^2.6.10"
vue-loader "^15.4.2"
+"@gitlab/visual-review-tools@^1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@gitlab/visual-review-tools/-/visual-review-tools-1.0.0.tgz#6012e0a19797c1f5dad34ccf4dacdaf38e400a73"
+ integrity sha512-xMvz9IwrXisQ1MH+Tj6lfbQcQSiQy88nTPuQV6OTLBGuV+vIQeVwXeIkQeTKuSpd0GqZvigPdRqxyQCa3blpIg==
+
"@gitlab/vue-toasted@^1.2.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@gitlab/vue-toasted/-/vue-toasted-1.2.1.tgz#f407b5aa710863e5b7f021f4a1f66160331ab263"