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:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-08-17 12:10:08 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-08-17 12:10:08 +0300
commit325318e2ddfcaedf0527053dd3c9bd62db547089 (patch)
tree2525b4135802427a95233219d9d339ceadb51280
parentc64b892786865a3b87701450c6ca62fcab0fa044 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/alert_management/components/alert_details.vue6
-rw-r--r--app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql1
-rw-r--r--app/assets/javascripts/pipelines/pipeline_details_bundle.js4
-rw-r--r--app/assets/javascripts/reports/components/grouped_test_reports_app.vue3
-rw-r--r--app/controllers/projects/merge_requests_controller.rb1
-rw-r--r--app/controllers/projects/pipelines_controller.rb3
-rw-r--r--app/models/concerns/has_wiki.rb2
-rw-r--r--app/models/group.rb4
-rw-r--r--app/models/project.rb10
-rw-r--r--app/models/wiki.rb1
-rw-r--r--app/services/alert_management/alerts/update_service.rb6
-rw-r--r--app/services/event_create_service.rb6
-rw-r--r--app/services/issues/update_service.rb2
-rw-r--r--app/services/merge_requests/update_service.rb2
-rw-r--r--app/services/resource_access_tokens/create_service.rb2
-rw-r--r--app/services/todo_service.rb14
-rw-r--r--app/views/projects/pipelines/_with_tabs.html.haml10
-rw-r--r--app/views/projects/settings/access_tokens/index.html.haml5
-rw-r--r--changelogs/unreleased/216478-remove-test-report-feature-flag.yml5
-rw-r--r--changelogs/unreleased/missing-a-blank.yml5
-rw-r--r--changelogs/unreleased/sy-surface-runbook-in-alert.yml5
-rw-r--r--config/initializers/1_settings.rb3
-rw-r--r--db/migrate/20200805071842_add_index_on_end_date_and_namespace_id_to_gitlab_subscriptions.rb17
-rw-r--r--db/schema_migrations/202008050718421
-rw-r--r--db/structure.sql2
-rw-r--r--doc/administration/feature_flags.md4
-rw-r--r--doc/api/graphql/reference/gitlab_schema.graphql63
-rw-r--r--doc/api/graphql/reference/gitlab_schema.json125
-rw-r--r--doc/ci/junit_test_reports.md21
-rw-r--r--doc/user/project/settings/project_access_tokens.md39
-rw-r--r--lib/api/ci/pipelines.rb4
-rw-r--r--lib/gitlab/usage_data.rb6
-rw-r--r--lib/gitlab/usage_data_counters/track_unique_actions.rb4
-rw-r--r--locale/gitlab.pot6
-rw-r--r--spec/controllers/projects/pipelines_controller_spec.rb133
-rw-r--r--spec/frontend/alert_management/components/alert_details_spec.js2
-rw-r--r--spec/frontend/fixtures/test_report.rb1
-rw-r--r--spec/frontend/reports/components/grouped_test_reports_app_spec.js29
-rw-r--r--spec/lib/banzai/filter/gollum_tags_filter_spec.rb3
-rw-r--r--spec/lib/banzai/filter/wiki_link_filter_spec.rb3
-rw-r--r--spec/lib/banzai/pipeline/wiki_pipeline_spec.rb2
-rw-r--r--spec/lib/gitlab/usage_data_counters/track_unique_actions_spec.rb50
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb16
-rw-r--r--spec/models/group_spec.rb44
-rw-r--r--spec/models/project_spec.rb24
-rw-r--r--spec/models/wiki_spec.rb14
-rw-r--r--spec/requests/api/ci/pipelines_spec.rb53
-rw-r--r--spec/services/alert_management/alerts/update_service_spec.rb3
-rw-r--r--spec/services/event_create_service_spec.rb10
-rw-r--r--spec/services/resource_access_tokens/create_service_spec.rb11
-rw-r--r--spec/services/todo_service_spec.rb30
51 files changed, 523 insertions, 297 deletions
diff --git a/app/assets/javascripts/alert_management/components/alert_details.vue b/app/assets/javascripts/alert_management/components/alert_details.vue
index 8c3ec527ef6..49eff61e12f 100644
--- a/app/assets/javascripts/alert_management/components/alert_details.vue
+++ b/app/assets/javascripts/alert_management/components/alert_details.vue
@@ -324,6 +324,12 @@ export default {
</div>
<div class="gl-pl-2" data-testid="service">{{ alert.service }}</div>
</div>
+ <div v-if="alert.runbook" class="gl-my-5 gl-display-flex">
+ <div class="bold gl-w-13 gl-text-right gl-pr-3">
+ {{ s__('AlertManagement|Runbook') }}:
+ </div>
+ <div class="gl-pl-2" data-testid="runbook">{{ alert.runbook }}</div>
+ </div>
<template>
<div v-if="alert.notes.nodes" class="issuable-discussion py-5">
<ul class="notes main-notes-list timeline">
diff --git a/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql b/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql
index 92eb828bdf8..0712ff12c23 100644
--- a/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql
+++ b/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql
@@ -11,6 +11,7 @@ fragment AlertDetailItem on AlertManagementAlert {
updatedAt
endedAt
details
+ runbook
todos {
nodes {
id
diff --git a/app/assets/javascripts/pipelines/pipeline_details_bundle.js b/app/assets/javascripts/pipelines/pipeline_details_bundle.js
index 6e425b82a82..127d24c5473 100644
--- a/app/assets/javascripts/pipelines/pipeline_details_bundle.js
+++ b/app/assets/javascripts/pipelines/pipeline_details_bundle.js
@@ -93,10 +93,6 @@ const createPipelineHeaderApp = mediator => {
};
const createTestDetails = () => {
- if (!window.gon?.features?.junitPipelineView) {
- return;
- }
-
const el = document.querySelector('#js-pipeline-tests-detail');
const { summaryEndpoint, suiteEndpoint } = el?.dataset || {};
diff --git a/app/assets/javascripts/reports/components/grouped_test_reports_app.vue b/app/assets/javascripts/reports/components/grouped_test_reports_app.vue
index b8a8cb940e7..31ac4510add 100644
--- a/app/assets/javascripts/reports/components/grouped_test_reports_app.vue
+++ b/app/assets/javascripts/reports/components/grouped_test_reports_app.vue
@@ -56,7 +56,7 @@ export default {
return `${this.pipelinePath}/test_report`;
},
showViewFullReport() {
- return Boolean(this.glFeatures.junitPipelineView) && this.pipelinePath.length;
+ return this.pipelinePath.length;
},
},
created() {
@@ -116,6 +116,7 @@ export default {
<template v-if="showViewFullReport" #actionButtons>
<gl-button
:href="testTabURL"
+ target="_blank"
icon="external-link"
data-testid="group-test-reports-full-link"
class="gl-mr-3"
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 9b246979860..b217b366ee5 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -43,7 +43,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
before_action do
push_frontend_feature_flag(:vue_issuable_sidebar, @project.group)
- push_frontend_feature_flag(:junit_pipeline_view, @project.group)
end
around_action :allow_gitaly_ref_name_caching, only: [:index, :show, :discussions]
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index 55dc03479b5..bfe23eb1035 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -12,7 +12,6 @@ class Projects::PipelinesController < Projects::ApplicationController
before_action :authorize_create_pipeline!, only: [:new, :create]
before_action :authorize_update_pipeline!, only: [:retry, :cancel]
before_action do
- push_frontend_feature_flag(:junit_pipeline_view, project)
push_frontend_feature_flag(:filter_pipelines_search, project, default_enabled: true)
push_frontend_feature_flag(:dag_pipeline_tab, project, default_enabled: true)
push_frontend_feature_flag(:pipelines_security_report_summary, project)
@@ -177,8 +176,6 @@ class Projects::PipelinesController < Projects::ApplicationController
end
def test_report
- return unless Feature.enabled?(:junit_pipeline_view, project)
-
respond_to do |format|
format.html do
render 'show'
diff --git a/app/models/concerns/has_wiki.rb b/app/models/concerns/has_wiki.rb
index 4dd72216e77..3e7cb940a62 100644
--- a/app/models/concerns/has_wiki.rb
+++ b/app/models/concerns/has_wiki.rb
@@ -17,7 +17,7 @@ module HasWiki
def wiki
strong_memoize(:wiki) do
- Wiki.for_container(self, self.owner)
+ Wiki.for_container(self, self.default_owner)
end
end
diff --git a/app/models/group.rb b/app/models/group.rb
index 440b2c6362b..f8cbaa2495c 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -563,6 +563,10 @@ class Group < Namespace
all_projects.update_all(shared_runners_enabled: false)
end
+ def default_owner
+ owners.first || parent&.default_owner || owner
+ end
+
private
def update_two_factor_requirement
diff --git a/app/models/project.rb b/app/models/project.rb
index 5e1822f1a34..e1b6a9c41dd 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1395,6 +1395,16 @@ class Project < ApplicationRecord
group || namespace.try(:owner)
end
+ def default_owner
+ obj = owner
+
+ if obj.respond_to?(:default_owner)
+ obj.default_owner
+ else
+ obj
+ end
+ end
+
def to_ability_name
model_name.singular
end
diff --git a/app/models/wiki.rb b/app/models/wiki.rb
index 4c497cc304c..30273d646cf 100644
--- a/app/models/wiki.rb
+++ b/app/models/wiki.rb
@@ -35,6 +35,7 @@ class Wiki
def initialize(container, user = nil)
@container = container
@user = user
+ raise ArgumentError, "user must be a User, got #{user.class}" if user && !user.is_a?(User)
end
def path
diff --git a/app/services/alert_management/alerts/update_service.rb b/app/services/alert_management/alerts/update_service.rb
index 0b7216cd9f8..18d615aa7e7 100644
--- a/app/services/alert_management/alerts/update_service.rb
+++ b/app/services/alert_management/alerts/update_service.rb
@@ -96,12 +96,12 @@ module AlertManagement
end
def handle_assignement(old_assignees)
- assign_todo
+ assign_todo(old_assignees)
add_assignee_system_note(old_assignees)
end
- def assign_todo
- todo_service.assign_alert(alert, current_user)
+ def assign_todo(old_assignees)
+ todo_service.reassigned_assignable(alert, current_user, old_assignees)
end
def add_assignee_system_note(old_assignees)
diff --git a/app/services/event_create_service.rb b/app/services/event_create_service.rb
index abbb68aaf94..3921dbefd06 100644
--- a/app/services/event_create_service.rb
+++ b/app/services/event_create_service.rb
@@ -109,7 +109,7 @@ class EventCreateService
def wiki_event(wiki_page_meta, author, action, fingerprint)
raise IllegalActionError, action unless Event::WIKI_ACTIONS.include?(action)
- Gitlab::UsageDataCounters::TrackUniqueActions.track_action(event_action: action, event_target: wiki_page_meta.class, author_id: author.id)
+ Gitlab::UsageDataCounters::TrackUniqueActions.track_event(event_action: action, event_target: wiki_page_meta.class, author_id: author.id)
duplicate = Event.for_wiki_meta(wiki_page_meta).for_fingerprint(fingerprint).first
return duplicate if duplicate.present?
@@ -154,7 +154,7 @@ class EventCreateService
result = Event.insert_all(attribute_sets, returning: %w[id])
tuples.each do |record, status, _|
- Gitlab::UsageDataCounters::TrackUniqueActions.track_action(event_action: status, event_target: record.class, author_id: current_user.id)
+ Gitlab::UsageDataCounters::TrackUniqueActions.track_event(event_action: status, event_target: record.class, author_id: current_user.id)
end
result
@@ -172,7 +172,7 @@ class EventCreateService
new_event
end
- Gitlab::UsageDataCounters::TrackUniqueActions.track_action(event_action: :pushed, event_target: Project, author_id: current_user.id)
+ Gitlab::UsageDataCounters::TrackUniqueActions.track_event(event_action: :pushed, event_target: Project, author_id: current_user.id)
Users::LastPushEventService.new(current_user)
.cache_last_push_event(event)
diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb
index 8835af3659d..ac7baba3b7c 100644
--- a/app/services/issues/update_service.rb
+++ b/app/services/issues/update_service.rb
@@ -43,7 +43,7 @@ module Issues
if issue.assignees != old_assignees
create_assignee_note(issue, old_assignees)
notification_service.async.reassigned_issue(issue, current_user, old_assignees)
- todo_service.reassigned_issuable(issue, current_user, old_assignees)
+ todo_service.reassigned_assignable(issue, current_user, old_assignees)
end
if issue.previous_changes.include?('confidential')
diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb
index 29e0c22b155..cf02158b629 100644
--- a/app/services/merge_requests/update_service.rb
+++ b/app/services/merge_requests/update_service.rb
@@ -105,7 +105,7 @@ module MergeRequests
def handle_assignees_change(merge_request, old_assignees)
create_assignee_note(merge_request, old_assignees)
notification_service.async.reassigned_merge_request(merge_request, current_user, old_assignees)
- todo_service.reassigned_issuable(merge_request, current_user, old_assignees)
+ todo_service.reassigned_assignable(merge_request, current_user, old_assignees)
end
def create_branch_change_note(issuable, branch_type, old_branch, new_branch)
diff --git a/app/services/resource_access_tokens/create_service.rb b/app/services/resource_access_tokens/create_service.rb
index 3aa0e5650ee..c253154c1b7 100644
--- a/app/services/resource_access_tokens/create_service.rb
+++ b/app/services/resource_access_tokens/create_service.rb
@@ -32,6 +32,8 @@ module ResourceAccessTokens
attr_reader :resource_type, :resource
def feature_enabled?
+ return false if ::Gitlab.com?
+
::Feature.enabled?(:resource_access_token, resource, default_enabled: true)
end
diff --git a/app/services/todo_service.rb b/app/services/todo_service.rb
index ec15bdde8d7..a3db2ae7947 100644
--- a/app/services/todo_service.rb
+++ b/app/services/todo_service.rb
@@ -49,11 +49,11 @@ class TodoService
todo_users.each(&:update_todos_count_cache)
end
- # When we reassign an issuable we should:
+ # When we reassign an assignable object (issuable, alert) we should:
#
- # * create a pending todo for new assignee if issuable is assigned
+ # * create a pending todo for new assignee if object is assigned
#
- def reassigned_issuable(issuable, current_user, old_assignees = [])
+ def reassigned_assignable(issuable, current_user, old_assignees = [])
create_assignment_todo(issuable, current_user, old_assignees)
end
@@ -154,14 +154,6 @@ class TodoService
resolve_todos_for_target(awardable, current_user)
end
- # When assigning an alert we should:
- #
- # * create a pending todo for new assignee if alert is assigned
- #
- def assign_alert(alert, current_user)
- create_assignment_todo(alert, current_user, [])
- end
-
# When user marks a target as todo
def mark_todo(target, current_user)
attributes = attributes_for_todo(target.project, target, current_user, Todo::MARKED)
diff --git a/app/views/projects/pipelines/_with_tabs.html.haml b/app/views/projects/pipelines/_with_tabs.html.haml
index 5530033ca1b..9199fdb99d6 100644
--- a/app/views/projects/pipelines/_with_tabs.html.haml
+++ b/app/views/projects/pipelines/_with_tabs.html.haml
@@ -1,5 +1,4 @@
- return if pipeline_has_errors
-- test_reports_enabled = Feature.enabled?(:junit_pipeline_view, @project)
- dag_pipeline_tab_enabled = Feature.enabled?(:dag_pipeline_tab, @project, default_enabled: true)
.tabs-holder
@@ -20,11 +19,10 @@
= link_to failures_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-failures', action: 'failures', toggle: 'tab' }, class: 'failures-tab' do
= _('Failed Jobs')
%span.badge.badge-pill.js-failures-counter= @pipeline.failed_builds.count
- - if test_reports_enabled
- %li.js-tests-tab-link
- = link_to test_report_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-tests', action: 'test_report', toggle: 'tab' }, class: 'test-tab' do
- = s_('TestReports|Tests')
- %span.badge.badge-pill.js-test-report-badge-counter= @pipeline.test_report_summary.total[:count]
+ %li.js-tests-tab-link
+ = link_to test_report_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-tests', action: 'test_report', toggle: 'tab' }, class: 'test-tab' do
+ = s_('TestReports|Tests')
+ %span.badge.badge-pill.js-test-report-badge-counter= @pipeline.test_report_summary.total[:count]
= render_if_exists "projects/pipelines/tabs_holder", pipeline: @pipeline, project: @project
.tab-content
diff --git a/app/views/projects/settings/access_tokens/index.html.haml b/app/views/projects/settings/access_tokens/index.html.haml
index 4992288a8c8..100eb5991dc 100644
--- a/app/views/projects/settings/access_tokens/index.html.haml
+++ b/app/views/projects/settings/access_tokens/index.html.haml
@@ -10,8 +10,9 @@
= page_title
%p
= _('You can generate an access token scoped to this project for each application to use the GitLab API.')
- %p
- = _('You can also use project access tokens to authenticate against Git over HTTP.')
+ -# Commented out until https://gitlab.com/gitlab-org/gitlab/-/issues/219551 is fixed
+ -# %p
+ -# = _('You can also use project access tokens to authenticate against Git over HTTP.')
.col-lg-8
- if @new_project_access_token
diff --git a/changelogs/unreleased/216478-remove-test-report-feature-flag.yml b/changelogs/unreleased/216478-remove-test-report-feature-flag.yml
new file mode 100644
index 00000000000..e8f1259593e
--- /dev/null
+++ b/changelogs/unreleased/216478-remove-test-report-feature-flag.yml
@@ -0,0 +1,5 @@
+---
+title: JUnit test report on pipeline detail page
+merge_request: 39260
+author:
+type: added
diff --git a/changelogs/unreleased/missing-a-blank.yml b/changelogs/unreleased/missing-a-blank.yml
new file mode 100644
index 00000000000..c04f439dd11
--- /dev/null
+++ b/changelogs/unreleased/missing-a-blank.yml
@@ -0,0 +1,5 @@
+---
+title: Make View full report button open link in new tab
+merge_request: 39501
+author:
+type: changed
diff --git a/changelogs/unreleased/sy-surface-runbook-in-alert.yml b/changelogs/unreleased/sy-surface-runbook-in-alert.yml
new file mode 100644
index 00000000000..a98b21f7160
--- /dev/null
+++ b/changelogs/unreleased/sy-surface-runbook-in-alert.yml
@@ -0,0 +1,5 @@
+---
+title: Show runbook for alert in detail view
+merge_request: 39477
+author:
+type: added
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index e8e2f7edd07..9b08f1e5be4 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -575,6 +575,9 @@ Gitlab.ee do
Settings.cron_jobs['elastic_cluster_reindexing_cron_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['elastic_cluster_reindexing_cron_worker']['cron'] ||= '*/10 * * * *'
Settings.cron_jobs['elastic_cluster_reindexing_cron_worker']['job_class'] ||= 'ElasticClusterReindexingCronWorker'
+ Settings.cron_jobs['elastic_remove_expired_namespace_subscriptions_from_index_cron_worker'] ||= Settingslogic.new({})
+ Settings.cron_jobs['elastic_remove_expired_namespace_subscriptions_from_index_cron_worker']['cron'] ||= '10 3 * * *'
+ Settings.cron_jobs['elastic_remove_expired_namespace_subscriptions_from_index_cron_worker']['job_class'] ||= 'ElasticRemoveExpiredNamespaceSubscriptionsFromIndexCronWorker'
Settings.cron_jobs['sync_seat_link_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['sync_seat_link_worker']['cron'] ||= "#{rand(60)} 0 * * *"
Settings.cron_jobs['sync_seat_link_worker']['job_class'] = 'SyncSeatLinkWorker'
diff --git a/db/migrate/20200805071842_add_index_on_end_date_and_namespace_id_to_gitlab_subscriptions.rb b/db/migrate/20200805071842_add_index_on_end_date_and_namespace_id_to_gitlab_subscriptions.rb
new file mode 100644
index 00000000000..17b92b6b8a8
--- /dev/null
+++ b/db/migrate/20200805071842_add_index_on_end_date_and_namespace_id_to_gitlab_subscriptions.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddIndexOnEndDateAndNamespaceIdToGitlabSubscriptions < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :gitlab_subscriptions, [:end_date, :namespace_id]
+ end
+
+ def down
+ remove_concurrent_index :gitlab_subscriptions, [:end_date, :namespace_id]
+ end
+end
diff --git a/db/schema_migrations/20200805071842 b/db/schema_migrations/20200805071842
new file mode 100644
index 00000000000..75810bed0d1
--- /dev/null
+++ b/db/schema_migrations/20200805071842
@@ -0,0 +1 @@
+432ef9d45c8242ab8db954ceeb6a68a75ef46181dd868a30d68fef0ed6058caf \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 853c686ccd5..25af1ab11d6 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -19710,6 +19710,8 @@ CREATE INDEX index_geo_upload_deleted_events_on_upload_id ON public.geo_upload_d
CREATE INDEX index_gitlab_subscription_histories_on_gitlab_subscription_id ON public.gitlab_subscription_histories USING btree (gitlab_subscription_id);
+CREATE INDEX index_gitlab_subscriptions_on_end_date_and_namespace_id ON public.gitlab_subscriptions USING btree (end_date, namespace_id);
+
CREATE INDEX index_gitlab_subscriptions_on_hosted_plan_id ON public.gitlab_subscriptions USING btree (hosted_plan_id);
CREATE UNIQUE INDEX index_gitlab_subscriptions_on_namespace_id ON public.gitlab_subscriptions USING btree (namespace_id);
diff --git a/doc/administration/feature_flags.md b/doc/administration/feature_flags.md
index 678ab6c5d7b..7cc7692975a 100644
--- a/doc/administration/feature_flags.md
+++ b/doc/administration/feature_flags.md
@@ -103,10 +103,10 @@ Some feature flags can be enabled or disabled on a per project basis:
Feature.enable(:<feature flag>, Project.find(<project id>))
```
-For example, to enable the [`:junit_pipeline_view`](../ci/junit_test_reports.md#enabling-the-junit-test-reports-feature-core-only) feature flag for project `1234`:
+For example, to enable the [`:product_analytics`](../operations/product_analytics.md#enable-or-disable-product-analytics) feature flag for project `1234`:
```ruby
-Feature.enable(:junit_pipeline_view, Project.find(1234))
+Feature.enable(:product_analytics, Project.find(1234))
```
`Feature.enable` and `Feature.disable` always return `nil`, this is not an indication that the command failed:
diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index 254c2bec304..9263dce0898 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -1135,42 +1135,47 @@ type BoardEdge {
input BoardEpicIssueInput {
"""
- Username of a user assigned to issues
+ Filter by assignee username
"""
assigneeUsername: [String]
"""
- Username of the issues author
+ Filter by author username
"""
authorUsername: String
"""
- Epic ID applied to issues
+ Filter by epic ID
"""
epicId: String
"""
- Label applied to issues
+ Filter by label name
"""
labelName: [String]
"""
- Milestone applied to issues
+ Filter by milestone title
"""
milestoneTitle: String
"""
- Reaction emoji applied to issues
+ Filter by reaction emoji
"""
myReactionEmoji: String
"""
- Release applied to issues
+ List of negated params. Warning: this argument is experimental and a subject to change in future
+ """
+ not: NegatedBoardEpicIssueInput
+
+ """
+ Filter by release tag
"""
releaseTag: String
"""
- Weight applied to issues
+ Filter by weight
"""
weight: String
}
@@ -9795,6 +9800,48 @@ type NamespaceIncreaseStorageTemporarilyPayload {
namespace: Namespace
}
+input NegatedBoardEpicIssueInput {
+ """
+ Filter by assignee username
+ """
+ assigneeUsername: [String]
+
+ """
+ Filter by author username
+ """
+ authorUsername: String
+
+ """
+ Filter by epic ID
+ """
+ epicId: String
+
+ """
+ Filter by label name
+ """
+ labelName: [String]
+
+ """
+ Filter by milestone title
+ """
+ milestoneTitle: String
+
+ """
+ Filter by reaction emoji
+ """
+ myReactionEmoji: String
+
+ """
+ Filter by release tag
+ """
+ releaseTag: String
+
+ """
+ Filter by weight
+ """
+ weight: String
+}
+
type Note implements ResolvableInterface {
"""
User who wrote this note
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index 262adffc4b5..1d791644909 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -3049,7 +3049,7 @@
"inputFields": [
{
"name": "labelName",
- "description": "Label applied to issues",
+ "description": "Filter by label name",
"type": {
"kind": "LIST",
"name": null,
@@ -3063,7 +3063,7 @@
},
{
"name": "milestoneTitle",
- "description": "Milestone applied to issues",
+ "description": "Filter by milestone title",
"type": {
"kind": "SCALAR",
"name": "String",
@@ -3073,7 +3073,7 @@
},
{
"name": "assigneeUsername",
- "description": "Username of a user assigned to issues",
+ "description": "Filter by assignee username",
"type": {
"kind": "LIST",
"name": null,
@@ -3087,7 +3087,7 @@
},
{
"name": "authorUsername",
- "description": "Username of the issues author",
+ "description": "Filter by author username",
"type": {
"kind": "SCALAR",
"name": "String",
@@ -3097,7 +3097,7 @@
},
{
"name": "releaseTag",
- "description": "Release applied to issues",
+ "description": "Filter by release tag",
"type": {
"kind": "SCALAR",
"name": "String",
@@ -3107,7 +3107,7 @@
},
{
"name": "epicId",
- "description": "Epic ID applied to issues",
+ "description": "Filter by epic ID",
"type": {
"kind": "SCALAR",
"name": "String",
@@ -3117,7 +3117,7 @@
},
{
"name": "myReactionEmoji",
- "description": "Reaction emoji applied to issues",
+ "description": "Filter by reaction emoji",
"type": {
"kind": "SCALAR",
"name": "String",
@@ -3127,13 +3127,23 @@
},
{
"name": "weight",
- "description": "Weight applied to issues",
+ "description": "Filter by weight",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
+ },
+ {
+ "name": "not",
+ "description": "List of negated params. Warning: this argument is experimental and a subject to change in future",
+ "type": {
+ "kind": "INPUT_OBJECT",
+ "name": "NegatedBoardEpicIssueInput",
+ "ofType": null
+ },
+ "defaultValue": null
}
],
"interfaces": null,
@@ -29246,6 +29256,105 @@
"possibleTypes": null
},
{
+ "kind": "INPUT_OBJECT",
+ "name": "NegatedBoardEpicIssueInput",
+ "description": null,
+ "fields": null,
+ "inputFields": [
+ {
+ "name": "labelName",
+ "description": "Filter by label name",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "milestoneTitle",
+ "description": "Filter by milestone title",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "assigneeUsername",
+ "description": "Filter by assignee username",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "authorUsername",
+ "description": "Filter by author username",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "releaseTag",
+ "description": "Filter by release tag",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "epicId",
+ "description": "Filter by epic ID",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "myReactionEmoji",
+ "description": "Filter by reaction emoji",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ },
+ {
+ "name": "weight",
+ "description": "Filter by weight",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null
+ }
+ ],
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
"kind": "OBJECT",
"name": "Note",
"description": null,
diff --git a/doc/ci/junit_test_reports.md b/doc/ci/junit_test_reports.md
index 898c3526963..ca2d8dcc373 100644
--- a/doc/ci/junit_test_reports.md
+++ b/doc/ci/junit_test_reports.md
@@ -239,9 +239,8 @@ Test:
## Viewing JUnit test reports on GitLab
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/24792) in GitLab 12.5.
-> - It's deployed behind a feature flag, disabled by default.
-> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enabling-the-junit-test-reports-feature-core-only). **(CORE ONLY)**
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/24792) in GitLab 12.5 behind a feature flag (`junit_pipeline_view`), disabled by default.
+> - The feature flag was removed and the feature was [made generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/216478) in GitLab 13.3.
If JUnit XML files are generated and uploaded as part of a pipeline, these reports
can be viewed inside the pipelines details page. The **Tests** tab on this page will
@@ -254,22 +253,6 @@ details, including the cases that make up the suite.
You can also retrieve the reports via the [GitLab API](../api/pipelines.md#get-a-pipelines-test-report).
-### Enabling the JUnit test reports feature **(CORE ONLY)**
-
-This feature comes with the `:junit_pipeline_view` feature flag disabled by default. This
-feature is disabled due to some performance issues with very large data sets.
-When [the performance is improved](https://gitlab.com/groups/gitlab-org/-/epics/2854), the feature will be enabled by default.
-
-To enable this feature, ask a GitLab administrator with [Rails console access](../administration/feature_flags.md#how-to-enable-and-disable-features-behind-flags) to run the
-following command:
-
-```ruby
-Feature.enable(:junit_pipeline_view)
-
-# Enable the feature for a specific project, GitLab 13.0 and above only.
-Feature.enable(:junit_pipeline_view, Project.find(<your-project-id-here>))
-```
-
## Viewing JUnit screenshots on GitLab
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/202114) in GitLab 13.0.
diff --git a/doc/user/project/settings/project_access_tokens.md b/doc/user/project/settings/project_access_tokens.md
index 37360a5f105..cbc4895f014 100644
--- a/doc/user/project/settings/project_access_tokens.md
+++ b/doc/user/project/settings/project_access_tokens.md
@@ -5,20 +5,20 @@ info: "To determine the technical writer assigned to the Stage/Group associated
type: reference, howto
---
-# Project access tokens (Alpha) **(CORE ONLY)**
-
-CAUTION: **Warning:**
-This is an [Alpha](https://about.gitlab.com/handbook/product/#alpha) feature, and it is subject to change at any time without
-prior notice.
+# Project access tokens **(CORE ONLY)**
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2587) in GitLab 13.0.
-> - It's deployed behind a feature flag, disabled by default.
+> - It was [deployed](https://gitlab.com/groups/gitlab-org/-/epics/2587) behind a feature flag, disabled by default.
+> - [Became enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/218722) in GitLab 13.3.
> - It's disabled on GitLab.com.
-> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-project-access-tokens).
+> - It can be enabled or disabled by project.
+> - It's recommended for production use.
+> - For GitLab self-managed instances, GitLab administrators can [disable it](#enable-or-disable-project-access-tokens).
Project access tokens are scoped to a project and can be used to authenticate with the [GitLab API](../../../api/README.md#personalproject-access-tokens).
-You can also use project access tokens with Git to authenticate over HTTP or SSH.
+<!-- Commented out until https://gitlab.com/gitlab-org/gitlab/-/issues/219551 is fixed -->
+<!-- You can also use project access tokens with Git to authenticate over HTTP or SSH. -->
Project access tokens expire on the date you define, at midnight UTC.
@@ -78,19 +78,30 @@ the following table.
### Enable or disable project access tokens
-Project access tokens is an [Alpha](https://about.gitlab.com/handbook/product/#alpha) feature and is not recommended for production use.
-It is deployed behind a feature flag that is **disabled by default**.
+Project access tokens are deployed behind a feature flag that is **enabled by default**.
[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
-can enable it for your instance.
+can disable it for your instance, globally or by project.
+
+To disable it globally:
+
+```ruby
+Feature.disable(:resource_access_token)
+```
-To enable it:
+To disable it for a specific project:
+
+```ruby
+Feature.disable(:resource_access_token, project)
+```
+
+To enable it globally:
```ruby
Feature.enable(:resource_access_token)
```
-To disable it:
+To enable it for a specific project:
```ruby
-Feature.disable(:resource_access_token)
+Feature.enable(:resource_access_token, project)
```
diff --git a/lib/api/ci/pipelines.rb b/lib/api/ci/pipelines.rb
index bbbf3b683c5..a010e0dd761 100644
--- a/lib/api/ci/pipelines.rb
+++ b/lib/api/ci/pipelines.rb
@@ -110,15 +110,13 @@ module API
end
desc 'Gets the test report for a given pipeline' do
- detail 'This feature was introduced in GitLab 13.0. Disabled by default behind feature flag `junit_pipeline_view`'
+ detail 'This feature was introduced in GitLab 13.0.'
success TestReportEntity
end
params do
requires :pipeline_id, type: Integer, desc: 'The pipeline ID'
end
get ':id/pipelines/:pipeline_id/test_report' do
- not_found! unless Feature.enabled?(:junit_pipeline_view, user_project)
-
authorize! :read_build, pipeline
present pipeline.test_reports, with: TestReportEntity, details: true
diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb
index ccfb7b3870f..db2aff9b25a 100644
--- a/lib/gitlab/usage_data.rb
+++ b/lib/gitlab/usage_data.rb
@@ -607,7 +607,7 @@ module Gitlab
counter = Gitlab::UsageDataCounters::TrackUniqueActions
project_count = redis_usage_data do
- counter.count_unique_events(
+ counter.count_unique(
event_action: Gitlab::UsageDataCounters::TrackUniqueActions::PUSH_ACTION,
date_from: time_period[:created_at].first,
date_to: time_period[:created_at].last
@@ -615,7 +615,7 @@ module Gitlab
end
design_count = redis_usage_data do
- counter.count_unique_events(
+ counter.count_unique(
event_action: Gitlab::UsageDataCounters::TrackUniqueActions::DESIGN_ACTION,
date_from: time_period[:created_at].first,
date_to: time_period[:created_at].last
@@ -623,7 +623,7 @@ module Gitlab
end
wiki_count = redis_usage_data do
- counter.count_unique_events(
+ counter.count_unique(
event_action: Gitlab::UsageDataCounters::TrackUniqueActions::WIKI_ACTION,
date_from: time_period[:created_at].first,
date_to: time_period[:created_at].last
diff --git a/lib/gitlab/usage_data_counters/track_unique_actions.rb b/lib/gitlab/usage_data_counters/track_unique_actions.rb
index 686cce8e0ac..b7948b07251 100644
--- a/lib/gitlab/usage_data_counters/track_unique_actions.rb
+++ b/lib/gitlab/usage_data_counters/track_unique_actions.rb
@@ -27,7 +27,7 @@ module Gitlab
}).freeze
class << self
- def track_action(event_action:, event_target:, author_id:, time: Time.zone.now)
+ def track_event(event_action:, event_target:, author_id:, time: Time.zone.now)
return unless Gitlab::CurrentSettings.usage_ping_enabled
return unless Feature.enabled?(FEATURE_FLAG)
return unless valid_target?(event_target)
@@ -40,7 +40,7 @@ module Gitlab
Gitlab::Redis::HLL.add(key: target_key, value: author_id, expiry: KEY_EXPIRY_LENGTH)
end
- def count_unique_events(event_action:, date_from:, date_to:)
+ def count_unique(event_action:, date_from:, date_to:)
keys = (date_from.to_date..date_to.to_date).map { |date| key(event_action, date) }
Gitlab::Redis::HLL.count(keys: keys)
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 23ae5515f11..e7e42175574 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -2180,6 +2180,9 @@ msgstr ""
msgid "AlertManagement|Resolved"
msgstr ""
+msgid "AlertManagement|Runbook"
+msgstr ""
+
msgid "AlertManagement|Service"
msgstr ""
@@ -27831,9 +27834,6 @@ msgstr ""
msgid "You can also upload existing files from your computer using the instructions below."
msgstr ""
-msgid "You can also use project access tokens to authenticate against Git over HTTP."
-msgstr ""
-
msgid "You can always edit this later"
msgstr ""
diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb
index 2f17cdd795a..ef560f6426b 100644
--- a/spec/controllers/projects/pipelines_controller_spec.rb
+++ b/spec/controllers/projects/pipelines_controller_spec.rb
@@ -859,113 +859,88 @@ RSpec.describe Projects::PipelinesController do
end
end
- context 'when feature is enabled' do
- before do
- stub_feature_flags(junit_pipeline_view: project)
- end
-
- context 'when pipeline does not have a test report' do
- it 'renders an empty test report' do
- get_test_report_json
+ context 'when pipeline does not have a test report' do
+ it 'renders an empty test report' do
+ get_test_report_json
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['total_count']).to eq(0)
- end
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['total_count']).to eq(0)
end
+ end
- context 'when pipeline has a test report' do
- before do
- create(:ci_build, name: 'rspec', pipeline: pipeline).tap do |build|
- create(:ci_job_artifact, :junit, job: build)
- end
- end
-
- it 'renders the test report' do
- get_test_report_json
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['total_count']).to eq(4)
- end
+ context 'when pipeline has a test report' do
+ before do
+ create(:ci_build, :test_reports, name: 'rspec', pipeline: pipeline)
end
- context 'when pipeline has a corrupt test report artifact' do
- before do
- create(:ci_build, name: 'rspec', pipeline: pipeline).tap do |build|
- create(:ci_job_artifact, :junit_with_corrupted_data, job: build)
- end
+ it 'renders the test report' do
+ get_test_report_json
- get_test_report_json
- end
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['total_count']).to eq(4)
+ end
+ end
- it 'renders the test reports' do
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['test_suites'].count).to eq(1)
- end
+ context 'when pipeline has a corrupt test report artifact' do
+ before do
+ create(:ci_build, :broken_test_reports, name: 'rspec', pipeline: pipeline)
- it 'returns a suite_error on the suite with corrupted XML' do
- expect(json_response['test_suites'].first['suite_error']).to eq('JUnit XML parsing failed: 1:1: FATAL: Document is empty')
- end
+ get_test_report_json
end
- context 'when junit_pipeline_screenshots_view is enabled' do
- before do
- stub_feature_flags(junit_pipeline_screenshots_view: project)
- end
-
- context 'when test_report contains attachment and scope is with_attachment as a URL param' do
- let(:pipeline) { create(:ci_pipeline, :with_test_reports_attachment, project: project) }
+ it 'renders the test reports' do
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['test_suites'].count).to eq(1)
+ end
- it 'returns a test reports with attachment' do
- get_test_report_json(scope: 'with_attachment')
+ it 'returns a suite_error on the suite with corrupted XML' do
+ expect(json_response['test_suites'].first['suite_error']).to eq('JUnit XML parsing failed: 1:1: FATAL: Document is empty')
+ end
+ end
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response["test_suites"]).to be_present
- expect(json_response["test_suites"].first["test_cases"].first).to include("attachment_url")
- end
- end
+ context 'when junit_pipeline_screenshots_view is enabled' do
+ before do
+ stub_feature_flags(junit_pipeline_screenshots_view: project)
+ end
- context 'when test_report does not contain attachment and scope is with_attachment as a URL param' do
- let(:pipeline) { create(:ci_pipeline, :with_test_reports, project: project) }
+ context 'when test_report contains attachment and scope is with_attachment as a URL param' do
+ let(:pipeline) { create(:ci_pipeline, :with_test_reports_attachment, project: project) }
- it 'returns a test reports with empty values' do
- get_test_report_json(scope: 'with_attachment')
+ it 'returns a test reports with attachment' do
+ get_test_report_json(scope: 'with_attachment')
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response["test_suites"]).to be_empty
- end
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response["test_suites"]).to be_present
+ expect(json_response["test_suites"].first["test_cases"].first).to include("attachment_url")
end
end
- context 'when junit_pipeline_screenshots_view is disabled' do
- before do
- stub_feature_flags(junit_pipeline_screenshots_view: false)
- end
-
- context 'when test_report contains attachment and scope is with_attachment as a URL param' do
- let(:pipeline) { create(:ci_pipeline, :with_test_reports_attachment, project: project) }
+ context 'when test_report does not contain attachment and scope is with_attachment as a URL param' do
+ let(:pipeline) { create(:ci_pipeline, :with_test_reports, project: project) }
- it 'returns a test reports without attachment_url' do
- get_test_report_json(scope: 'with_attachment')
+ it 'returns a test reports with empty values' do
+ get_test_report_json(scope: 'with_attachment')
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response["test_suites"].first["test_cases"].first).not_to include("attachment_url")
- end
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response["test_suites"]).to be_empty
end
end
end
- context 'when feature is disabled' do
- let(:pipeline) { create(:ci_empty_pipeline, project: project) }
-
+ context 'when junit_pipeline_screenshots_view is disabled' do
before do
- stub_feature_flags(junit_pipeline_view: false)
+ stub_feature_flags(junit_pipeline_screenshots_view: false)
end
- it 'renders empty response' do
- get_test_report_json
+ context 'when test_report contains attachment and scope is with_attachment as a URL param' do
+ let(:pipeline) { create(:ci_pipeline, :with_test_reports_attachment, project: project) }
- expect(response).to have_gitlab_http_status(:no_content)
- expect(response.body).to be_empty
+ it 'returns a test reports without attachment_url' do
+ get_test_report_json(scope: 'with_attachment')
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response["test_suites"].first["test_cases"].first).not_to include("attachment_url")
+ end
end
end
diff --git a/spec/frontend/alert_management/components/alert_details_spec.js b/spec/frontend/alert_management/components/alert_details_spec.js
index 5364d662591..f91f08cae63 100644
--- a/spec/frontend/alert_management/components/alert_details_spec.js
+++ b/spec/frontend/alert_management/components/alert_details_spec.js
@@ -118,6 +118,8 @@ describe('AlertDetails', () => {
${'monitoringTool'} | ${undefined} | ${false}
${'service'} | ${'Prometheus'} | ${true}
${'service'} | ${undefined} | ${false}
+ ${'runbook'} | ${undefined} | ${false}
+ ${'runbook'} | ${'run.com'} | ${true}
`(`$desc`, ({ field, data, isShown }) => {
beforeEach(() => {
mountComponent({ data: { alert: { ...mockAlert, [field]: data } } });
diff --git a/spec/frontend/fixtures/test_report.rb b/spec/frontend/fixtures/test_report.rb
index 16496aa901b..3d09078ba68 100644
--- a/spec/frontend/fixtures/test_report.rb
+++ b/spec/frontend/fixtures/test_report.rb
@@ -15,7 +15,6 @@ RSpec.describe Projects::PipelinesController, "(JavaScript fixtures)", type: :co
before do
sign_in(user)
- stub_feature_flags(junit_pipeline_view: project)
end
it "pipelines/test_report.json" do
diff --git a/spec/frontend/reports/components/grouped_test_reports_app_spec.js b/spec/frontend/reports/components/grouped_test_reports_app_spec.js
index 017e0335569..c26e2fbc19a 100644
--- a/spec/frontend/reports/components/grouped_test_reports_app_spec.js
+++ b/spec/frontend/reports/components/grouped_test_reports_app_spec.js
@@ -20,10 +20,7 @@ describe('Grouped test reports app', () => {
let wrapper;
let mockStore;
- const mountComponent = ({
- glFeatures = { junitPipelineView: false },
- props = { pipelinePath },
- } = {}) => {
+ const mountComponent = ({ props = { pipelinePath } } = {}) => {
wrapper = mount(Component, {
store: mockStore,
localVue,
@@ -35,9 +32,6 @@ describe('Grouped test reports app', () => {
methods: {
fetchReports: () => {},
},
- provide: {
- glFeatures,
- },
});
};
@@ -78,28 +72,17 @@ describe('Grouped test reports app', () => {
});
describe('`View full report` button', () => {
- it('should not render the full test report link', () => {
- expect(findFullTestReportLink().exists()).toBe(false);
- });
+ it('should render the full test report link', () => {
+ const fullTestReportLink = findFullTestReportLink();
- describe('With junitPipelineView feature flag enabled', () => {
- beforeEach(() => {
- mountComponent({ glFeatures: { junitPipelineView: true } });
- });
-
- it('should render the full test report link', () => {
- const fullTestReportLink = findFullTestReportLink();
-
- expect(fullTestReportLink.exists()).toBe(true);
- expect(pipelinePath).not.toBe('');
- expect(fullTestReportLink.attributes('href')).toBe(`${pipelinePath}/test_report`);
- });
+ expect(fullTestReportLink.exists()).toBe(true);
+ expect(pipelinePath).not.toBe('');
+ expect(fullTestReportLink.attributes('href')).toBe(`${pipelinePath}/test_report`);
});
describe('Without a pipelinePath', () => {
beforeEach(() => {
mountComponent({
- glFeatures: { junitPipelineView: true },
props: { pipelinePath: '' },
});
});
diff --git a/spec/lib/banzai/filter/gollum_tags_filter_spec.rb b/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
index 2576dd1bf07..f39b5280490 100644
--- a/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
+++ b/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
@@ -6,8 +6,7 @@ RSpec.describe Banzai::Filter::GollumTagsFilter do
include FilterSpecHelper
let(:project) { create(:project) }
- let(:user) { double }
- let(:wiki) { ProjectWiki.new(project, user) }
+ let(:wiki) { ProjectWiki.new(project, nil) }
describe 'validation' do
it 'ensure that a :wiki key exists in context' do
diff --git a/spec/lib/banzai/filter/wiki_link_filter_spec.rb b/spec/lib/banzai/filter/wiki_link_filter_spec.rb
index 7a4464a2604..d1f6ee49260 100644
--- a/spec/lib/banzai/filter/wiki_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/wiki_link_filter_spec.rb
@@ -7,8 +7,7 @@ RSpec.describe Banzai::Filter::WikiLinkFilter do
let(:namespace) { build_stubbed(:namespace, name: "wiki_link_ns") }
let(:project) { build_stubbed(:project, :public, name: "wiki_link_project", namespace: namespace) }
- let(:user) { double }
- let(:wiki) { ProjectWiki.new(project, user) }
+ let(:wiki) { ProjectWiki.new(project, nil) }
let(:repository_upload_folder) { Wikis::CreateAttachmentService::ATTACHMENT_PATH }
it "doesn't rewrite absolute links" do
diff --git a/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb b/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb
index 4af782c7d73..b102de24041 100644
--- a/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb
+++ b/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Banzai::Pipeline::WikiPipeline do
let_it_be(:namespace) { create(:namespace, name: "wiki_link_ns") }
let_it_be(:project) { create(:project, :public, name: "wiki_link_project", namespace: namespace) }
- let_it_be(:wiki) { ProjectWiki.new(project, double(:user)) }
+ let_it_be(:wiki) { ProjectWiki.new(project, nil) }
let_it_be(:page) { build(:wiki_page, wiki: wiki, title: 'nested/twice/start-page') }
describe 'TableOfContents' do
diff --git a/spec/lib/gitlab/usage_data_counters/track_unique_actions_spec.rb b/spec/lib/gitlab/usage_data_counters/track_unique_actions_spec.rb
index 584d8407e79..6db77f19877 100644
--- a/spec/lib/gitlab/usage_data_counters/track_unique_actions_spec.rb
+++ b/spec/lib/gitlab/usage_data_counters/track_unique_actions_spec.rb
@@ -7,12 +7,12 @@ RSpec.describe Gitlab::UsageDataCounters::TrackUniqueActions, :clean_gitlab_redi
let(:time) { Time.zone.now }
- def track_action(params)
- track_unique_events.track_action(params)
+ def track_event(params)
+ track_unique_events.track_event(params)
end
- def count_unique_events(params)
- track_unique_events.count_unique_events(params)
+ def count_unique(params)
+ track_unique_events.count_unique(params)
end
context 'tracking an event' do
@@ -29,28 +29,28 @@ RSpec.describe Gitlab::UsageDataCounters::TrackUniqueActions, :clean_gitlab_redi
design = Event::TARGET_TYPES[:design]
wiki = Event::TARGET_TYPES[:wiki]
- expect(track_action(event_action: :pushed, event_target: project, author_id: 1)).to be_truthy
- expect(track_action(event_action: :pushed, event_target: project, author_id: 1)).to be_truthy
- expect(track_action(event_action: :pushed, event_target: project, author_id: 2)).to be_truthy
- expect(track_action(event_action: :pushed, event_target: project, author_id: 3)).to be_truthy
- expect(track_action(event_action: :pushed, event_target: project, author_id: 4, time: time - 3.days)).to be_truthy
- expect(track_action(event_action: :created, event_target: project, author_id: 5, time: time - 3.days)).to be_truthy
+ expect(track_event(event_action: :pushed, event_target: project, author_id: 1)).to be_truthy
+ expect(track_event(event_action: :pushed, event_target: project, author_id: 1)).to be_truthy
+ expect(track_event(event_action: :pushed, event_target: project, author_id: 2)).to be_truthy
+ expect(track_event(event_action: :pushed, event_target: project, author_id: 3)).to be_truthy
+ expect(track_event(event_action: :pushed, event_target: project, author_id: 4, time: time - 3.days)).to be_truthy
+ expect(track_event(event_action: :created, event_target: project, author_id: 5, time: time - 3.days)).to be_truthy
- expect(track_action(event_action: :destroyed, event_target: design, author_id: 3)).to be_truthy
- expect(track_action(event_action: :created, event_target: design, author_id: 4)).to be_truthy
- expect(track_action(event_action: :updated, event_target: design, author_id: 5)).to be_truthy
- expect(track_action(event_action: :pushed, event_target: design, author_id: 6)).to be_truthy
+ expect(track_event(event_action: :destroyed, event_target: design, author_id: 3)).to be_truthy
+ expect(track_event(event_action: :created, event_target: design, author_id: 4)).to be_truthy
+ expect(track_event(event_action: :updated, event_target: design, author_id: 5)).to be_truthy
+ expect(track_event(event_action: :pushed, event_target: design, author_id: 6)).to be_truthy
- expect(track_action(event_action: :destroyed, event_target: wiki, author_id: 5)).to be_truthy
- expect(track_action(event_action: :created, event_target: wiki, author_id: 3)).to be_truthy
- expect(track_action(event_action: :updated, event_target: wiki, author_id: 4)).to be_truthy
- expect(track_action(event_action: :pushed, event_target: wiki, author_id: 6)).to be_truthy
+ expect(track_event(event_action: :destroyed, event_target: wiki, author_id: 5)).to be_truthy
+ expect(track_event(event_action: :created, event_target: wiki, author_id: 3)).to be_truthy
+ expect(track_event(event_action: :updated, event_target: wiki, author_id: 4)).to be_truthy
+ expect(track_event(event_action: :pushed, event_target: wiki, author_id: 6)).to be_truthy
- expect(count_unique_events(event_action: described_class::PUSH_ACTION, date_from: time, date_to: Date.today)).to eq(3)
- expect(count_unique_events(event_action: described_class::PUSH_ACTION, date_from: time - 5.days, date_to: Date.tomorrow)).to eq(4)
- expect(count_unique_events(event_action: described_class::DESIGN_ACTION, date_from: time - 5.days, date_to: Date.today)).to eq(3)
- expect(count_unique_events(event_action: described_class::WIKI_ACTION, date_from: time - 5.days, date_to: Date.today)).to eq(3)
- expect(count_unique_events(event_action: described_class::PUSH_ACTION, date_from: time - 5.days, date_to: time - 2.days)).to eq(1)
+ expect(count_unique(event_action: described_class::PUSH_ACTION, date_from: time, date_to: Date.today)).to eq(3)
+ expect(count_unique(event_action: described_class::PUSH_ACTION, date_from: time - 5.days, date_to: Date.tomorrow)).to eq(4)
+ expect(count_unique(event_action: described_class::DESIGN_ACTION, date_from: time - 5.days, date_to: Date.today)).to eq(3)
+ expect(count_unique(event_action: described_class::WIKI_ACTION, date_from: time - 5.days, date_to: Date.today)).to eq(3)
+ expect(count_unique(event_action: described_class::PUSH_ACTION, date_from: time - 5.days, date_to: time - 2.days)).to eq(1)
end
end
end
@@ -73,8 +73,8 @@ RSpec.describe Gitlab::UsageDataCounters::TrackUniqueActions, :clean_gitlab_redi
end
it 'returns the expected values' do
- expect(track_action(event_action: action, event_target: target, author_id: 2)).to be_nil
- expect(count_unique_events(event_action: described_class::PUSH_ACTION, date_from: time, date_to: Date.today)).to eq(0)
+ expect(track_event(event_action: action, event_target: target, author_id: 2)).to be_nil
+ expect(count_unique(event_action: described_class::PUSH_ACTION, date_from: time, date_to: Date.today)).to eq(0)
end
end
end
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index 681784369e0..2fb30b3228a 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -924,14 +924,14 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
wiki = Event::TARGET_TYPES[:wiki]
design = Event::TARGET_TYPES[:design]
- counter.track_action(event_action: :pushed, event_target: project, author_id: 1)
- counter.track_action(event_action: :pushed, event_target: project, author_id: 1)
- counter.track_action(event_action: :pushed, event_target: project, author_id: 2)
- counter.track_action(event_action: :pushed, event_target: project, author_id: 3)
- counter.track_action(event_action: :pushed, event_target: project, author_id: 4, time: time - 3.days)
- counter.track_action(event_action: :created, event_target: project, author_id: 5, time: time - 3.days)
- counter.track_action(event_action: :created, event_target: wiki, author_id: 3)
- counter.track_action(event_action: :created, event_target: design, author_id: 3)
+ counter.track_event(event_action: :pushed, event_target: project, author_id: 1)
+ counter.track_event(event_action: :pushed, event_target: project, author_id: 1)
+ counter.track_event(event_action: :pushed, event_target: project, author_id: 2)
+ counter.track_event(event_action: :pushed, event_target: project, author_id: 3)
+ counter.track_event(event_action: :pushed, event_target: project, author_id: 4, time: time - 3.days)
+ counter.track_event(event_action: :created, event_target: project, author_id: 5, time: time - 3.days)
+ counter.track_event(event_action: :created, event_target: wiki, author_id: 3)
+ counter.track_event(event_action: :created, event_target: design, author_id: 3)
end
it 'returns the distinct count of user actions within the specified time period' do
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index dfc51ff377b..3eb74da09e1 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -1541,4 +1541,48 @@ RSpec.describe Group do
end
end
end
+
+ describe '#default_owner' do
+ let(:group) { build(:group) }
+
+ context 'the group has owners' do
+ before do
+ group.add_owner(create(:user))
+ group.add_owner(create(:user))
+ end
+
+ it 'is the first owner' do
+ expect(group.default_owner)
+ .to eq(group.owners.first)
+ .and be_a(User)
+ end
+ end
+
+ context 'the group has a parent' do
+ let(:parent) { build(:group) }
+
+ before do
+ group.parent = parent
+ parent.add_owner(create(:user))
+ end
+
+ it 'is the first owner of the parent' do
+ expect(group.default_owner)
+ .to eq(parent.default_owner)
+ .and be_a(User)
+ end
+ end
+
+ context 'we fallback to group.owner' do
+ before do
+ group.owner = build(:user)
+ end
+
+ it 'is the group.owner' do
+ expect(group.default_owner)
+ .to eq(group.owner)
+ .and be_a(User)
+ end
+ end
+ end
end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index e6d51e0bfd7..f589589af8f 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -1090,6 +1090,30 @@ RSpec.describe Project do
end
end
+ describe '#default_owner' do
+ let_it_be(:owner) { create(:user) }
+ let_it_be(:namespace) { create(:namespace, owner: owner) }
+
+ context 'the project does not have a group' do
+ let(:project) { build(:project, namespace: namespace) }
+
+ it 'is the namespace owner' do
+ expect(project.default_owner).to eq(owner)
+ end
+ end
+
+ context 'the project is in a group' do
+ let(:group) { build(:group) }
+ let(:project) { build(:project, group: group, namespace: namespace) }
+
+ it 'is the group owner' do
+ allow(group).to receive(:default_owner).and_return(Object.new)
+
+ expect(project.default_owner).to eq(group.default_owner)
+ end
+ end
+ end
+
describe '#external_wiki' do
let(:project) { create(:project) }
diff --git a/spec/models/wiki_spec.rb b/spec/models/wiki_spec.rb
new file mode 100644
index 00000000000..8dd510a0b98
--- /dev/null
+++ b/spec/models/wiki_spec.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe Wiki do
+ describe '.new' do
+ it 'verifies that the user is a User' do
+ expect { described_class.new(double, 1) }.to raise_error(ArgumentError)
+ expect { described_class.new(double, build(:group)) }.to raise_error(ArgumentError)
+ expect { described_class.new(double, build(:user)) }.not_to raise_error
+ expect { described_class.new(double, nil) }.not_to raise_error
+ end
+ end
+end
diff --git a/spec/requests/api/ci/pipelines_spec.rb b/spec/requests/api/ci/pipelines_spec.rb
index 6ab00f96092..111bc933ea4 100644
--- a/spec/requests/api/ci/pipelines_spec.rb
+++ b/spec/requests/api/ci/pipelines_spec.rb
@@ -735,55 +735,36 @@ RSpec.describe API::Ci::Pipelines do
let(:pipeline) { create(:ci_pipeline, project: project) }
- context 'when feature is enabled' do
- before do
- stub_feature_flags(junit_pipeline_view: true)
- end
-
- context 'when pipeline does not have a test report' do
- it 'returns an empty test report' do
- subject
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['total_count']).to eq(0)
- end
- end
-
- context 'when pipeline has a test report' do
- let(:pipeline) { create(:ci_pipeline, :with_test_reports, project: project) }
-
- it 'returns the test report' do
- subject
+ context 'when pipeline does not have a test report' do
+ it 'returns an empty test report' do
+ subject
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['total_count']).to eq(4)
- end
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['total_count']).to eq(0)
end
+ end
- context 'when pipeline has corrupt test reports' do
- before do
- job = create(:ci_build, pipeline: pipeline)
- create(:ci_job_artifact, :junit_with_corrupted_data, job: job, project: project)
- end
+ context 'when pipeline has a test report' do
+ let(:pipeline) { create(:ci_pipeline, :with_test_reports, project: project) }
- it 'returns a suite_error' do
- subject
+ it 'returns the test report' do
+ subject
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['test_suites'].first['suite_error']).to eq('JUnit XML parsing failed: 1:1: FATAL: Document is empty')
- end
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['total_count']).to eq(4)
end
end
- context 'when feature is disabled' do
+ context 'when pipeline has corrupt test reports' do
before do
- stub_feature_flags(junit_pipeline_view: false)
+ create(:ci_build, :broken_test_reports, name: 'rspec', pipeline: pipeline)
end
- it 'renders empty response' do
+ it 'returns a suite_error' do
subject
- expect(response).to have_gitlab_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['test_suites'].first['suite_error']).to eq('JUnit XML parsing failed: 1:1: FATAL: Document is empty')
end
end
end
diff --git a/spec/services/alert_management/alerts/update_service_spec.rb b/spec/services/alert_management/alerts/update_service_spec.rb
index 91b02325bad..ee04fc55984 100644
--- a/spec/services/alert_management/alerts/update_service_spec.rb
+++ b/spec/services/alert_management/alerts/update_service_spec.rb
@@ -147,8 +147,7 @@ RSpec.describe AlertManagement::Alerts::UpdateService do
end
it_behaves_like 'does not add a system note'
- # TODO: We should not add another todo in this scenario
- it_behaves_like 'adds a todo'
+ it_behaves_like 'does not add a todo'
end
context 'with multiple users included' do
diff --git a/spec/services/event_create_service_spec.rb b/spec/services/event_create_service_spec.rb
index 57382b7e5a0..edd585cb4b6 100644
--- a/spec/services/event_create_service_spec.rb
+++ b/spec/services/event_create_service_spec.rb
@@ -207,7 +207,7 @@ RSpec.describe EventCreateService do
tracking_params = { event_action: counter_class::WIKI_ACTION, date_from: Date.yesterday, date_to: Date.today }
expect { create_event }
- .to change { counter_class.count_unique_events(tracking_params) }
+ .to change { counter_class.count_unique(tracking_params) }
.by(1)
end
end
@@ -249,7 +249,7 @@ RSpec.describe EventCreateService do
tracking_params = { event_action: counter_class::PUSH_ACTION, date_from: Date.yesterday, date_to: Date.today }
expect { subject }
- .to change { counter_class.count_unique_events(tracking_params) }
+ .to change { counter_class.count_unique(tracking_params) }
.from(0).to(1)
end
end
@@ -273,7 +273,7 @@ RSpec.describe EventCreateService do
tracking_params = { event_action: counter_class::PUSH_ACTION, date_from: Date.yesterday, date_to: Date.today }
expect { subject }
- .to change { counter_class.count_unique_events(tracking_params) }
+ .to change { counter_class.count_unique(tracking_params) }
.from(0).to(1)
end
end
@@ -328,7 +328,7 @@ RSpec.describe EventCreateService do
tracking_params = { event_action: counter_class::DESIGN_ACTION, date_from: Date.yesterday, date_to: Date.today }
expect { result }
- .to change { counter_class.count_unique_events(tracking_params) }
+ .to change { counter_class.count_unique(tracking_params) }
.from(0).to(1)
end
end
@@ -356,7 +356,7 @@ RSpec.describe EventCreateService do
tracking_params = { event_action: counter_class::DESIGN_ACTION, date_from: Date.yesterday, date_to: Date.today }
expect { result }
- .to change { counter_class.count_unique_events(tracking_params) }
+ .to change { counter_class.count_unique(tracking_params) }
.from(0).to(1)
end
end
diff --git a/spec/services/resource_access_tokens/create_service_spec.rb b/spec/services/resource_access_tokens/create_service_spec.rb
index f22c379cd30..7dbd55a6909 100644
--- a/spec/services/resource_access_tokens/create_service_spec.rb
+++ b/spec/services/resource_access_tokens/create_service_spec.rb
@@ -34,6 +34,16 @@ RSpec.describe ResourceAccessTokens::CreateService do
end
end
+ shared_examples 'fails on gitlab.com' do
+ before do
+ allow(Gitlab).to receive(:com?) { true }
+ end
+
+ it 'returns nil' do
+ expect(subject).to be nil
+ end
+ end
+
shared_examples 'allows creation of bot with valid params' do
it { expect { subject }.to change { User.count }.by(1) }
@@ -171,6 +181,7 @@ RSpec.describe ResourceAccessTokens::CreateService do
it_behaves_like 'fails when user does not have the permission to create a Resource Bot'
it_behaves_like 'fails when flag is disabled'
+ it_behaves_like 'fails on gitlab.com'
context 'user with valid permission' do
before_all do
diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb
index 13da76263b1..94d4b61933d 100644
--- a/spec/services/todo_service_spec.rb
+++ b/spec/services/todo_service_spec.rb
@@ -59,6 +59,10 @@ RSpec.describe TodoService do
should_not_create_todo(user: guest, target: addressed_target_assigned, action: Todo::DIRECTLY_ADDRESSED)
end
+
+ it 'does not create a todo if already assigned' do
+ should_not_create_any_todo { service.send(described_method, target_assigned, author, [john_doe]) }
+ end
end
describe 'Issues' do
@@ -573,10 +577,10 @@ RSpec.describe TodoService do
end
end
- describe '#reassigned_issuable' do
- let(:described_method) { :reassigned_issuable }
+ describe '#reassigned_assignable' do
+ let(:described_method) { :reassigned_assignable }
- context 'issuable is a merge request' do
+ context 'assignable is a merge request' do
it_behaves_like 'reassigned target' do
let(:target_assigned) { create(:merge_request, source_project: project, author: author, assignees: [john_doe], description: "- [ ] Task 1\n- [ ] Task 2 #{mentions}") }
let(:addressed_target_assigned) { create(:merge_request, source_project: project, author: author, assignees: [john_doe], description: "#{directly_addressed}\n- [ ] Task 1\n- [ ] Task 2") }
@@ -584,13 +588,21 @@ RSpec.describe TodoService do
end
end
- context 'issuable is an issue' do
+ context 'assignable is an issue' do
it_behaves_like 'reassigned target' do
let(:target_assigned) { create(:issue, project: project, author: author, assignees: [john_doe], description: "- [ ] Task 1\n- [ ] Task 2 #{mentions}") }
let(:addressed_target_assigned) { create(:issue, project: project, author: author, assignees: [john_doe], description: "#{directly_addressed}\n- [ ] Task 1\n- [ ] Task 2") }
let(:target_unassigned) { create(:issue, project: project, author: author, assignees: []) }
end
end
+
+ context 'assignable is an alert' do
+ it_behaves_like 'reassigned target' do
+ let(:target_assigned) { create(:alert_management_alert, project: project, assignees: [john_doe]) }
+ let(:addressed_target_assigned) { create(:alert_management_alert, project: project, assignees: [john_doe]) }
+ let(:target_unassigned) { create(:alert_management_alert, project: project, assignees: []) }
+ end
+ end
end
describe 'Merge Requests' do
@@ -778,16 +790,6 @@ RSpec.describe TodoService do
end
end
- describe '#assign_alert' do
- let(:described_method) { :assign_alert }
-
- it_behaves_like 'reassigned target' do
- let(:target_assigned) { create(:alert_management_alert, project: project, assignees: [john_doe]) }
- let(:addressed_target_assigned) { create(:alert_management_alert, project: project, assignees: [john_doe]) }
- let(:target_unassigned) { create(:alert_management_alert, project: project, assignees: []) }
- end
- end
-
describe '#merge_request_build_failed' do
let(:merge_participants) { [mr_unassigned.author, admin] }