diff --git a/.gitignore b/.gitignore index eda4ba62b9a..71ecf31a50b 100644 --- a/.gitignore +++ b/.gitignore @@ -383,4 +383,224 @@ db/schema_migrations/20181219145521 db/schema_migrations/20190225160300 # Removed in 44f9d16edca328e5bb234b853f0d670ee0b30a26 db/schema_migrations/20200615101135 +# Removed in cfae6ec2647 +db/schema_migrations/20180502134117 +db/schema_migrations/20180521162137 +db/schema_migrations/20180619121030 +db/schema_migrations/20180723130817 +db/schema_migrations/20180906051323 +db/schema_migrations/20180913051323 +db/schema_migrations/20180916014356 +db/schema_migrations/20181014121030 +db/schema_migrations/20181204154019 +db/schema_migrations/20180103234731 +db/schema_migrations/20180104001824 +db/schema_migrations/20180105233807 +db/schema_migrations/20180109150457 +db/schema_migrations/20180115013218 +db/schema_migrations/20180126165535 +db/schema_migrations/20180131104538 +db/schema_migrations/20180201101405 +db/schema_migrations/20180201192230 +db/schema_migrations/20180206184810 +db/schema_migrations/20180215143644 +db/schema_migrations/20180225180932 +db/schema_migrations/20180302230551 +db/schema_migrations/20180307164427 +db/schema_migrations/20180308234102 +db/schema_migrations/20180314174825 +db/schema_migrations/20180317020334 +db/schema_migrations/20180320142552 +db/schema_migrations/20180325034910 +db/schema_migrations/20180329230151 +db/schema_migrations/20180401213713 +db/schema_migrations/20180416112831 +db/schema_migrations/20180416205949 +db/schema_migrations/20180419031622 +db/schema_migrations/20180419171038 +db/schema_migrations/20180423165301 +db/schema_migrations/20180502124117 +db/schema_migrations/20180502125859 +db/schema_migrations/20180503154922 +db/schema_migrations/20180520211048 +db/schema_migrations/20180524115107 +db/schema_migrations/20180531031410 +db/schema_migrations/20180531221734 +db/schema_migrations/20180607154422 +db/schema_migrations/20180607154516 +db/schema_migrations/20180607154645 +db/schema_migrations/20180612175636 +db/schema_migrations/20180615152524 +db/schema_migrations/20180621100024 +db/schema_migrations/20180621100025 +db/schema_migrations/20180623053658 +db/schema_migrations/20180626171125 +db/schema_migrations/20180702114215 +db/schema_migrations/20180702181530 +db/schema_migrations/20180709153607 +db/schema_migrations/20180709183353 +db/schema_migrations/20180709184533 +db/schema_migrations/20180711014025 +db/schema_migrations/20180711014026 +db/schema_migrations/20180718100455 +db/schema_migrations/20180719161844 +db/schema_migrations/20180720082636 +db/schema_migrations/20180720120716 +db/schema_migrations/20180720120726 +db/schema_migrations/20180720121404 +db/schema_migrations/20180723023517 +db/schema_migrations/20180723081631 +db/schema_migrations/20180723134433 +db/schema_migrations/20180724161450 +db/schema_migrations/20180803001726 +db/schema_migrations/20180803041220 +db/schema_migrations/20180806145747 +db/schema_migrations/20180823132905 +db/schema_migrations/20180831134049 +db/schema_migrations/20180831152625 +db/schema_migrations/20180910104020 +db/schema_migrations/20180910105100 +db/schema_migrations/20180912113336 +db/schema_migrations/20180917145556 +db/schema_migrations/20180917171038 +db/schema_migrations/20180917171533 +db/schema_migrations/20180917171534 +db/schema_migrations/20180917171535 +db/schema_migrations/20180917213751 +db/schema_migrations/20180917214204 +db/schema_migrations/20180920043317 +db/schema_migrations/20180924070647 +db/schema_migrations/20180926101838 +db/schema_migrations/20180926140319 +db/schema_migrations/20180930171532 +db/schema_migrations/20181001172126 +db/schema_migrations/20181001172651 +db/schema_migrations/20181004131020 +db/schema_migrations/20181004131025 +db/schema_migrations/20181012151642 +db/schema_migrations/20181017131623 +db/schema_migrations/20181022131445 +db/schema_migrations/20181025000427 +db/schema_migrations/20181025030732 +db/schema_migrations/20181026085436 +db/schema_migrations/20181028092114 +db/schema_migrations/20181028092115 +db/schema_migrations/20181105122803 +db/schema_migrations/20181114163403 +db/schema_migrations/20181121174028 +db/schema_migrations/20181121175359 +db/schema_migrations/20181123090058 +db/schema_migrations/20181123100058 +db/schema_migrations/20181126125616 +db/schema_migrations/20181127130125 +db/schema_migrations/20181127133629 +db/schema_migrations/20181127203117 +db/schema_migrations/20181201151856 +db/schema_migrations/20181203154104 +db/schema_migrations/20181204031328 +db/schema_migrations/20181204031329 +db/schema_migrations/20181204031330 +db/schema_migrations/20181204031331 +db/schema_migrations/20181204135519 +db/schema_migrations/20181204135932 +db/schema_migrations/20181205093951 +db/schema_migrations/20181206121338 +db/schema_migrations/20181220163029 +db/schema_migrations/20181221135205 +db/schema_migrations/20181228140935 +db/schema_migrations/20190110200434 +db/schema_migrations/20190111183834 +db/schema_migrations/20190114040404 +db/schema_migrations/20190114040405 +db/schema_migrations/20190121140418 +db/schema_migrations/20190121140658 +db/schema_migrations/20190122101816 +db/schema_migrations/20190123211816 +db/schema_migrations/20190128104236 +db/schema_migrations/20190128172533 +db/schema_migrations/20190129013538 +db/schema_migrations/20190130164903 +db/schema_migrations/20190218031401 +db/schema_migrations/20190218144405 +db/schema_migrations/20190219134239 +db/schema_migrations/20190219210244 +db/schema_migrations/20190220112238 +db/schema_migrations/20190222105948 +db/schema_migrations/20190222110418 +db/schema_migrations/20190225173106 +db/schema_migrations/20190226154144 +db/schema_migrations/20190228134845 +db/schema_migrations/20190301095211 +db/schema_migrations/20190301182031 +db/schema_migrations/20190302144241 +db/schema_migrations/20190304020812 +db/schema_migrations/20190304223216 +db/schema_migrations/20190304223220 +db/schema_migrations/20190305162221 +db/schema_migrations/20190318020549 +db/schema_migrations/20190318021429 +db/schema_migrations/20190318120957 +db/schema_migrations/20190320162221 +db/schema_migrations/20190321103531 +db/schema_migrations/20190322145954 +db/schema_migrations/20190327085945 +db/schema_migrations/20190328210840 +db/schema_migrations/20190401150745 +db/schema_migrations/20190401150746 +db/schema_migrations/20190402112450 +db/schema_migrations/20180309215236 +db/schema_migrations/20180314172513 +db/schema_migrations/20180417102933 +db/schema_migrations/20180502130136 +db/schema_migrations/20180509091305 +db/schema_migrations/20180605213516 +db/schema_migrations/20180608150653 +db/schema_migrations/20180618193715 +db/schema_migrations/20180713171825 +db/schema_migrations/20180815043102 +db/schema_migrations/20180914195058 +db/schema_migrations/20181014131030 +db/schema_migrations/20181115140251 +db/schema_migrations/20181116100917 +db/schema_migrations/20181204040404 +db/schema_migrations/20181206121340 +db/schema_migrations/20181215161939 +db/schema_migrations/20181220165848 +db/schema_migrations/20190111231855 +# Removed in ef1efa0f650 +db/schema_migrations/20180406204716 +db/schema_migrations/20180521171529 +db/schema_migrations/20180831164904 +# Removed in 28ac2d30498 +db/schema_migrations/20180202111106 +# Removed in b87dcc238a8 +db/schema_migrations/20181218192239 +# Removed in various revert commits +db/schema_migrations/20180115094742 +db/schema_migrations/20180115113902 +db/schema_migrations/20190107151029 +db/schema_migrations/20190114184258 +db/schema_migrations/20190228092516 +db/schema_migrations/20190311132500 +db/schema_migrations/20190311132527 +db/schema_migrations/20190703001116 +db/schema_migrations/20190703001120 +db/schema_migrations/20190724091326 +db/schema_migrations/20190801072937 +db/schema_migrations/20191004134055 +db/schema_migrations/20191029060358 +db/schema_migrations/20191029061556 +db/schema_migrations/20191220102807 +db/schema_migrations/20200123092602 +db/schema_migrations/20200123101859 +db/schema_migrations/20200127111953 +db/schema_migrations/20200127131953 +db/schema_migrations/20200127141953 +db/schema_migrations/20200127151953 +db/schema_migrations/20200206111847 +db/schema_migrations/20200214173000 +db/schema_migrations/20200214174519 +db/schema_migrations/20200214174607 +db/schema_migrations/20200309105539 +db/schema_migrations/20200615203153 diff --git a/app/helpers/environments_helper.rb b/app/helpers/environments_helper.rb index c83bf702f50..7d5a1adc1dc 100644 --- a/app/helpers/environments_helper.rb +++ b/app/helpers/environments_helper.rb @@ -111,7 +111,7 @@ module EnvironmentsHelper 'empty-no-data-svg-path' => image_path('illustrations/monitoring/no_data.svg'), 'empty-no-data-small-svg-path' => image_path('illustrations/chart-empty-state-small.svg'), 'empty-unable-to-connect-svg-path' => image_path('illustrations/monitoring/unable_to_connect.svg'), - 'custom-dashboard-base-path' => Metrics::Dashboard::CustomDashboardService::DASHBOARD_ROOT + 'custom-dashboard-base-path' => Gitlab::Metrics::Dashboard::RepoDashboardFinder::DASHBOARD_ROOT } end end diff --git a/app/models/repository.rb b/app/models/repository.rb index bec7cda5250..f4244764338 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -43,7 +43,7 @@ class Repository gitlab_ci_yml branch_names tag_names branch_count tag_count avatar exists? root_ref merged_branch_names has_visible_content? issue_template_names merge_request_template_names - metrics_dashboard_paths xcode_project?).freeze + user_defined_metrics_dashboard_paths xcode_project?).freeze # Methods that use cache_method but only memoize the value MEMOIZED_CACHED_METHODS = %i(license).freeze @@ -61,7 +61,7 @@ class Repository avatar: :avatar, issue_template: :issue_template_names, merge_request_template: :merge_request_template_names, - metrics_dashboard: :metrics_dashboard_paths, + metrics_dashboard: :user_defined_metrics_dashboard_paths, xcode_config: :xcode_project? }.freeze @@ -576,10 +576,10 @@ class Repository end cache_method :merge_request_template_names, fallback: [] - def metrics_dashboard_paths - Gitlab::Metrics::Dashboard::Finder.find_all_paths_from_source(project) + def user_defined_metrics_dashboard_paths + Gitlab::Metrics::Dashboard::RepoDashboardFinder.list_dashboards(project) end - cache_method :metrics_dashboard_paths + cache_method :user_defined_metrics_dashboard_paths, fallback: [] def readme head_tree&.readme diff --git a/app/services/metrics/dashboard/clone_dashboard_service.rb b/app/services/metrics/dashboard/clone_dashboard_service.rb index a2605ca21dc..b5df82ea92a 100644 --- a/app/services/metrics/dashboard/clone_dashboard_service.rb +++ b/app/services/metrics/dashboard/clone_dashboard_service.rb @@ -9,7 +9,7 @@ module Metrics include Gitlab::Utils::StrongMemoize ALLOWED_FILE_TYPE = '.yml' - USER_DASHBOARDS_DIR = ::Metrics::Dashboard::CustomDashboardService::DASHBOARD_ROOT + USER_DASHBOARDS_DIR = ::Gitlab::Metrics::Dashboard::RepoDashboardFinder::DASHBOARD_ROOT SEQUENCES = { ::Metrics::Dashboard::SystemDashboardService::DASHBOARD_PATH => [ ::Gitlab::Metrics::Dashboard::Stages::CommonMetricsInserter, diff --git a/app/services/metrics/dashboard/custom_dashboard_service.rb b/app/services/metrics/dashboard/custom_dashboard_service.rb index 741738cc3af..f0f19bf2ba3 100644 --- a/app/services/metrics/dashboard/custom_dashboard_service.rb +++ b/app/services/metrics/dashboard/custom_dashboard_service.rb @@ -6,16 +6,13 @@ module Metrics module Dashboard class CustomDashboardService < ::Metrics::Dashboard::BaseService - DASHBOARD_ROOT = ".gitlab/dashboards" - class << self def valid_params?(params) params[:dashboard_path].present? end def all_dashboard_paths(project) - file_finder(project) - .list_files_for(DASHBOARD_ROOT) + project.repository.user_defined_metrics_dashboard_paths .map do |filepath| { path: filepath, @@ -27,13 +24,9 @@ module Metrics end end - def file_finder(project) - Gitlab::Template::Finders::RepoTemplateFinder.new(project, DASHBOARD_ROOT, '.yml') - end - # Grabs the filepath after the base directory. def name_for_path(filepath) - filepath.delete_prefix("#{DASHBOARD_ROOT}/") + filepath.delete_prefix("#{Gitlab::Metrics::Dashboard::RepoDashboardFinder::DASHBOARD_ROOT}/") end end @@ -41,7 +34,7 @@ module Metrics # Searches the project repo for a custom-defined dashboard. def get_raw_dashboard - yml = self.class.file_finder(project).read(dashboard_path) + yml = Gitlab::Metrics::Dashboard::RepoDashboardFinder.read_dashboard(project, dashboard_path) load_yaml(yml) end diff --git a/app/services/metrics/dashboard/update_dashboard_service.rb b/app/services/metrics/dashboard/update_dashboard_service.rb index b501e368153..d990e96ecb5 100644 --- a/app/services/metrics/dashboard/update_dashboard_service.rb +++ b/app/services/metrics/dashboard/update_dashboard_service.rb @@ -7,7 +7,7 @@ module Metrics include Stepable ALLOWED_FILE_TYPE = '.yml' - USER_DASHBOARDS_DIR = ::Metrics::Dashboard::CustomDashboardService::DASHBOARD_ROOT + USER_DASHBOARDS_DIR = ::Gitlab::Metrics::Dashboard::RepoDashboardFinder::DASHBOARD_ROOT steps :check_push_authorized, :check_branch_name, diff --git a/doc/development/documentation/styleguide.md b/doc/development/documentation/styleguide.md index bb5931a11d6..9ad93ae01fd 100644 --- a/doc/development/documentation/styleguide.md +++ b/doc/development/documentation/styleguide.md @@ -265,8 +265,8 @@ because it’s friendly and easy to understand. Use sentence case. For example: -- `## Use variables to configure pipelines` -- `You can use the To-Do List.` +- `# Use variables to configure pipelines` +- `## Use the To-Do List` #### UI text diff --git a/doc/development/telemetry/index.md b/doc/development/telemetry/index.md index 871f7a13d42..00cda29b8c8 100644 --- a/doc/development/telemetry/index.md +++ b/doc/development/telemetry/index.md @@ -6,60 +6,36 @@ info: To determine the technical writer assigned to the Stage/Group associated w # Telemetry Guide -At GitLab, we collect telemetry for the purpose of helping us build a better GitLab. Data about how GitLab is used is collected to better understand what parts of GitLab needs improvement and what features to build next. Telemetry also helps our team better understand the reasons why people use GitLab and with this knowledge we are able to make better product decisions. +At GitLab, we collect telemetry for the purpose of helping us build a better product. Data helps GitLab understand which parts of the product need improvement and which features we should build next. Telemetry also helps our team better understand the reasons why people use GitLab. With this knowledge we are able to make better product decisions. -We also encourage users to enable tracking, and we embrace full transparency with our tracking approach so it can be easily understood and trusted. By enabling tracking, users can: +We encourage users to enable tracking, and we embrace full transparency with our tracking approach so it can be easily understood and trusted. + +By enabling tracking, users can: - Contribute back to the wider community. - Help GitLab improve on the product. -This documentation consists of three guides providing an overview of Telemetry at GitLab. - -Telemetry Guide: - - 1. [Our tracking tools](#our-tracking-tools) - 1. [What data can be tracked](#what-data-can-be-tracked) - 1. [Telemetry systems overview](#telemetry-systems-overview) - 1. [Snowflake data warehouse](#snowflake-data-warehouse) - -[Usage Ping Guide](usage_ping.md) - - 1. [What is Usage Ping](usage_ping.md#what-is-usage-ping) - 1. [Usage Ping payload](usage_ping.md#usage-ping-payload) - 1. [Disable Usage Ping](usage_ping.md#disable-usage-ping) - 1. [Usage Ping request flow](usage_ping.md#usage-ping-request-flow) - 1. [How Usage Ping works](usage_ping.md#how-usage-ping-works) - 1. [Implementing Usage Ping](usage_ping.md#implementing-usage-ping) - 1. [Developing and testing Usage Ping](usage_ping.md#developing-and-testing-usage-ping) - -[Snowplow Guide](snowplow.md) - -1. [What is Snowplow](snowplow.md#what-is-snowplow) -1. [Snowplow schema](snowplow.md#snowplow-schema) -1. [Enabling Snowplow](snowplow.md#enabling-snowplow) -1. [Snowplow request flow](snowplow.md#snowplow-request-flow) -1. [Implementing Snowplow JS (Frontend) tracking](snowplow.md#implementing-snowplow-js-frontend-tracking) -1. [Implementing Snowplow Ruby (Backend) tracking](snowplow.md#implementing-snowplow-ruby-backend-tracking) -1. [Developing and testing Snowplow](snowplow.md#developing-and-testing-snowplow) - -More useful links: - -- [Telemetry Direction](https://about.gitlab.com/direction/telemetry/) -- [Data Analysis Process](https://about.gitlab.com/handbook/business-ops/data-team/#data-analysis-process/) -- [Data for Product Managers](https://about.gitlab.com/handbook/business-ops/data-team/programs/data-for-product-managers/) -- [Data Infrastructure](https://about.gitlab.com/handbook/business-ops/data-team/platform/infrastructure/) - ## Our tracking tools -We use several different technologies to gather product usage data. +We use several different technologies to gather product usage data: -### Snowplow JS (Frontend) +- [Snowplow](#snowplow) +- [Usage Ping](#usage-ping) +- [Database import](#database-import) +- [Log system](#log-system) -Snowplow is an enterprise-grade marketing and product analytics platform which helps track the way users engage with our website and application. [Snowplow JS](https://github.com/snowplow/snowplow/wiki/javascript-tracker) is a frontend tracker for client-side events. +### Snowplow -### Snowplow Ruby (Backend) +Snowplow is an enterprise-grade marketing and product analytics platform which helps track the way +users engage with our website and application. -Snowplow is an enterprise-grade marketing and product analytics platform which helps track the way users engage with our website and application. [Snowplow Ruby](https://github.com/snowplow/snowplow/wiki/ruby-tracker) is a backend tracker for server-side events. +Snowplow consists of two components: + +- [Snowplow JS](https://github.com/snowplow/snowplow/wiki/javascript-tracker) tracks client-side + events. +- [Snowplow Ruby](https://github.com/snowplow/snowplow/wiki/ruby-tracker) tracks server-side events. + +For more details, read the [Snowplow](snowplow.md) guide. ### Usage Ping @@ -220,3 +196,12 @@ There are several data sources available in Snowflake and Sisense each represent | analytics | These tables have typically undergone more data transformation. They will typically end in `_xf` to represent the fact that they are transformed | Access via Snowflake or Sisense | If you are a Product Manager interested in the raw data, you will likely focus on the `analytics` and `analytics_staging` sources. The raw source is limited to the data and infrastructure teams. For more information, please see [Data For Product Managers: What's the difference between analytics_staging and analytics?](https://about.gitlab.com/handbook/business-ops/data-team/programs/data-for-product-managers/#whats-the-difference-between-analytics_staging-and-analytics) + +## Additional information + +More useful links: + +- [Telemetry Direction](https://about.gitlab.com/direction/telemetry/) +- [Data Analysis Process](https://about.gitlab.com/handbook/business-ops/data-team/#data-analysis-process/) +- [Data for Product Managers](https://about.gitlab.com/handbook/business-ops/data-team/programs/data-for-product-managers/) +- [Data Infrastructure](https://about.gitlab.com/handbook/business-ops/data-team/platform/infrastructure/) diff --git a/doc/operations/incident_management/img/incident_list_13_3.png b/doc/operations/incident_management/img/incident_list_13_3.png new file mode 100644 index 00000000000..cd049eeed49 Binary files /dev/null and b/doc/operations/incident_management/img/incident_list_13_3.png differ diff --git a/doc/operations/incident_management/index.md b/doc/operations/incident_management/index.md index 6a395e3cfbb..93eb9996da9 100644 --- a/doc/operations/incident_management/index.md +++ b/doc/operations/incident_management/index.md @@ -7,7 +7,38 @@ info: To determine the technical writer assigned to the Stage/Group associated w # Incident management GitLab offers solutions for handling incidents in your applications and services, -such as setting up Prometheus alerts, displaying metrics, and sending notifications. +such as [setting up Prometheus alerts](#configure-prometheus-alerts), +[displaying metrics](#embed-metrics-in-incidents-and-issues), and sending notifications. +While no configuration is required to use the [manual features](#create-an-incident-manually) +of incident management, both automation and [configuration](#configure-incidents-ultimate) +of incident management are only available in +[GitLab Ultimate and GitLab.com Gold](https://about.gitlab.com/pricing/). + +For users with at least Developer [permissions](../../user/permissions.md), the +Incident Management list is available at **{cloud-gear}** **Operations > Incidents** +in your project's sidebar. The list contains the following metrics: + +![Incident Management List](img/incident_list_13_3.png) + +- **Incident** - The description of the incident, which attempts to capture the + most meaningful data. +- **Date created** - How long ago the incident was created. This field uses the + standard GitLab pattern of `X time ago`, but is supported by a granular date/time + tooltip depending on the user's locale. +- **Assignees** - The user assigned to the incident. + +NOTE: **Note:** +Incidents share the [Issues API](../../user/project/issues/index.md). + +## Create an incident manually + +> [Moved](https://gitlab.com/gitlab-org/monitor/health/-/issues/24) to GitLab core in 13.3. + +To create a Incident you can take any of the following actions: + +- Navigate to **{cloud-gear}** **Operations > Incidents** and click **Create Incident**. +- Create a new issue using the `incident` template available when creating it. +- Create a new issue and assign the `incident` label to it. ## Configure incidents **(ULTIMATE)** diff --git a/doc/user/packages/composer_repository/index.md b/doc/user/packages/composer_repository/index.md index d1b9f134cc6..cb67cd3378c 100644 --- a/doc/user/packages/composer_repository/index.md +++ b/doc/user/packages/composer_repository/index.md @@ -69,7 +69,8 @@ git init git add composer.json git commit -m 'Composer package test' git tag v1.0.0 -git add origin git@gitlab.com:/.git +git remote add origin git@gitlab.com:/.git +git push --set-upstream origin master git push origin v1.0.0 ``` diff --git a/lib/gitlab/metrics/dashboard/finder.rb b/lib/gitlab/metrics/dashboard/finder.rb index 5e2d78e10a4..6b3f1e7a850 100644 --- a/lib/gitlab/metrics/dashboard/finder.rb +++ b/lib/gitlab/metrics/dashboard/finder.rb @@ -72,14 +72,6 @@ module Gitlab # display_name: String, # default: Boolean }] def find_all_paths(project) - project.repository.metrics_dashboard_paths - end - - # Summary of all known dashboards. Used to populate repo cache. - # Prefer #find_all_paths. - def find_all_paths_from_source(project) - Gitlab::Metrics::Dashboard::Cache.delete_all! - user_facing_dashboard_services(project).flat_map do |service| service.all_dashboard_paths(project) end diff --git a/lib/gitlab/metrics/dashboard/repo_dashboard_finder.rb b/lib/gitlab/metrics/dashboard/repo_dashboard_finder.rb new file mode 100644 index 00000000000..3da2be84bfe --- /dev/null +++ b/lib/gitlab/metrics/dashboard/repo_dashboard_finder.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +# Provides methods to list and read dashboard yaml files from a project's repository. +module Gitlab + module Metrics + module Dashboard + class RepoDashboardFinder + DASHBOARD_ROOT = ".gitlab/dashboards" + DASHBOARD_EXTENSION = '.yml' + + class << self + # Returns list of all user-defined dashboard paths. Used to populate + # Repository model cache (Repository#user_defined_metrics_dashboard_paths). + # Also deletes all dashboard cache entries. + # @return [Array] ex) ['.gitlab/dashboards/dashboard1.yml'] + def list_dashboards(project) + Gitlab::Metrics::Dashboard::Cache.delete_all! + + file_finder(project).list_files_for(DASHBOARD_ROOT) + end + + # Reads the given dashboard from repository, and returns the content as a string. + # @return [String] + def read_dashboard(project, dashboard_path) + file_finder(project).read(dashboard_path) + end + + private + + def file_finder(project) + Gitlab::Template::Finders::RepoTemplateFinder.new(project, DASHBOARD_ROOT, DASHBOARD_EXTENSION) + end + end + end + end + end +end diff --git a/spec/helpers/environments_helper_spec.rb b/spec/helpers/environments_helper_spec.rb index 691a9e05ba9..84e7e00e184 100644 --- a/spec/helpers/environments_helper_spec.rb +++ b/spec/helpers/environments_helper_spec.rb @@ -42,7 +42,7 @@ RSpec.describe EnvironmentsHelper do 'custom-metrics-available' => 'true', 'alerts-endpoint' => project_prometheus_alerts_path(project, environment_id: environment.id, format: :json), 'prometheus-alerts-available' => 'true', - 'custom-dashboard-base-path' => Metrics::Dashboard::CustomDashboardService::DASHBOARD_ROOT, + 'custom-dashboard-base-path' => Gitlab::Metrics::Dashboard::RepoDashboardFinder::DASHBOARD_ROOT, 'operations-settings-path' => project_settings_operations_path(project), 'can-access-operations-settings' => 'true' ) diff --git a/spec/lib/gitlab/metrics/dashboard/repo_dashboard_finder_spec.rb b/spec/lib/gitlab/metrics/dashboard/repo_dashboard_finder_spec.rb new file mode 100644 index 00000000000..be17591d9b2 --- /dev/null +++ b/spec/lib/gitlab/metrics/dashboard/repo_dashboard_finder_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Metrics::Dashboard::RepoDashboardFinder do + include MetricsDashboardHelpers + + let_it_be(:project) { create(:project) } + + describe '.list_dashboards' do + it 'deletes dashboard cache entries' do + expect(Gitlab::Metrics::Dashboard::Cache).to receive(:delete_all!).and_call_original + + described_class.list_dashboards(project) + end + + it 'returns empty array when there are no dashboards' do + expect(described_class.list_dashboards(project)).to eq([]) + end + + context 'when there are project dashboards available' do + let_it_be(:dashboard_path) { '.gitlab/dashboards/test.yml' } + let_it_be(:project) { project_with_dashboard(dashboard_path) } + + it 'returns the dashboard list' do + expect(described_class.list_dashboards(project)).to contain_exactly(dashboard_path) + end + end + end + + describe '.read_dashboard' do + it 'raises error when dashboard does not exist' do + dashboard_path = '.gitlab/dashboards/test.yml' + + expect { described_class.read_dashboard(project, dashboard_path) }.to raise_error( + Gitlab::Metrics::Dashboard::Errors::NOT_FOUND_ERROR + ) + end + + context 'when there are project dashboards available' do + let_it_be(:dashboard_path) { '.gitlab/dashboards/test.yml' } + let_it_be(:project) { project_with_dashboard(dashboard_path) } + + it 'reads dashboard' do + expect(described_class.read_dashboard(project, dashboard_path)).to eq( + fixture_file('lib/gitlab/metrics/dashboard/sample_dashboard.yml') + ) + end + end + end +end diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 964cc5a13ca..0b7e501daaf 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -1926,7 +1926,7 @@ RSpec.describe Repository do :has_visible_content?, :issue_template_names, :merge_request_template_names, - :metrics_dashboard_paths, + :user_defined_metrics_dashboard_paths, :xcode_project? ]) diff --git a/spec/services/metrics/dashboard/custom_dashboard_service_spec.rb b/spec/services/metrics/dashboard/custom_dashboard_service_spec.rb index d4391ecb6b9..33643a2fbb2 100644 --- a/spec/services/metrics/dashboard/custom_dashboard_service_spec.rb +++ b/spec/services/metrics/dashboard/custom_dashboard_service_spec.rb @@ -104,6 +104,16 @@ RSpec.describe Metrics::Dashboard::CustomDashboardService, :use_clean_rails_memo }] ) end + + it 'caches repo file list' do + expect(Gitlab::Metrics::Dashboard::RepoDashboardFinder).to receive(:list_dashboards) + .with(project) + .once + .and_call_original + + described_class.all_dashboard_paths(project) + described_class.all_dashboard_paths(project) + end end end