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--app/models/concerns/referable.rb2
-rw-r--r--doc/user/analytics/code_review_analytics.md35
-rw-r--r--doc/user/analytics/index.md2
-rw-r--r--doc/user/project/operations/error_tracking.md5
-rw-r--r--doc/user/project/operations/img/error_details_v12_7.pngbin0 -> 92858 bytes
-rw-r--r--lib/banzai/filter/abstract_reference_filter.rb4
-rw-r--r--lib/gitlab/pagination/base.rb25
-rw-r--r--lib/gitlab/pagination/keyset/pager.rb2
-rw-r--r--lib/gitlab/pagination/offset_pagination.rb23
-rw-r--r--spec/frontend/environments/environment_monitoring_spec.js1
-rw-r--r--spec/frontend/environments/environment_rollback_spec.js2
-rw-r--r--spec/frontend/environments/environment_stop_spec.js1
-rw-r--r--spec/frontend/environments/environment_terminal_button_spec.js1
-rw-r--r--spec/frontend/monitoring/components/charts/time_series_spec.js1
-rw-r--r--spec/frontend/monitoring/components/dashboard_spec.js43
-rw-r--r--spec/frontend/monitoring/components/dashboard_time_url_spec.js5
-rw-r--r--spec/frontend/monitoring/components/dashboard_time_window_spec.js5
-rw-r--r--spec/frontend/monitoring/panel_type_spec.js2
-rw-r--r--spec/migrations/20190924152703_migrate_issue_trackers_data_spec.rb2
19 files changed, 84 insertions, 77 deletions
diff --git a/app/models/concerns/referable.rb b/app/models/concerns/referable.rb
index 4a506146de3..3b0606aa425 100644
--- a/app/models/concerns/referable.rb
+++ b/app/models/concerns/referable.rb
@@ -74,7 +74,7 @@ module Referable
#{Regexp.escape(Gitlab.config.gitlab.url)}
\/#{Project.reference_pattern}
(?:\/\-)?
- \/#{Regexp.escape(route)}
+ \/#{route.is_a?(Regexp) ? route : Regexp.escape(route)}
\/#{pattern}
(?<path>
(\/[a-z0-9_=-]+)*
diff --git a/doc/user/analytics/code_review_analytics.md b/doc/user/analytics/code_review_analytics.md
new file mode 100644
index 00000000000..87c29c265bf
--- /dev/null
+++ b/doc/user/analytics/code_review_analytics.md
@@ -0,0 +1,35 @@
+---
+description: "Learn how long your open merge requests have spent in code review, and what distinguishes the longest-running." # Up to ~200 chars long. They will be displayed in Google Search snippets. It may help to write the page intro first, and then reuse it here.
+---
+
+# Code Review Analytics **(STARTER)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/38062) in GitLab ([Starter](https://about.gitlab.com/pricing/)) 12.7.
+
+Want to learn how long your open merge requests have spent in code review? Or what distinguishes your longest-running code reviews? These are some of the questions Code Review Analytics is designed to answer.
+
+NOTE: **Note:**
+Initially no data will appear. Data will populate as users comment on open merge requests.
+
+## Overview
+
+Code Review Analytics displays a collection of merge requests in a table. These are all the open merge requests that are considered to be in code review. This feature considers code review to begin when a merge request receives its first comment from someone other than the author. The rows of the table are sorted by review time so the longest reviews appear at the top. There are also columns to display the author, approvers, comment count, and line -/+ counts.
+
+This feature is designed for [development team leaders](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#delaney-development-team-lead) and others who want to understand broad code review dynamics, and identify patterns to help explain them. You can use Code Review Analytics to expose your team's unique challenges with code review, and identify improvements that might substantially accelerate your development cycle.
+
+## Use cases
+
+Perhaps your team agrees that code review is moving too slow, or the [Cycle Analytics feature](https://docs.gitlab.com/ee/user/analytics/cycle_analytics.html) shows that "Review" is your team's most time-consuming step. You can use Code Review Analytics to see what is currently moving slowest, and analyze the patterns and trends between them. Lots of comments or commits? Maybe the code is too complex. A particular author is involved? Maybe more training is advisable. Few comments and approvers? Maybe your team is understaffed.
+
+## Permissions
+
+- On [Starter or Bronze tier](https://about.gitlab.com/pricing/) and above.
+- By users with [Reporter access] and above.
+
+## Feature flag
+
+Code Review Analytics is [currently protected by a feature flag](https://gitlab.com/gitlab-org/gitlab/issues/194165) that defaults to "enabled" - meaning the feature is available. If you experience performance problems or otherwise wish to disable the feature, a GitLab administrator can execute a command in a Rails console:
+
+```ruby
+Feature.disable(:code_review_analytics)
+```
diff --git a/doc/user/analytics/index.md b/doc/user/analytics/index.md
index 8e88d8fd7b6..707ba01eb79 100644
--- a/doc/user/analytics/index.md
+++ b/doc/user/analytics/index.md
@@ -15,6 +15,8 @@ Once enabled, click on **Analytics** from the top navigation bar.
From the centralized analytics workspace, the following analytics are available:
+- [Code Review Analytics](code_review_analytics.md), enabled with the `code_review_analytics`
+ [feature flag](../../development/feature_flags/development.html#enabling-a-feature-flag-in-development). **(STARTER)**
- [Cycle Analytics](cycle_analytics.md), enabled with the `cycle_analytics`
[feature flag](../../development/feature_flags/development.html#enabling-a-feature-flag-in-development). **(PREMIUM)**
- [Productivity Analytics](productivity_analytics.md), enabled with the `productivity_analytics`
diff --git a/doc/user/project/operations/error_tracking.md b/doc/user/project/operations/error_tracking.md
index f76c9d9912b..447d294bef8 100644
--- a/doc/user/project/operations/error_tracking.md
+++ b/doc/user/project/operations/error_tracking.md
@@ -53,11 +53,12 @@ From error list, users can navigate to the error details page by clicking the ti
This page has:
- A link to the Sentry issue.
+- A link to the GitLab commit if the Sentry [release id/version](https://docs.sentry.io/workflow/releases/?platform=javascript#configure-sdk) on the Sentry Issue's first release matches a commit SHA in your GitLab hosted project.
- Other details about the issue, including a full stack trace.
-If the error has not been linked to an existing GitLab issue, a 'Create issue' button will be visible:
+By default, a **Create issue** button is displayed. Once you have used it to create an issue, the button is hidden.
-![Error Details without Issue Link](img/error_details_v12_6.png)
+![Error Details without Issue Link](img/error_details_v12_7.png)
If a link does exist, it will be shown in the details and the 'Create issue' button will change to a 'View issue' button:
diff --git a/doc/user/project/operations/img/error_details_v12_7.png b/doc/user/project/operations/img/error_details_v12_7.png
new file mode 100644
index 00000000000..1c7ace35e2a
--- /dev/null
+++ b/doc/user/project/operations/img/error_details_v12_7.png
Binary files differ
diff --git a/lib/banzai/filter/abstract_reference_filter.rb b/lib/banzai/filter/abstract_reference_filter.rb
index 7f986bccc99..5962403d488 100644
--- a/lib/banzai/filter/abstract_reference_filter.rb
+++ b/lib/banzai/filter/abstract_reference_filter.rb
@@ -297,8 +297,8 @@ module Banzai
@references_per[parent_type] ||= begin
refs = Hash.new { |hash, key| hash[key] = Set.new }
regex = [
- object_class.reference_pattern,
- object_class.link_reference_pattern
+ object_class.link_reference_pattern,
+ object_class.reference_pattern
].compact.reduce { |a, b| Regexp.union(a, b) }
nodes.each do |node|
diff --git a/lib/gitlab/pagination/base.rb b/lib/gitlab/pagination/base.rb
index 6402b9c0f76..a8a3397eba2 100644
--- a/lib/gitlab/pagination/base.rb
+++ b/lib/gitlab/pagination/base.rb
@@ -10,31 +10,6 @@ module Gitlab
def finalize(records)
# Optional: Called with the actual set of records
end
-
- private
-
- def per_page
- @per_page ||= params[:per_page]
- end
-
- def base_request_uri
- @base_request_uri ||= URI.parse(request.url).tap do |uri|
- uri.host = Gitlab.config.gitlab.host
- uri.port = Gitlab.config.gitlab.port
- end
- end
-
- def build_page_url(query_params:)
- base_request_uri.tap do |uri|
- uri.query = query_params
- end.to_s
- end
-
- def page_href(next_page_params = {})
- query_params = params.merge(**next_page_params, per_page: per_page).to_query
-
- build_page_url(query_params: query_params)
- end
end
end
end
diff --git a/lib/gitlab/pagination/keyset/pager.rb b/lib/gitlab/pagination/keyset/pager.rb
index 6eaa7f3ba87..6a2ae20f3b8 100644
--- a/lib/gitlab/pagination/keyset/pager.rb
+++ b/lib/gitlab/pagination/keyset/pager.rb
@@ -3,7 +3,7 @@
module Gitlab
module Pagination
module Keyset
- class Pager
+ class Pager < Gitlab::Pagination::Base
attr_reader :request
def initialize(request)
diff --git a/lib/gitlab/pagination/offset_pagination.rb b/lib/gitlab/pagination/offset_pagination.rb
index bf31f252a6b..11a5ef4e518 100644
--- a/lib/gitlab/pagination/offset_pagination.rb
+++ b/lib/gitlab/pagination/offset_pagination.rb
@@ -72,6 +72,29 @@ module Gitlab
def data_without_counts?(paginated_data)
paginated_data.is_a?(Kaminari::PaginatableWithoutCount)
end
+
+ def base_request_uri
+ @base_request_uri ||= URI.parse(request.url).tap do |uri|
+ uri.host = Gitlab.config.gitlab.host
+ uri.port = Gitlab.config.gitlab.port
+ end
+ end
+
+ def build_page_url(query_params:)
+ base_request_uri.tap do |uri|
+ uri.query = query_params
+ end.to_s
+ end
+
+ def page_href(next_page_params = {})
+ query_params = params.merge(**next_page_params, per_page: per_page).to_query
+
+ build_page_url(query_params: query_params)
+ end
+
+ def per_page
+ @per_page ||= params[:per_page]
+ end
end
end
end
diff --git a/spec/frontend/environments/environment_monitoring_spec.js b/spec/frontend/environments/environment_monitoring_spec.js
index 9dea02ff66a..d2129bd7b30 100644
--- a/spec/frontend/environments/environment_monitoring_spec.js
+++ b/spec/frontend/environments/environment_monitoring_spec.js
@@ -9,7 +9,6 @@ describe('Monitoring Component', () => {
const createWrapper = () => {
wrapper = shallowMount(MonitoringComponent, {
- attachToDocument: true,
propsData: {
monitoringUrl,
},
diff --git a/spec/frontend/environments/environment_rollback_spec.js b/spec/frontend/environments/environment_rollback_spec.js
index a165e94016e..fb62a096c3d 100644
--- a/spec/frontend/environments/environment_rollback_spec.js
+++ b/spec/frontend/environments/environment_rollback_spec.js
@@ -13,7 +13,6 @@ describe('Rollback Component', () => {
isLastDeployment: true,
environment: {},
},
- attachToDocument: true,
});
expect(wrapper.element).toHaveSpriteIcon('repeat');
@@ -26,7 +25,6 @@ describe('Rollback Component', () => {
isLastDeployment: false,
environment: {},
},
- attachToDocument: true,
});
expect(wrapper.element).toHaveSpriteIcon('redo');
diff --git a/spec/frontend/environments/environment_stop_spec.js b/spec/frontend/environments/environment_stop_spec.js
index 0b9b3078a09..f971cf56b65 100644
--- a/spec/frontend/environments/environment_stop_spec.js
+++ b/spec/frontend/environments/environment_stop_spec.js
@@ -11,7 +11,6 @@ describe('Stop Component', () => {
const createWrapper = () => {
wrapper = shallowMount(StopComponent, {
- attachToDocument: true,
propsData: {
environment: {},
},
diff --git a/spec/frontend/environments/environment_terminal_button_spec.js b/spec/frontend/environments/environment_terminal_button_spec.js
index c890334c484..007fda2f2cc 100644
--- a/spec/frontend/environments/environment_terminal_button_spec.js
+++ b/spec/frontend/environments/environment_terminal_button_spec.js
@@ -7,7 +7,6 @@ describe('Stop Component', () => {
const mountWithProps = props => {
wrapper = shallowMount(TerminalComponent, {
- attachToDocument: true,
propsData: props,
});
};
diff --git a/spec/frontend/monitoring/components/charts/time_series_spec.js b/spec/frontend/monitoring/components/charts/time_series_spec.js
index 12f83a07d23..d9960b3d18e 100644
--- a/spec/frontend/monitoring/components/charts/time_series_spec.js
+++ b/spec/frontend/monitoring/components/charts/time_series_spec.js
@@ -59,7 +59,6 @@ describe('Time series component', () => {
default: mockWidgets,
},
store,
- attachToDocument: true,
});
});
diff --git a/spec/frontend/monitoring/components/dashboard_spec.js b/spec/frontend/monitoring/components/dashboard_spec.js
index 030b68bcd5a..85408d57dde 100644
--- a/spec/frontend/monitoring/components/dashboard_spec.js
+++ b/spec/frontend/monitoring/components/dashboard_spec.js
@@ -63,7 +63,7 @@ describe('Dashboard', () => {
beforeEach(() => {
mock.onGet(mockApiEndpoint).reply(statusCodes.OK, metricsGroupsAPIResponse);
- createShallowWrapper({}, { attachToDocument: true });
+ createShallowWrapper();
});
afterEach(() => {
@@ -79,7 +79,7 @@ describe('Dashboard', () => {
beforeEach(done => {
mock.onGet(mockApiEndpoint).reply(statusCodes.OK, metricsGroupsAPIResponse);
- createShallowWrapper({}, { attachToDocument: true });
+ createShallowWrapper();
wrapper.vm.$nextTick(done);
});
@@ -99,7 +99,7 @@ describe('Dashboard', () => {
});
it('shows up a loading state', done => {
- createShallowWrapper({ hasMetrics: true }, { attachToDocument: true });
+ createShallowWrapper({ hasMetrics: true });
wrapper.vm
.$nextTick()
@@ -114,7 +114,7 @@ describe('Dashboard', () => {
it('hides the group panels when showPanels is false', done => {
createMountedWrapper(
{ hasMetrics: true, showPanels: false },
- { attachToDocument: true, stubs: ['graph-group', 'panel-type'] },
+ { stubs: ['graph-group', 'panel-type'] },
);
setupComponentStore(wrapper);
@@ -136,10 +136,7 @@ describe('Dashboard', () => {
it('fetches the metrics data with proper time window', done => {
jest.spyOn(store, 'dispatch');
- createMountedWrapper(
- { hasMetrics: true },
- { attachToDocument: true, stubs: ['graph-group', 'panel-type'] },
- );
+ createMountedWrapper({ hasMetrics: true }, { stubs: ['graph-group', 'panel-type'] });
wrapper.vm.$store.commit(
`monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
@@ -161,10 +158,7 @@ describe('Dashboard', () => {
beforeEach(() => {
mock.onGet(mockApiEndpoint).reply(statusCodes.OK, metricsGroupsAPIResponse);
- createMountedWrapper(
- { hasMetrics: true },
- { attachToDocument: true, stubs: ['graph-group', 'panel-type'] },
- );
+ createMountedWrapper({ hasMetrics: true }, { stubs: ['graph-group', 'panel-type'] });
setupComponentStore(wrapper);
});
@@ -216,10 +210,7 @@ describe('Dashboard', () => {
});
it('hides the environments dropdown list when there is no environments', done => {
- createMountedWrapper(
- { hasMetrics: true },
- { attachToDocument: true, stubs: ['graph-group', 'panel-type'] },
- );
+ createMountedWrapper({ hasMetrics: true }, { stubs: ['graph-group', 'panel-type'] });
wrapper.vm.$store.commit(
`monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`,
@@ -244,10 +235,7 @@ describe('Dashboard', () => {
});
it('renders the datetimepicker dropdown', done => {
- createMountedWrapper(
- { hasMetrics: true },
- { attachToDocument: true, stubs: ['graph-group', 'panel-type'] },
- );
+ createMountedWrapper({ hasMetrics: true }, { stubs: ['graph-group', 'panel-type'] });
setupComponentStore(wrapper);
@@ -264,7 +252,7 @@ describe('Dashboard', () => {
beforeEach(done => {
mock.onGet(mockApiEndpoint).reply(200, metricsGroupsAPIResponse);
- createShallowWrapper({ hasMetrics: true }, { attachToDocument: true });
+ createShallowWrapper({ hasMetrics: true });
setupComponentStore(wrapper);
wrapper.vm.$nextTick(done);
@@ -298,7 +286,7 @@ describe('Dashboard', () => {
});
beforeEach(done => {
- createShallowWrapper({ hasMetrics: true }, { attachToDocument: true });
+ createShallowWrapper({ hasMetrics: true });
setupComponentStore(wrapper);
@@ -415,7 +403,7 @@ describe('Dashboard', () => {
beforeEach(done => {
mock.onGet(mockApiEndpoint).reply(statusCodes.OK, metricsGroupsAPIResponse);
- createShallowWrapper({ hasMetrics: true }, { attachToDocument: true });
+ createShallowWrapper({ hasMetrics: true });
wrapper.vm.$store.commit(
`monitoringDashboard/${types.SET_ALL_DASHBOARDS}`,
@@ -452,10 +440,7 @@ describe('Dashboard', () => {
beforeEach(() => {
mock.onGet(mockApiEndpoint).reply(200, metricsGroupsAPIResponse);
- createMountedWrapper(
- { hasMetrics: true },
- { attachToDocument: true, stubs: ['graph-group', 'panel-type'] },
- );
+ createMountedWrapper({ hasMetrics: true }, { stubs: ['graph-group', 'panel-type'] });
wrapper.vm.$store.commit(
`monitoringDashboard/${types.SET_ALL_DASHBOARDS}`,
@@ -487,7 +472,7 @@ describe('Dashboard', () => {
showTimeWindowDropdown: false,
externalDashboardUrl: '/mockUrl',
},
- { attachToDocument: true, stubs: ['graph-group', 'panel-type'] },
+ { stubs: ['graph-group', 'panel-type'] },
);
});
@@ -517,7 +502,7 @@ describe('Dashboard', () => {
beforeEach(done => {
mock.onGet(mockApiEndpoint).reply(200, metricsGroupsAPIResponse);
- createShallowWrapper({ hasMetrics: true, currentDashboard }, { attachToDocument: true });
+ createShallowWrapper({ hasMetrics: true, currentDashboard });
setTimeout(done);
});
diff --git a/spec/frontend/monitoring/components/dashboard_time_url_spec.js b/spec/frontend/monitoring/components/dashboard_time_url_spec.js
index 07b39c959be..2da377eb79f 100644
--- a/spec/frontend/monitoring/components/dashboard_time_url_spec.js
+++ b/spec/frontend/monitoring/components/dashboard_time_url_spec.js
@@ -38,10 +38,7 @@ describe('dashboard invalid url parameters', () => {
});
it('shows an error message if invalid url parameters are passed', done => {
- createMountedWrapper(
- { hasMetrics: true },
- { attachToDocument: true, stubs: ['graph-group', 'panel-type'] },
- );
+ createMountedWrapper({ hasMetrics: true }, { stubs: ['graph-group', 'panel-type'] });
wrapper.vm
.$nextTick()
diff --git a/spec/frontend/monitoring/components/dashboard_time_window_spec.js b/spec/frontend/monitoring/components/dashboard_time_window_spec.js
index c297b47eee0..4acc2d75b73 100644
--- a/spec/frontend/monitoring/components/dashboard_time_window_spec.js
+++ b/spec/frontend/monitoring/components/dashboard_time_window_spec.js
@@ -45,10 +45,7 @@ describe('dashboard time window', () => {
it('shows an error message if invalid url parameters are passed', done => {
mock.onGet(mockApiEndpoint).reply(statusCodes.OK, metricsGroupsAPIResponse);
- createComponentWrapperMounted(
- { hasMetrics: true },
- { attachToDocument: true, stubs: ['graph-group', 'panel-type'] },
- );
+ createComponentWrapperMounted({ hasMetrics: true }, { stubs: ['graph-group', 'panel-type'] });
setupComponentStore(wrapper);
diff --git a/spec/frontend/monitoring/panel_type_spec.js b/spec/frontend/monitoring/panel_type_spec.js
index 04642d071aa..e51b69ef14d 100644
--- a/spec/frontend/monitoring/panel_type_spec.js
+++ b/spec/frontend/monitoring/panel_type_spec.js
@@ -26,7 +26,6 @@ describe('Panel Type component', () => {
...props,
},
store,
- attachToDocument: true,
});
beforeEach(() => {
@@ -151,7 +150,6 @@ describe('Panel Type component', () => {
graphData: graphDataPrometheusQueryRange,
},
store,
- attachToDocument: true,
});
panelType.vm.$nextTick(done);
});
diff --git a/spec/migrations/20190924152703_migrate_issue_trackers_data_spec.rb b/spec/migrations/20190924152703_migrate_issue_trackers_data_spec.rb
index 0453ac87436..53c176fc46f 100644
--- a/spec/migrations/20190924152703_migrate_issue_trackers_data_spec.rb
+++ b/spec/migrations/20190924152703_migrate_issue_trackers_data_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20190924152703_migrate_issue_trackers_data.rb')
-describe MigrateIssueTrackersData, :migration do
+describe MigrateIssueTrackersData, :migration, :sidekiq do
let(:services) { table(:services) }
let(:migration_class) { Gitlab::BackgroundMigration::MigrateIssueTrackersSensitiveData }
let(:migration_name) { migration_class.to_s.demodulize }