Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
f4182abcb6
commit
458209640c
|
|
@ -30,9 +30,6 @@ Graphql/IDType:
|
||||||
- 'app/graphql/mutations/boards/issues/issue_move_list.rb'
|
- 'app/graphql/mutations/boards/issues/issue_move_list.rb'
|
||||||
- 'app/graphql/mutations/issues/update.rb'
|
- 'app/graphql/mutations/issues/update.rb'
|
||||||
- 'app/graphql/mutations/metrics/dashboard/annotations/delete.rb'
|
- 'app/graphql/mutations/metrics/dashboard/annotations/delete.rb'
|
||||||
- 'app/graphql/mutations/snippets/destroy.rb'
|
|
||||||
- 'app/graphql/mutations/snippets/mark_as_spam.rb'
|
|
||||||
- 'app/graphql/mutations/snippets/update.rb'
|
|
||||||
- 'app/graphql/resolvers/design_management/design_at_version_resolver.rb'
|
- 'app/graphql/resolvers/design_management/design_at_version_resolver.rb'
|
||||||
- 'app/graphql/resolvers/design_management/design_resolver.rb'
|
- 'app/graphql/resolvers/design_management/design_resolver.rb'
|
||||||
- 'app/graphql/resolvers/design_management/designs_resolver.rb'
|
- 'app/graphql/resolvers/design_management/designs_resolver.rb'
|
||||||
|
|
@ -42,7 +39,6 @@ Graphql/IDType:
|
||||||
- 'app/graphql/resolvers/design_management/versions_resolver.rb'
|
- 'app/graphql/resolvers/design_management/versions_resolver.rb'
|
||||||
- 'app/graphql/resolvers/error_tracking/sentry_detailed_error_resolver.rb'
|
- 'app/graphql/resolvers/error_tracking/sentry_detailed_error_resolver.rb'
|
||||||
- 'app/graphql/resolvers/error_tracking/sentry_error_stack_trace_resolver.rb'
|
- 'app/graphql/resolvers/error_tracking/sentry_error_stack_trace_resolver.rb'
|
||||||
- 'app/graphql/resolvers/snippets_resolver.rb'
|
|
||||||
- 'app/graphql/resolvers/user_merge_requests_resolver.rb'
|
- 'app/graphql/resolvers/user_merge_requests_resolver.rb'
|
||||||
|
|
||||||
Graphql/ResolverType:
|
Graphql/ResolverType:
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,12 @@ import Modal from './modal.vue';
|
||||||
import createStore from '../store';
|
import createStore from '../store';
|
||||||
import Tracking from '~/tracking';
|
import Tracking from '~/tracking';
|
||||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||||
import { summaryTextBuilder, reportTextBuilder, statusIcon } from '../store/utils';
|
import {
|
||||||
|
summaryTextBuilder,
|
||||||
|
reportTextBuilder,
|
||||||
|
statusIcon,
|
||||||
|
recentFailuresTextBuilder,
|
||||||
|
} from '../store/utils';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'GroupedTestReportsApp',
|
name: 'GroupedTestReportsApp',
|
||||||
|
|
@ -86,6 +91,12 @@ export default {
|
||||||
|
|
||||||
return reportTextBuilder(name, summary);
|
return reportTextBuilder(name, summary);
|
||||||
},
|
},
|
||||||
|
hasRecentFailures(summary) {
|
||||||
|
return this.glFeatures.testFailureHistory && summary?.recentlyFailed > 0;
|
||||||
|
},
|
||||||
|
recentFailuresText(summary) {
|
||||||
|
return recentFailuresTextBuilder(summary);
|
||||||
|
},
|
||||||
getReportIcon(report) {
|
getReportIcon(report) {
|
||||||
return statusIcon(report.status);
|
return statusIcon(report.status);
|
||||||
},
|
},
|
||||||
|
|
@ -134,14 +145,22 @@ export default {
|
||||||
{{ s__('ciReport|View full report') }}
|
{{ s__('ciReport|View full report') }}
|
||||||
</gl-button>
|
</gl-button>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-if="hasRecentFailures(summary)" #subHeading>
|
||||||
|
{{ recentFailuresText(summary) }}
|
||||||
|
</template>
|
||||||
<template #body>
|
<template #body>
|
||||||
<div class="mr-widget-grouped-section report-block">
|
<div class="mr-widget-grouped-section report-block">
|
||||||
<template v-for="(report, i) in reports">
|
<template v-for="(report, i) in reports">
|
||||||
<summary-row
|
<summary-row :key="`summary-row-${i}`" :status-icon="getReportIcon(report)">
|
||||||
:key="`summary-row-${i}`"
|
<template #summary>
|
||||||
:summary="reportText(report)"
|
<div class="gl-display-inline-flex gl-flex-direction-column">
|
||||||
:status-icon="getReportIcon(report)"
|
<div>{{ reportText(report) }}</div>
|
||||||
/>
|
<div v-if="hasRecentFailures(report.summary)">
|
||||||
|
{{ recentFailuresText(report.summary) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</summary-row>
|
||||||
<issues-list
|
<issues-list
|
||||||
v-if="shouldRenderIssuesList(report)"
|
v-if="shouldRenderIssuesList(report)"
|
||||||
:key="`issues-list-${i}`"
|
:key="`issues-list-${i}`"
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,15 @@
|
||||||
<script>
|
<script>
|
||||||
import { mapActions } from 'vuex';
|
import { mapActions } from 'vuex';
|
||||||
|
import { GlBadge } from '@gitlab/ui';
|
||||||
|
import { n__ } from '~/locale';
|
||||||
|
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TestIssueBody',
|
name: 'TestIssueBody',
|
||||||
|
components: {
|
||||||
|
GlBadge,
|
||||||
|
},
|
||||||
|
mixins: [glFeatureFlagsMixin()],
|
||||||
props: {
|
props: {
|
||||||
issue: {
|
issue: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|
@ -19,8 +26,20 @@ export default {
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
showRecentFailures() {
|
||||||
|
return this.glFeatures.testFailureHistory && this.issue.recent_failures;
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['openModal']),
|
...mapActions(['openModal']),
|
||||||
|
recentFailuresText(count) {
|
||||||
|
return n__(
|
||||||
|
'Failed %d time in the last 14 days',
|
||||||
|
'Failed %d times in the last 14 days',
|
||||||
|
count,
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -32,7 +51,10 @@ export default {
|
||||||
class="btn-link btn-blank text-left break-link vulnerability-name-button"
|
class="btn-link btn-blank text-left break-link vulnerability-name-button"
|
||||||
@click="openModal({ issue })"
|
@click="openModal({ issue })"
|
||||||
>
|
>
|
||||||
<div v-if="isNew" class="badge badge-danger gl-mr-2">{{ s__('New') }}</div>
|
<gl-badge v-if="isNew" variant="danger" class="gl-mr-2">{{ s__('New') }}</gl-badge>
|
||||||
|
<gl-badge v-if="showRecentFailures" variant="warning" class="gl-mr-2">
|
||||||
|
{{ recentFailuresText(issue.recent_failures) }}
|
||||||
|
</gl-badge>
|
||||||
{{ issue.name }}
|
{{ issue.name }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import * as types from './mutation_types';
|
import * as types from './mutation_types';
|
||||||
|
import { countRecentlyFailedTests } from './utils';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
[types.SET_ENDPOINT](state, endpoint) {
|
[types.SET_ENDPOINT](state, endpoint) {
|
||||||
|
|
@ -16,9 +17,15 @@ export default {
|
||||||
state.summary.resolved = response.summary.resolved;
|
state.summary.resolved = response.summary.resolved;
|
||||||
state.summary.failed = response.summary.failed;
|
state.summary.failed = response.summary.failed;
|
||||||
state.summary.errored = response.summary.errored;
|
state.summary.errored = response.summary.errored;
|
||||||
|
state.summary.recentlyFailed = countRecentlyFailedTests(response.suites);
|
||||||
|
|
||||||
state.status = response.status;
|
state.status = response.status;
|
||||||
state.reports = response.suites;
|
state.reports = response.suites;
|
||||||
|
|
||||||
|
state.reports.forEach((report, i) => {
|
||||||
|
if (!state.reports[i].summary) return;
|
||||||
|
state.reports[i].summary.recentlyFailed = countRecentlyFailedTests(report);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
[types.RECEIVE_REPORTS_ERROR](state) {
|
[types.RECEIVE_REPORTS_ERROR](state) {
|
||||||
state.isLoading = false;
|
state.isLoading = false;
|
||||||
|
|
@ -30,6 +37,7 @@ export default {
|
||||||
resolved: 0,
|
resolved: 0,
|
||||||
failed: 0,
|
failed: 0,
|
||||||
errored: 0,
|
errored: 0,
|
||||||
|
recentlyFailed: 0,
|
||||||
};
|
};
|
||||||
state.status = null;
|
state.status = null;
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,48 @@ export const reportTextBuilder = (name = '', results = {}) => {
|
||||||
return sprintf(__('%{name} found %{resultsString}'), { name, resultsString });
|
return sprintf(__('%{name} found %{resultsString}'), { name, resultsString });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const recentFailuresTextBuilder = (summary = {}) => {
|
||||||
|
const { failed, recentlyFailed } = summary;
|
||||||
|
if (!failed || !recentlyFailed) return '';
|
||||||
|
|
||||||
|
if (failed < 2) {
|
||||||
|
return sprintf(
|
||||||
|
s__(
|
||||||
|
'Reports|%{recentlyFailed} out of %{failed} failed test has failed more than once in the last 14 days',
|
||||||
|
),
|
||||||
|
{ recentlyFailed, failed },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return sprintf(
|
||||||
|
n__(
|
||||||
|
s__(
|
||||||
|
'Reports|%{recentlyFailed} out of %{failed} failed tests has failed more than once in the last 14 days',
|
||||||
|
),
|
||||||
|
s__(
|
||||||
|
'Reports|%{recentlyFailed} out of %{failed} failed tests have failed more than once in the last 14 days',
|
||||||
|
),
|
||||||
|
recentlyFailed,
|
||||||
|
),
|
||||||
|
{ recentlyFailed, failed },
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const countRecentlyFailedTests = subject => {
|
||||||
|
// handle either a single report or an array of reports
|
||||||
|
const reports = !subject.length ? [subject] : subject;
|
||||||
|
|
||||||
|
return reports
|
||||||
|
.map(report => {
|
||||||
|
return (
|
||||||
|
[report.new_failures, report.existing_failures, report.resolved_failures]
|
||||||
|
// only count tests which have failed more than once
|
||||||
|
.map(failureArray => failureArray.filter(failure => failure.recent_failures > 1).length)
|
||||||
|
.reduce((total, count) => total + count, 0)
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.reduce((total, count) => total + count, 0);
|
||||||
|
};
|
||||||
|
|
||||||
export const statusIcon = status => {
|
export const statusIcon = status => {
|
||||||
if (status === STATUS_FAILED) {
|
if (status === STATUS_FAILED) {
|
||||||
return ICON_WARNING;
|
return ICON_WARNING;
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ class Admin::DashboardController < Admin::ApplicationController
|
||||||
@groups = Group.order_id_desc.with_route.limit(10)
|
@groups = Group.order_id_desc.with_route.limit(10)
|
||||||
@notices = Gitlab::ConfigChecker::PumaRuggedChecker.check
|
@notices = Gitlab::ConfigChecker::PumaRuggedChecker.check
|
||||||
@notices += Gitlab::ConfigChecker::ExternalDatabaseChecker.check
|
@notices += Gitlab::ConfigChecker::ExternalDatabaseChecker.check
|
||||||
|
@redis_versions = [Gitlab::Redis::Queues, Gitlab::Redis::SharedState, Gitlab::Redis::Cache].map(&:version).uniq
|
||||||
end
|
end
|
||||||
# rubocop: enable CodeReuse/ActiveRecord
|
# rubocop: enable CodeReuse/ActiveRecord
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
|
||||||
push_frontend_feature_flag(:default_merge_ref_for_diffs, @project)
|
push_frontend_feature_flag(:default_merge_ref_for_diffs, @project)
|
||||||
push_frontend_feature_flag(:core_security_mr_widget, @project, default_enabled: true)
|
push_frontend_feature_flag(:core_security_mr_widget, @project, default_enabled: true)
|
||||||
push_frontend_feature_flag(:remove_resolve_note, @project, default_enabled: true)
|
push_frontend_feature_flag(:remove_resolve_note, @project, default_enabled: true)
|
||||||
|
push_frontend_feature_flag(:test_failure_history, @project)
|
||||||
|
|
||||||
record_experiment_user(:invite_members_version_a)
|
record_experiment_user(:invite_members_version_a)
|
||||||
record_experiment_user(:invite_members_version_b)
|
record_experiment_user(:invite_members_version_b)
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,10 @@ class DeviseMailer < Devise::Mailer
|
||||||
devise_mail(record, :password_change_by_admin, opts)
|
devise_mail(record, :password_change_by_admin, opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def user_admin_approval(record, opts = {})
|
||||||
|
devise_mail(record, :user_admin_approval, opts)
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def subject_for(key)
|
def subject_for(key)
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,10 @@ class DeviseMailerPreview < ActionMailer::Preview
|
||||||
DeviseMailer.password_change(unsaved_user, {})
|
DeviseMailer.password_change(unsaved_user, {})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def user_admin_approval
|
||||||
|
DeviseMailer.user_admin_approval(unsaved_user, {})
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def unsaved_user
|
def unsaved_user
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ module Users
|
||||||
# Please see Devise's implementation of `resend_confirmation_instructions` for detail.
|
# Please see Devise's implementation of `resend_confirmation_instructions` for detail.
|
||||||
user.resend_confirmation_instructions
|
user.resend_confirmation_instructions
|
||||||
user.accept_pending_invitations! if user.active_for_authentication?
|
user.accept_pending_invitations! if user.active_for_authentication?
|
||||||
|
DeviseMailer.user_admin_approval(user).deliver_later
|
||||||
|
|
||||||
success
|
success
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,10 @@
|
||||||
= Gitlab::Database.human_adapter_name
|
= Gitlab::Database.human_adapter_name
|
||||||
%span.float-right
|
%span.float-right
|
||||||
= Gitlab::Database.version
|
= Gitlab::Database.version
|
||||||
|
%p
|
||||||
|
= _('Redis')
|
||||||
|
%span.float-right
|
||||||
|
= @redis_versions&.join(", ")
|
||||||
%p
|
%p
|
||||||
= link_to _("Gitaly Servers"), admin_gitaly_servers_path
|
= link_to _("Gitaly Servers"), admin_gitaly_servers_path
|
||||||
.row
|
.row
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
= email_default_heading(say_hi(@resource))
|
||||||
|
|
||||||
|
%p
|
||||||
|
= _('Your GitLab account request has been approved!')
|
||||||
|
%p
|
||||||
|
= _('Your username is %{username}.') % { username: @resource.username }
|
||||||
|
%p
|
||||||
|
= _('Your sign-in page is %{url}.').html_safe % { url: link_to(Gitlab.config.gitlab.url, Gitlab.config.gitlab.url) }
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<%= say_hi(@resource) %>
|
||||||
|
|
||||||
|
<%= _('Your GitLab account request has been approved!') %>
|
||||||
|
|
||||||
|
<%= _('Your username is %{username}.' % { username: @resource.username }) %>
|
||||||
|
|
||||||
|
<%= _('Your sign-in page is %{url}.' % { url: Gitlab.config.gitlab.url }) %>
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Email user on admin account approval
|
||||||
|
merge_request: 45947
|
||||||
|
author:
|
||||||
|
type: added
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Include aggregated git-write usage counts
|
||||||
|
merge_request: 47511
|
||||||
|
author:
|
||||||
|
type: added
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Add Redis version to admin page
|
||||||
|
merge_request: 47242
|
||||||
|
author:
|
||||||
|
type: added
|
||||||
|
|
@ -30,6 +30,8 @@ en:
|
||||||
subject: "Password Changed"
|
subject: "Password Changed"
|
||||||
password_change_by_admin:
|
password_change_by_admin:
|
||||||
subject: "Password changed by administrator"
|
subject: "Password changed by administrator"
|
||||||
|
user_admin_approval:
|
||||||
|
subject: "Welcome to GitLab!"
|
||||||
omniauth_callbacks:
|
omniauth_callbacks:
|
||||||
failure: "Could not authenticate you from %{kind} because \"%{reason}\"."
|
failure: "Could not authenticate you from %{kind} because \"%{reason}\"."
|
||||||
success: "Successfully authenticated from %{kind} account."
|
success: "Successfully authenticated from %{kind} account."
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class CreatedIndexForVulnerabilityOccurrencesOnProjectFingerprint < ActiveRecord::Migration[6.0]
|
||||||
|
include Gitlab::Database::MigrationHelpers
|
||||||
|
|
||||||
|
DOWNTIME = false
|
||||||
|
INDEX_NAME = 'index_vulnerability_occurrences_on_project_fingerprint'
|
||||||
|
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
|
def up
|
||||||
|
add_concurrent_index :vulnerability_occurrences, :project_fingerprint, name: INDEX_NAME
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_concurrent_index_by_name :vulnerability_occurrences, INDEX_NAME
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
21245809e056dfefedc4d2c6a8e2bf642bfcee480a863f8707ba6fa6b748a2e0
|
||||||
|
|
@ -22211,6 +22211,8 @@ CREATE INDEX index_vulnerability_occurrences_for_issue_links_migration ON vulner
|
||||||
|
|
||||||
CREATE INDEX index_vulnerability_occurrences_on_primary_identifier_id ON vulnerability_occurrences USING btree (primary_identifier_id);
|
CREATE INDEX index_vulnerability_occurrences_on_primary_identifier_id ON vulnerability_occurrences USING btree (primary_identifier_id);
|
||||||
|
|
||||||
|
CREATE INDEX index_vulnerability_occurrences_on_project_fingerprint ON vulnerability_occurrences USING btree (project_fingerprint);
|
||||||
|
|
||||||
CREATE INDEX index_vulnerability_occurrences_on_scanner_id ON vulnerability_occurrences USING btree (scanner_id);
|
CREATE INDEX index_vulnerability_occurrences_on_scanner_id ON vulnerability_occurrences USING btree (scanner_id);
|
||||||
|
|
||||||
CREATE UNIQUE INDEX index_vulnerability_occurrences_on_unique_keys ON vulnerability_occurrences USING btree (project_id, primary_identifier_id, location_fingerprint, scanner_id);
|
CREATE UNIQUE INDEX index_vulnerability_occurrences_on_unique_keys ON vulnerability_occurrences USING btree (project_id, primary_identifier_id, location_fingerprint, scanner_id);
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
||||||
|
|
||||||
Available action types for the `action` parameter are:
|
Available action types for the `action` parameter are:
|
||||||
|
|
||||||
|
- `approved`
|
||||||
- `created`
|
- `created`
|
||||||
- `updated`
|
- `updated`
|
||||||
- `closed`
|
- `closed`
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,7 @@ See [database guidelines](database/index.md).
|
||||||
## Documentation guides
|
## Documentation guides
|
||||||
|
|
||||||
- [Writing documentation](documentation/index.md)
|
- [Writing documentation](documentation/index.md)
|
||||||
- [Documentation style guide](documentation/styleguide.md)
|
- [Documentation style guide](documentation/styleguide/index.md)
|
||||||
- [Markdown](../user/markdown.md)
|
- [Markdown](../user/markdown.md)
|
||||||
|
|
||||||
## Internationalization (i18n) guides
|
## Internationalization (i18n) guides
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ Keep the following in mind when submitting merge requests:
|
||||||
reviewers.
|
reviewers.
|
||||||
- If the code quality is found to not meet GitLab’s standards, the merge request reviewer will
|
- If the code quality is found to not meet GitLab’s standards, the merge request reviewer will
|
||||||
provide guidance and refer the author to our:
|
provide guidance and refer the author to our:
|
||||||
- [Documentation](../documentation/styleguide.md) style guide.
|
- [Documentation](../documentation/styleguide/index.md) style guide.
|
||||||
- Code style guides.
|
- Code style guides.
|
||||||
- Sometimes style guides will be followed but the code will lack structural integrity, or the
|
- Sometimes style guides will be followed but the code will lack structural integrity, or the
|
||||||
reviewer will have reservations about the code’s overall quality. When there is a reservation,
|
reviewer will have reservations about the code’s overall quality. When there is a reservation,
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ We're following [Ciro Santilli's Markdown Style Guide](https://cirosantilli.com/
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
See the dedicated [Documentation Style Guide](../documentation/styleguide.md).
|
See the dedicated [Documentation Style Guide](../documentation/styleguide/index.md).
|
||||||
|
|
||||||
## Python
|
## Python
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ See how to document them below, according to the state of the flag:
|
||||||
- [Features that can be enabled or disabled for a single project](#features-enabled-by-project).
|
- [Features that can be enabled or disabled for a single project](#features-enabled-by-project).
|
||||||
- [Features with the feature flag removed](#features-with-flag-removed).
|
- [Features with the feature flag removed](#features-with-flag-removed).
|
||||||
|
|
||||||
The [`**(CORE ONLY)**`](styleguide.md#product-badges) badge or equivalent for
|
The [`**(CORE ONLY)**`](styleguide/index.md#product-badges) badge or equivalent for
|
||||||
the feature's tier should be added to the line and heading that refers to
|
the feature's tier should be added to the line and heading that refers to
|
||||||
enabling/disabling feature flags as Admin access is required to do so,
|
enabling/disabling feature flags as Admin access is required to do so,
|
||||||
therefore, it indicates that it cannot be done by regular users of GitLab.com.
|
therefore, it indicates that it cannot be done by regular users of GitLab.com.
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ Set up the section with the following:
|
||||||
```
|
```
|
||||||
|
|
||||||
- Include a screenshot of the result in the GraphiQL explorer. Follow the naming
|
- Include a screenshot of the result in the GraphiQL explorer. Follow the naming
|
||||||
convention described in the [Save the image](styleguide.md#save-the-image) section of the Documentation style guide.
|
convention described in the [Save the image](styleguide/index.md#save-the-image) section of the Documentation style guide.
|
||||||
- Follow up with an example of what you can do with the output. Make sure the
|
- Follow up with an example of what you can do with the output. Make sure the
|
||||||
example is something that readers can do on their own deployments.
|
example is something that readers can do on their own deployments.
|
||||||
- Include a link to the [GraphQL API resources](../../api/graphql/reference/index.md).
|
- Include a link to the [GraphQL API resources](../../api/graphql/reference/index.md).
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ GitLab's documentation is [intended as the single source of truth (SSOT)](https:
|
||||||
|
|
||||||
In addition to this page, the following resources can help you craft and contribute to documentation:
|
In addition to this page, the following resources can help you craft and contribute to documentation:
|
||||||
|
|
||||||
- [Style Guide](styleguide.md) - What belongs in the docs, language guidelines, Markdown standards to follow, links, and more.
|
- [Style Guide](styleguide/index.md) - What belongs in the docs, language guidelines, Markdown standards to follow, links, and more.
|
||||||
- [Structure and template](structure.md) - Learn the typical parts of a doc page and how to write each one.
|
- [Structure and template](structure.md) - Learn the typical parts of a doc page and how to write each one.
|
||||||
- [Documentation process](workflow.md).
|
- [Documentation process](workflow.md).
|
||||||
- [Markdown Guide](../../user/markdown.md) - A reference for all Markdown syntax supported by GitLab.
|
- [Markdown Guide](../../user/markdown.md) - A reference for all Markdown syntax supported by GitLab.
|
||||||
|
|
@ -64,11 +64,11 @@ However, anyone can contribute [documentation improvements](workflow.md) that ar
|
||||||
[GitLab docs](https://gitlab.com/gitlab-org/gitlab-docs) uses [GitLab Kramdown](https://gitlab.com/gitlab-org/gitlab_kramdown)
|
[GitLab docs](https://gitlab.com/gitlab-org/gitlab-docs) uses [GitLab Kramdown](https://gitlab.com/gitlab-org/gitlab_kramdown)
|
||||||
as its Markdown rendering engine. See the [GitLab Markdown Guide](https://about.gitlab.com/handbook/markdown-guide/) for a complete Kramdown reference.
|
as its Markdown rendering engine. See the [GitLab Markdown Guide](https://about.gitlab.com/handbook/markdown-guide/) for a complete Kramdown reference.
|
||||||
|
|
||||||
Adhere to the [Documentation Style Guide](styleguide.md). If a style standard is missing, you are welcome to suggest one via a merge request.
|
Adhere to the [Documentation Style Guide](styleguide/index.md). If a style standard is missing, you are welcome to suggest one via a merge request.
|
||||||
|
|
||||||
## Folder structure and files
|
## Folder structure and files
|
||||||
|
|
||||||
See the [Structure](styleguide.md#structure) section of the [Documentation Style Guide](styleguide.md).
|
See the [Structure](styleguide/index.md#structure) section of the [Documentation Style Guide](styleguide/index.md).
|
||||||
|
|
||||||
## Metadata
|
## Metadata
|
||||||
|
|
||||||
|
|
@ -229,7 +229,7 @@ Things to note:
|
||||||
it in for `workflow/lfs/lfs_administration` and `lfs/lfs_administration`
|
it in for `workflow/lfs/lfs_administration` and `lfs/lfs_administration`
|
||||||
and will print the file and the line where this file is mentioned.
|
and will print the file and the line where this file is mentioned.
|
||||||
You may ask why the two greps. Since [we use relative paths to link to
|
You may ask why the two greps. Since [we use relative paths to link to
|
||||||
documentation](styleguide.md#links), sometimes it might be useful to search a path deeper.
|
documentation](styleguide/index.md#links), sometimes it might be useful to search a path deeper.
|
||||||
- The `*.md` extension is not used when a document is linked to GitLab's
|
- The `*.md` extension is not used when a document is linked to GitLab's
|
||||||
built-in help page, which is why we omit it in `git grep`.
|
built-in help page, which is why we omit it in `git grep`.
|
||||||
- Use the checklist on the "Change documentation location" MR description template.
|
- Use the checklist on the "Change documentation location" MR description template.
|
||||||
|
|
|
||||||
|
|
@ -105,8 +105,8 @@ you can use in the API documentation.
|
||||||
|
|
||||||
CAUTION: **Caution:**
|
CAUTION: **Caution:**
|
||||||
Do not use information for real users, URLs, or tokens. For documentation, refer to our
|
Do not use information for real users, URLs, or tokens. For documentation, refer to our
|
||||||
relevant style guide sections on [Fake user information](styleguide.md#fake-user-information),
|
relevant style guide sections on [Fake user information](styleguide/index.md#fake-user-information),
|
||||||
[Fake URLs](styleguide.md#fake-urls), and [Fake tokens](styleguide.md#fake-tokens).
|
[Fake URLs](styleguide/index.md#fake-urls), and [Fake tokens](styleguide/index.md#fake-tokens).
|
||||||
|
|
||||||
### Simple cURL command
|
### Simple cURL command
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ description: What to include in GitLab documentation pages.
|
||||||
Use these standards to contribute content to the GitLab documentation.
|
Use these standards to contribute content to the GitLab documentation.
|
||||||
|
|
||||||
Before getting started, familiarize yourself with [GitLab's Documentation guidelines](index.md)
|
Before getting started, familiarize yourself with [GitLab's Documentation guidelines](index.md)
|
||||||
and the [Documentation Style Guide](styleguide.md).
|
and the [Documentation Style Guide](styleguide/index.md).
|
||||||
|
|
||||||
## Components of a documentation page
|
## Components of a documentation page
|
||||||
|
|
||||||
|
|
@ -39,7 +39,7 @@ pre-deployment and post-deployment tasks.
|
||||||
|
|
||||||
## Template for new docs
|
## Template for new docs
|
||||||
|
|
||||||
Follow the [folder structure and file name guidelines](styleguide.md#folder-structure-overview)
|
Follow the [folder structure and file name guidelines](styleguide/index.md#folder-structure-overview)
|
||||||
and create a new topic by using this template:
|
and create a new topic by using this template:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
|
|
@ -160,9 +160,9 @@ commented out to help encourage others to add to it in the future. -->
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
- (1): Apply the [tier badges](styleguide.md#product-badges) accordingly.
|
- (1): Apply the [tier badges](styleguide/index.md#product-badges) accordingly.
|
||||||
- (2): Apply the correct format for the
|
- (2): Apply the correct format for the
|
||||||
[GitLab version that introduces the feature](styleguide.md#gitlab-versions-and-tiers).
|
[GitLab version that introduces the feature](styleguide/index.md#gitlab-versions-and-tiers).
|
||||||
```
|
```
|
||||||
|
|
||||||
## Help and feedback section
|
## Help and feedback section
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -122,7 +122,7 @@ and you should make sure your version matches the version used by GitLab.
|
||||||
|
|
||||||
## Local linters
|
## Local linters
|
||||||
|
|
||||||
To help adhere to the [documentation style guidelines](styleguide.md), and improve the content
|
To help adhere to the [documentation style guidelines](styleguide/index.md), and improve the content
|
||||||
added to documentation, [install documentation linters](#install-linters) and
|
added to documentation, [install documentation linters](#install-linters) and
|
||||||
[integrate them with your code editor](#configure-editors).
|
[integrate them with your code editor](#configure-editors).
|
||||||
|
|
||||||
|
|
@ -137,7 +137,7 @@ At GitLab, we mostly use:
|
||||||
[certain rules](https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md#rules), and is
|
[certain rules](https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md#rules), and is
|
||||||
used by the `docs-lint` test.
|
used by the `docs-lint` test.
|
||||||
|
|
||||||
Our [Documentation Style Guide](styleguide.md#markdown) and
|
Our [Documentation Style Guide](styleguide/index.md#markdown) and
|
||||||
[Markdown Guide](https://about.gitlab.com/handbook/markdown-guide/) elaborate on which choices must
|
[Markdown Guide](https://about.gitlab.com/handbook/markdown-guide/) elaborate on which choices must
|
||||||
be made when selecting Markdown syntax for GitLab documentation. This tool helps catch deviations
|
be made when selecting Markdown syntax for GitLab documentation. This tool helps catch deviations
|
||||||
from those guidelines.
|
from those guidelines.
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ To update GitLab documentation:
|
||||||
[GitLab Documentation guidelines](index.md) page.
|
[GitLab Documentation guidelines](index.md) page.
|
||||||
1. Follow the described standards and processes listed on the page, including:
|
1. Follow the described standards and processes listed on the page, including:
|
||||||
- The [Structure and template](structure.md) page.
|
- The [Structure and template](structure.md) page.
|
||||||
- The [Style Guide](styleguide.md).
|
- The [Style Guide](styleguide/index.md).
|
||||||
- The [Markdown Guide](https://about.gitlab.com/handbook/markdown-guide/).
|
- The [Markdown Guide](https://about.gitlab.com/handbook/markdown-guide/).
|
||||||
1. Follow GitLab's [Merge Request Guidelines](../contributing/merge_request_workflow.md#merge-request-guidelines).
|
1. Follow GitLab's [Merge Request Guidelines](../contributing/merge_request_workflow.md#merge-request-guidelines).
|
||||||
|
|
||||||
|
|
@ -87,7 +87,7 @@ Anyone with Maintainer access to the relevant GitLab project can merge documenta
|
||||||
Maintainers must make a good-faith effort to ensure that the content:
|
Maintainers must make a good-faith effort to ensure that the content:
|
||||||
|
|
||||||
- Is clear and sufficiently easy for the intended audience to navigate and understand.
|
- Is clear and sufficiently easy for the intended audience to navigate and understand.
|
||||||
- Meets the [Documentation Guidelines](index.md) and [Style Guide](styleguide.md).
|
- Meets the [Documentation Guidelines](index.md) and [Style Guide](styleguide/index.md).
|
||||||
|
|
||||||
If the author or reviewer has any questions, they can mention the writer who is assigned to the relevant
|
If the author or reviewer has any questions, they can mention the writer who is assigned to the relevant
|
||||||
[DevOps stage group](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments).
|
[DevOps stage group](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments).
|
||||||
|
|
@ -154,15 +154,15 @@ Remember:
|
||||||
|
|
||||||
Ensure the following if skipping an initial Technical Writer review:
|
Ensure the following if skipping an initial Technical Writer review:
|
||||||
|
|
||||||
- That [product badges](styleguide.md#product-badges) are applied.
|
- That [product badges](styleguide/index.md#product-badges) are applied.
|
||||||
- That the GitLab [version](styleguide.md#text-for-documentation-requiring-version-text) that
|
- That the GitLab [version](styleguide/index.md#text-for-documentation-requiring-version-text) that
|
||||||
introduced the feature has been included.
|
introduced the feature has been included.
|
||||||
- That changes to headings don't affect in-app hyperlinks.
|
- That changes to headings don't affect in-app hyperlinks.
|
||||||
- Specific [user permissions](../../user/permissions.md) are documented.
|
- Specific [user permissions](../../user/permissions.md) are documented.
|
||||||
- That new documents are linked from higher-level indexes, for discoverability.
|
- That new documents are linked from higher-level indexes, for discoverability.
|
||||||
- Style guide is followed:
|
- Style guide is followed:
|
||||||
- For [directories and files](styleguide.md#work-with-directories-and-files).
|
- For [directories and files](styleguide/index.md#work-with-directories-and-files).
|
||||||
- For [images](styleguide.md#images).
|
- For [images](styleguide/index.md#images).
|
||||||
|
|
||||||
Merge requests that change the location of documentation must always be reviewed by a Technical
|
Merge requests that change the location of documentation must always be reviewed by a Technical
|
||||||
Writer prior to merging.
|
Writer prior to merging.
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
||||||
- **Write the code and the tests.**: As with any code, EE features should have
|
- **Write the code and the tests.**: As with any code, EE features should have
|
||||||
good test coverage to prevent regressions.
|
good test coverage to prevent regressions.
|
||||||
- **Write documentation.**: Add documentation to the `doc/` directory. Describe
|
- **Write documentation.**: Add documentation to the `doc/` directory. Describe
|
||||||
the feature and include screenshots, if applicable. Indicate [what editions](documentation/styleguide.md#product-badges)
|
the feature and include screenshots, if applicable. Indicate [what editions](documentation/styleguide/index.md#product-badges)
|
||||||
the feature applies to.
|
the feature applies to.
|
||||||
- **Submit a MR to the `www-gitlab-com` project.**: Add the new feature to the
|
- **Submit a MR to the `www-gitlab-com` project.**: Add the new feature to the
|
||||||
[EE features list](https://about.gitlab.com/features/).
|
[EE features list](https://about.gitlab.com/features/).
|
||||||
|
|
|
||||||
|
|
@ -312,6 +312,7 @@ Implemented using Redis methods [PFADD](https://redis.io/commands/pfadd) and [PF
|
||||||
- `aggregation`: aggregation `:daily` or `:weekly`. The argument defines how we build the Redis
|
- `aggregation`: aggregation `:daily` or `:weekly`. The argument defines how we build the Redis
|
||||||
keys for data storage. For `daily` we keep a key for metric per day of the year, for `weekly` we
|
keys for data storage. For `daily` we keep a key for metric per day of the year, for `weekly` we
|
||||||
keep a key for metric per week of the year.
|
keep a key for metric per week of the year.
|
||||||
|
- `feature_flag`: optional. For details, see our [GitLab internal Feature flags](../feature_flags/) documentation.
|
||||||
|
|
||||||
1. Track event in controller using `RedisTracking` module with `track_redis_hll_event(*controller_actions, name:, feature:, feature_default_enabled: false)`.
|
1. Track event in controller using `RedisTracking` module with `track_redis_hll_event(*controller_actions, name:, feature:, feature_default_enabled: false)`.
|
||||||
|
|
||||||
|
|
@ -402,7 +403,7 @@ Implemented using Redis methods [PFADD](https://redis.io/commands/pfadd) and [PF
|
||||||
| `event` | string | yes | The event name it should be tracked |
|
| `event` | string | yes | The event name it should be tracked |
|
||||||
|
|
||||||
Response
|
Response
|
||||||
w
|
|
||||||
Return 200 if tracking failed for any reason.
|
Return 200 if tracking failed for any reason.
|
||||||
|
|
||||||
- `200` if event was tracked or any errors
|
- `200` if event was tracked or any errors
|
||||||
|
|
@ -454,6 +455,20 @@ Recommendations:
|
||||||
- Use a [feature flag](../../operations/feature_flags.md) to have a control over the impact when
|
- Use a [feature flag](../../operations/feature_flags.md) to have a control over the impact when
|
||||||
adding new metrics.
|
adding new metrics.
|
||||||
|
|
||||||
|
##### Enable/Disable Redis HLL tracking
|
||||||
|
|
||||||
|
Events are tracked behind [feature flags](../feature_flags/index.md) due to concerns for Redis performance and scalability.
|
||||||
|
|
||||||
|
For a full list of events and coresponding feature flags see, [known_events](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/) files.
|
||||||
|
|
||||||
|
To enable or disable tracking for specific event within <https://gitlab.com> or <https://staging.gitlab.com>, run commands such as the following to
|
||||||
|
[enable or disable the corresponding feature](../feature_flags/index.md).
|
||||||
|
|
||||||
|
```shell
|
||||||
|
/chatops run feature set <feature_name> true
|
||||||
|
/chatops run feature set <feature_name> false
|
||||||
|
```
|
||||||
|
|
||||||
##### Known events in usage data payload
|
##### Known events in usage data payload
|
||||||
|
|
||||||
All events added in [`known_events/common.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/common.yml) are automatically added to usage data generation under the `redis_hll_counters` key. This column is stored in [version-app as a JSON](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/db/schema.rb#L209).
|
All events added in [`known_events/common.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events/common.yml) are automatically added to usage data generation under the `redis_hll_counters` key. This column is stored in [version-app as a JSON](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/db/schema.rb#L209).
|
||||||
|
|
|
||||||
|
|
@ -8,51 +8,87 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
||||||
|
|
||||||
Project integrations can be configured and enabled by project administrators. As a GitLab instance
|
Project integrations can be configured and enabled by project administrators. As a GitLab instance
|
||||||
administrator, you can set default configuration parameters for a given integration that all projects
|
administrator, you can set default configuration parameters for a given integration that all projects
|
||||||
can inherit and use. This enables the integration for all projects that are not already using custom
|
can inherit and use, enabling the integration for all projects that are not already using custom
|
||||||
settings.
|
settings.
|
||||||
|
|
||||||
You can update these default settings at any time, changing the settings used for all projects that
|
You can update these default settings at any time, changing the settings used for all projects that
|
||||||
are set to use instance-level defaults. Updating the default settings also enables the integration
|
are set to use instance-level or group-level defaults. Updating the default settings also enables the integration
|
||||||
for all projects that didn't have it already enabled.
|
for all projects that didn't have it already enabled.
|
||||||
|
|
||||||
Only the complete settings for an integration can be inherited. Per-field inheritance is
|
Only the complete settings for an integration can be inherited. Per-field inheritance is [planned](https://gitlab.com/groups/gitlab-org/-/epics/2137).
|
||||||
[planned](https://gitlab.com/groups/gitlab-org/-/epics/2137) as is
|
|
||||||
[group-level management](https://gitlab.com/groups/gitlab-org/-/epics/2543) of integration settings.
|
|
||||||
|
|
||||||
## Manage instance-level default settings for a project integration **(CORE ONLY)**
|
## Manage instance-level default settings for a project integration **(CORE ONLY)**
|
||||||
|
|
||||||
> [Introduced in](https://gitlab.com/groups/gitlab-org/-/epics/2137) GitLab 13.3.
|
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2137) in GitLab 13.3 for project-level integrations.
|
||||||
|
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2543) in GitLab 13.6 for group-level integrations.
|
||||||
|
|
||||||
1. Navigate to **Admin Area > Settings > Integrations**.
|
1. Navigate to **Admin Area > Settings > Integrations**.
|
||||||
1. Select a project integration.
|
1. Select an integration.
|
||||||
1. Enter configuration details and click **Save changes**.
|
1. Enter configuration details and click **Save changes**.
|
||||||
|
|
||||||
CAUTION: **Caution:**
|
CAUTION: **Caution:**
|
||||||
This may affect all or most of the projects on your GitLab instance. Please review the details
|
This may affect all or most of the groups and projects on your GitLab instance. Please review the details
|
||||||
below.
|
below.
|
||||||
|
|
||||||
If this is the first time you are setting up instance-level settings for an integration:
|
If this is the first time you are setting up instance-level settings for an integration:
|
||||||
|
|
||||||
- The integration is enabled for all projects that don't already have this integration configured,
|
- The integration is enabled for all groups and projects that don't already have this integration configured,
|
||||||
if you have the **Enable integration** toggle turned on in the instance-level settings.
|
if you have the **Enable integration** toggle turned on in the instance-level settings.
|
||||||
- Projects that already have the integration configured are not affected, but can choose to use the
|
- Groups and projects that already have the integration configured are not affected, but can choose to use the
|
||||||
inherited settings at any time.
|
inherited settings at any time.
|
||||||
|
|
||||||
When you make further changes to the instance defaults:
|
When you make further changes to the instance defaults:
|
||||||
|
|
||||||
- They are immediately applied to all projects that have the integration set to use default settings.
|
- They are immediately applied to all groups and projects that have the integration set to use default settings.
|
||||||
- They are immediately applied to newer projects, created since you last saved defaults for the
|
- They are immediately applied to newer groups and projects, created since you last saved defaults for the
|
||||||
integration. If your instance-level default setting has the **Enable integration** toggle turned
|
integration. If your instance-level default setting has the **Enable integration** toggle turned
|
||||||
on, the integration is automatically enabled for all such projects.
|
on, the integration is automatically enabled for all such groups and projects.
|
||||||
- Projects with custom settings selected for the integration are not immediately affected and may
|
- Groups and projects with custom settings selected for the integration are not immediately affected and may
|
||||||
choose to use the latest defaults at any time.
|
choose to use the latest defaults at any time.
|
||||||
|
|
||||||
Only the complete settings for an integration can be inherited. Per-field inheritance
|
Only the complete settings for an integration can be inherited. Per-field inheritance
|
||||||
is [planned](https://gitlab.com/groups/gitlab-org/-/epics/2137). This would allow
|
is [planned](https://gitlab.com/groups/gitlab-org/-/epics/2137). This would allow
|
||||||
administrators to update settings inherited by projects without enabling the
|
administrators to update settings inherited by groups and projects without enabling the
|
||||||
integration on all non-configured projects by default.
|
integration on all non-configured groups and projects by default.
|
||||||
|
|
||||||
## Use instance-level default settings for a project integration
|
## Manage group-level default settings for a project integration
|
||||||
|
|
||||||
|
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2543) in GitLab 13.6.
|
||||||
|
|
||||||
|
1. Navigate to the group's **Settings > Integrations**.
|
||||||
|
1. Select an integration.
|
||||||
|
1. Enter configuration details and click **Save changes**.
|
||||||
|
|
||||||
|
CAUTION: **Caution:**
|
||||||
|
This may affect all or most of the subgroups and projects belonging to the group. Please review the details below.
|
||||||
|
|
||||||
|
If this is the first time you are setting up group-level settings for an integration:
|
||||||
|
|
||||||
|
- The integration is enabled for all subgroups and projects belonging to the group that don't already have
|
||||||
|
this integration configured, if you have the **Enable integration** toggle turned on in the group-level
|
||||||
|
settings.
|
||||||
|
- Subgroups and projects that already have the integration configured are not affected, but can choose to use
|
||||||
|
the inherited settings at any time.
|
||||||
|
|
||||||
|
When you make further changes to the group defaults:
|
||||||
|
|
||||||
|
- They are immediately applied to all subgroups and projects belonging to the group that have the integration
|
||||||
|
set to use default settings.
|
||||||
|
- They are immediately applied to newer subgroups and projects, created since you last saved defaults for the
|
||||||
|
integration. If your group-level default setting has the **Enable integration** toggle turned on,
|
||||||
|
the integration is automatically enabled for all such subgroups and projects.
|
||||||
|
|
||||||
|
- Subgroups and projects with custom settings selected for the integration are not immediately affected and
|
||||||
|
may choose to use the latest defaults at any time.
|
||||||
|
|
||||||
|
Only the complete settings for an integration can be inherited. Per-field inheritance
|
||||||
|
is [planned](https://gitlab.com/groups/gitlab-org/-/epics/2137). This would allow
|
||||||
|
administrators to update settings inherited by subgroups and projects without enabling the
|
||||||
|
integration on all non-configured groups and projects by default.
|
||||||
|
|
||||||
|
## Use instance-level or group-level default settings for a project integration
|
||||||
|
|
||||||
|
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2543) in GitLab 13.6 for group-level settings.
|
||||||
|
|
||||||
1. Navigate to **Project > Settings > Integrations**.
|
1. Navigate to **Project > Settings > Integrations**.
|
||||||
1. Choose the integration you want to enable or update.
|
1. Choose the integration you want to enable or update.
|
||||||
|
|
@ -60,9 +96,9 @@ integration on all non-configured projects by default.
|
||||||
1. Ensure the toggle is set to **Enable integration**.
|
1. Ensure the toggle is set to **Enable integration**.
|
||||||
1. Click **Save changes**.
|
1. Click **Save changes**.
|
||||||
|
|
||||||
## Use custom settings for a project integration
|
## Use custom settings for a group or project integration
|
||||||
|
|
||||||
1. Navigate to project's **Settings > Integrations**.
|
1. Navigate to project or group's **Settings > Integrations**.
|
||||||
1. Choose the integration you want to enable or update.
|
1. Choose the integration you want to enable or update.
|
||||||
1. From the drop-down, select **Use custom settings**.
|
1. From the drop-down, select **Use custom settings**.
|
||||||
1. Ensure the toggle is set to **Enable integration** and enter all required settings.
|
1. Ensure the toggle is set to **Enable integration** and enter all required settings.
|
||||||
|
|
|
||||||
|
|
@ -745,6 +745,7 @@ To enable prevent project forking:
|
||||||
- **Audit Events**: View [Audit Events](../../administration/audit_events.md)
|
- **Audit Events**: View [Audit Events](../../administration/audit_events.md)
|
||||||
for the group. **(STARTER ONLY)**
|
for the group. **(STARTER ONLY)**
|
||||||
- **Pipelines quota**: Keep track of the [pipeline quota](../admin_area/settings/continuous_integration.md) for the group.
|
- **Pipelines quota**: Keep track of the [pipeline quota](../admin_area/settings/continuous_integration.md) for the group.
|
||||||
|
- **Integrations**: Configure [integrations](../admin_area/settings/project_integration_management.md) for your group.
|
||||||
|
|
||||||
#### Storage usage quota **(STARTER)**
|
#### Storage usage quota **(STARTER)**
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,10 @@ module Gitlab
|
||||||
pool.with { |redis| yield redis }
|
pool.with { |redis| yield redis }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def version
|
||||||
|
with { |redis| redis.info['redis_version'] }
|
||||||
|
end
|
||||||
|
|
||||||
def pool
|
def pool
|
||||||
@pool ||= ConnectionPool.new(size: pool_size) { ::Redis.new(params) }
|
@pool ||= ConnectionPool.new(size: pool_size) { ::Redis.new(params) }
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -765,7 +765,8 @@ module Gitlab
|
||||||
data = {
|
data = {
|
||||||
action_monthly_active_users_project_repo: Gitlab::UsageDataCounters::TrackUniqueEvents::PUSH_ACTION,
|
action_monthly_active_users_project_repo: Gitlab::UsageDataCounters::TrackUniqueEvents::PUSH_ACTION,
|
||||||
action_monthly_active_users_design_management: Gitlab::UsageDataCounters::TrackUniqueEvents::DESIGN_ACTION,
|
action_monthly_active_users_design_management: Gitlab::UsageDataCounters::TrackUniqueEvents::DESIGN_ACTION,
|
||||||
action_monthly_active_users_wiki_repo: Gitlab::UsageDataCounters::TrackUniqueEvents::WIKI_ACTION
|
action_monthly_active_users_wiki_repo: Gitlab::UsageDataCounters::TrackUniqueEvents::WIKI_ACTION,
|
||||||
|
action_monthly_active_users_git_write: Gitlab::UsageDataCounters::TrackUniqueEvents::GIT_WRITE_ACTION
|
||||||
}
|
}
|
||||||
|
|
||||||
data.each do |key, event|
|
data.each do |key, event|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ module Gitlab
|
||||||
# category: compliance # Group events in categories
|
# category: compliance # Group events in categories
|
||||||
# expiry: 29 # Optional expiration time in days, default value 29 days for daily and 6.weeks for weekly
|
# expiry: 29 # Optional expiration time in days, default value 29 days for daily and 6.weeks for weekly
|
||||||
# aggregation: daily # Aggregation level, keys are stored daily or weekly
|
# aggregation: daily # Aggregation level, keys are stored daily or weekly
|
||||||
|
# feature_flag: # The event feature flag
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -4,114 +4,141 @@
|
||||||
redis_slot: compliance
|
redis_slot: compliance
|
||||||
category: compliance
|
category: compliance
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: track_unique_visits
|
||||||
- name: g_compliance_audit_events
|
- name: g_compliance_audit_events
|
||||||
category: compliance
|
category: compliance
|
||||||
redis_slot: compliance
|
redis_slot: compliance
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: track_unique_visits
|
||||||
- name: i_compliance_audit_events
|
- name: i_compliance_audit_events
|
||||||
category: compliance
|
category: compliance
|
||||||
redis_slot: compliance
|
redis_slot: compliance
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: track_unique_visits
|
||||||
- name: i_compliance_credential_inventory
|
- name: i_compliance_credential_inventory
|
||||||
category: compliance
|
category: compliance
|
||||||
redis_slot: compliance
|
redis_slot: compliance
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: track_unique_visits
|
||||||
- name: a_compliance_audit_events_api
|
- name: a_compliance_audit_events_api
|
||||||
category: compliance
|
category: compliance
|
||||||
redis_slot: compliance
|
redis_slot: compliance
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: usage_data_a_compliance_audit_events_api
|
||||||
# Analytics category
|
# Analytics category
|
||||||
- name: g_analytics_contribution
|
- name: g_analytics_contribution
|
||||||
category: analytics
|
category: analytics
|
||||||
redis_slot: analytics
|
redis_slot: analytics
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: track_unique_visits
|
||||||
- name: g_analytics_insights
|
- name: g_analytics_insights
|
||||||
category: analytics
|
category: analytics
|
||||||
redis_slot: analytics
|
redis_slot: analytics
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: track_unique_visits
|
||||||
- name: g_analytics_issues
|
- name: g_analytics_issues
|
||||||
category: analytics
|
category: analytics
|
||||||
redis_slot: analytics
|
redis_slot: analytics
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: track_unique_visits
|
||||||
- name: g_analytics_productivity
|
- name: g_analytics_productivity
|
||||||
category: analytics
|
category: analytics
|
||||||
redis_slot: analytics
|
redis_slot: analytics
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: track_unique_visits
|
||||||
- name: g_analytics_valuestream
|
- name: g_analytics_valuestream
|
||||||
category: analytics
|
category: analytics
|
||||||
redis_slot: analytics
|
redis_slot: analytics
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: track_unique_visits
|
||||||
- name: p_analytics_pipelines
|
- name: p_analytics_pipelines
|
||||||
category: analytics
|
category: analytics
|
||||||
redis_slot: analytics
|
redis_slot: analytics
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: track_unique_visits
|
||||||
- name: p_analytics_code_reviews
|
- name: p_analytics_code_reviews
|
||||||
category: analytics
|
category: analytics
|
||||||
redis_slot: analytics
|
redis_slot: analytics
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: track_unique_visits
|
||||||
- name: p_analytics_valuestream
|
- name: p_analytics_valuestream
|
||||||
category: analytics
|
category: analytics
|
||||||
redis_slot: analytics
|
redis_slot: analytics
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: track_unique_visits
|
||||||
- name: p_analytics_insights
|
- name: p_analytics_insights
|
||||||
category: analytics
|
category: analytics
|
||||||
redis_slot: analytics
|
redis_slot: analytics
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: track_unique_visits
|
||||||
- name: p_analytics_issues
|
- name: p_analytics_issues
|
||||||
category: analytics
|
category: analytics
|
||||||
redis_slot: analytics
|
redis_slot: analytics
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: track_unique_visits
|
||||||
- name: p_analytics_repo
|
- name: p_analytics_repo
|
||||||
category: analytics
|
category: analytics
|
||||||
redis_slot: analytics
|
redis_slot: analytics
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: track_unique_visits
|
||||||
- name: i_analytics_cohorts
|
- name: i_analytics_cohorts
|
||||||
category: analytics
|
category: analytics
|
||||||
redis_slot: analytics
|
redis_slot: analytics
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: track_unique_visits
|
||||||
- name: i_analytics_dev_ops_score
|
- name: i_analytics_dev_ops_score
|
||||||
category: analytics
|
category: analytics
|
||||||
redis_slot: analytics
|
redis_slot: analytics
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: track_unique_visits
|
||||||
- name: g_analytics_merge_request
|
- name: g_analytics_merge_request
|
||||||
category: analytics
|
category: analytics
|
||||||
redis_slot: analytics
|
redis_slot: analytics
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: track_unique_visits
|
||||||
- name: p_analytics_merge_request
|
- name: p_analytics_merge_request
|
||||||
category: analytics
|
category: analytics
|
||||||
redis_slot: analytics
|
redis_slot: analytics
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: track_unique_visits
|
||||||
- name: i_analytics_instance_statistics
|
- name: i_analytics_instance_statistics
|
||||||
category: analytics
|
category: analytics
|
||||||
redis_slot: analytics
|
redis_slot: analytics
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: track_unique_visits
|
||||||
- name: g_edit_by_web_ide
|
- name: g_edit_by_web_ide
|
||||||
category: ide_edit
|
category: ide_edit
|
||||||
redis_slot: edit
|
redis_slot: edit
|
||||||
expiry: 29
|
expiry: 29
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_editor_edit_actions
|
||||||
- name: g_edit_by_sfe
|
- name: g_edit_by_sfe
|
||||||
category: ide_edit
|
category: ide_edit
|
||||||
redis_slot: edit
|
redis_slot: edit
|
||||||
expiry: 29
|
expiry: 29
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_editor_edit_actions
|
||||||
- name: g_edit_by_snippet_ide
|
- name: g_edit_by_snippet_ide
|
||||||
category: ide_edit
|
category: ide_edit
|
||||||
redis_slot: edit
|
redis_slot: edit
|
||||||
expiry: 29
|
expiry: 29
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_editor_edit_actions
|
||||||
- name: i_search_total
|
- name: i_search_total
|
||||||
category: search
|
category: search
|
||||||
redis_slot: search
|
redis_slot: search
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: search_track_unique_users
|
||||||
- name: i_search_advanced
|
- name: i_search_advanced
|
||||||
category: search
|
category: search
|
||||||
redis_slot: search
|
redis_slot: search
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: search_track_unique_users
|
||||||
- name: i_search_paid
|
- name: i_search_paid
|
||||||
category: search
|
category: search
|
||||||
redis_slot: search
|
redis_slot: search
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: search_track_unique_users
|
||||||
- name: wiki_action
|
- name: wiki_action
|
||||||
category: source_code
|
category: source_code
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
|
@ -121,6 +148,9 @@
|
||||||
- name: project_action
|
- name: project_action
|
||||||
category: source_code
|
category: source_code
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
- name: git_write_action
|
||||||
|
category: source_code
|
||||||
|
aggregation: daily
|
||||||
- name: merge_request_action
|
- name: merge_request_action
|
||||||
category: source_code
|
category: source_code
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
|
@ -133,194 +163,242 @@
|
||||||
redis_slot: incident_management
|
redis_slot: incident_management
|
||||||
category: incident_management
|
category: incident_management
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: usage_data_incident_management_alert_status_changed
|
||||||
- name: incident_management_alert_assigned
|
- name: incident_management_alert_assigned
|
||||||
redis_slot: incident_management
|
redis_slot: incident_management
|
||||||
category: incident_management
|
category: incident_management
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: usage_data_incident_management_alert_assigned
|
||||||
- name: incident_management_alert_todo
|
- name: incident_management_alert_todo
|
||||||
redis_slot: incident_management
|
redis_slot: incident_management
|
||||||
category: incident_management
|
category: incident_management
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: usage_data_incident_management_alert_todo
|
||||||
- name: incident_management_incident_created
|
- name: incident_management_incident_created
|
||||||
redis_slot: incident_management
|
redis_slot: incident_management
|
||||||
category: incident_management
|
category: incident_management
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: usage_data_incident_management_incident_created
|
||||||
- name: incident_management_incident_reopened
|
- name: incident_management_incident_reopened
|
||||||
redis_slot: incident_management
|
redis_slot: incident_management
|
||||||
category: incident_management
|
category: incident_management
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: usage_data_incident_management_incident_reopened
|
||||||
- name: incident_management_incident_closed
|
- name: incident_management_incident_closed
|
||||||
redis_slot: incident_management
|
redis_slot: incident_management
|
||||||
category: incident_management
|
category: incident_management
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: usage_data_incident_management_incident_closed
|
||||||
- name: incident_management_incident_assigned
|
- name: incident_management_incident_assigned
|
||||||
redis_slot: incident_management
|
redis_slot: incident_management
|
||||||
category: incident_management
|
category: incident_management
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: usage_data_incident_management_incident_assigned
|
||||||
- name: incident_management_incident_todo
|
- name: incident_management_incident_todo
|
||||||
redis_slot: incident_management
|
redis_slot: incident_management
|
||||||
category: incident_management
|
category: incident_management
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: usage_data_incident_management_incident_todo
|
||||||
- name: incident_management_incident_comment
|
- name: incident_management_incident_comment
|
||||||
redis_slot: incident_management
|
redis_slot: incident_management
|
||||||
category: incident_management
|
category: incident_management
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: usage_data_incident_management_incident_comment
|
||||||
- name: incident_management_incident_zoom_meeting
|
- name: incident_management_incident_zoom_meeting
|
||||||
redis_slot: incident_management
|
redis_slot: incident_management
|
||||||
category: incident_management
|
category: incident_management
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: usage_data_incident_management_incident_zoom_meeting
|
||||||
- name: incident_management_incident_published
|
- name: incident_management_incident_published
|
||||||
redis_slot: incident_management
|
redis_slot: incident_management
|
||||||
category: incident_management
|
category: incident_management
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: usage_data_incident_management_incident_published
|
||||||
- name: incident_management_incident_relate
|
- name: incident_management_incident_relate
|
||||||
redis_slot: incident_management
|
redis_slot: incident_management
|
||||||
category: incident_management
|
category: incident_management
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: usage_data_incident_management_incident_relate
|
||||||
- name: incident_management_incident_unrelate
|
- name: incident_management_incident_unrelate
|
||||||
redis_slot: incident_management
|
redis_slot: incident_management
|
||||||
category: incident_management
|
category: incident_management
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: usage_data_incident_management_incident_unrelate
|
||||||
- name: incident_management_incident_change_confidential
|
- name: incident_management_incident_change_confidential
|
||||||
redis_slot: incident_management
|
redis_slot: incident_management
|
||||||
category: incident_management
|
category: incident_management
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: usage_data_incident_management_incident_change_confidential
|
||||||
# Testing category
|
# Testing category
|
||||||
- name: i_testing_test_case_parsed
|
- name: i_testing_test_case_parsed
|
||||||
category: testing
|
category: testing
|
||||||
redis_slot: testing
|
redis_slot: testing
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: usage_data_i_testing_test_case_parsed
|
||||||
# Project Management group
|
# Project Management group
|
||||||
- name: g_project_management_issue_title_changed
|
- name: g_project_management_issue_title_changed
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_description_changed
|
- name: g_project_management_issue_description_changed
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_assignee_changed
|
- name: g_project_management_issue_assignee_changed
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_made_confidential
|
- name: g_project_management_issue_made_confidential
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_made_visible
|
- name: g_project_management_issue_made_visible
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_created
|
- name: g_project_management_issue_created
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_closed
|
- name: g_project_management_issue_closed
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_reopened
|
- name: g_project_management_issue_reopened
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_label_changed
|
- name: g_project_management_issue_label_changed
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_milestone_changed
|
- name: g_project_management_issue_milestone_changed
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_iteration_changed
|
- name: g_project_management_issue_iteration_changed
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_weight_changed
|
- name: g_project_management_issue_weight_changed
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_cross_referenced
|
- name: g_project_management_issue_cross_referenced
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_moved
|
- name: g_project_management_issue_moved
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_related
|
- name: g_project_management_issue_related
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_unrelated
|
- name: g_project_management_issue_unrelated
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_marked_as_duplicate
|
- name: g_project_management_issue_marked_as_duplicate
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_locked
|
- name: g_project_management_issue_locked
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_unlocked
|
- name: g_project_management_issue_unlocked
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_added_to_epic
|
- name: g_project_management_issue_added_to_epic
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_removed_from_epic
|
- name: g_project_management_issue_removed_from_epic
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_changed_epic
|
- name: g_project_management_issue_changed_epic
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_designs_added
|
- name: g_project_management_issue_designs_added
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_designs_modified
|
- name: g_project_management_issue_designs_modified
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_designs_removed
|
- name: g_project_management_issue_designs_removed
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_due_date_changed
|
- name: g_project_management_issue_due_date_changed
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_time_estimate_changed
|
- name: g_project_management_issue_time_estimate_changed
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_time_spent_changed
|
- name: g_project_management_issue_time_spent_changed
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_comment_added
|
- name: g_project_management_issue_comment_added
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_comment_edited
|
- name: g_project_management_issue_comment_edited
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_comment_removed
|
- name: g_project_management_issue_comment_removed
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
- name: g_project_management_issue_health_status_changed
|
- name: g_project_management_issue_health_status_changed
|
||||||
category: issues_edit
|
category: issues_edit
|
||||||
redis_slot: project_management
|
redis_slot: project_management
|
||||||
aggregation: daily
|
aggregation: daily
|
||||||
|
feature_flag: track_issue_activity_actions
|
||||||
# Secrets Management
|
# Secrets Management
|
||||||
- name: i_ci_secrets_management_vault_build_created
|
- name: i_ci_secrets_management_vault_build_created
|
||||||
category: ci_secrets_management
|
category: ci_secrets_management
|
||||||
redis_slot: ci_secrets_management
|
redis_slot: ci_secrets_management
|
||||||
aggregation: weekly
|
aggregation: weekly
|
||||||
|
feature_flag: usage_data_i_ci_secrets_management_vault_build_created
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@ module Gitlab
|
||||||
PUSH_ACTION = :project_action
|
PUSH_ACTION = :project_action
|
||||||
MERGE_REQUEST_ACTION = :merge_request_action
|
MERGE_REQUEST_ACTION = :merge_request_action
|
||||||
|
|
||||||
|
GIT_WRITE_ACTIONS = [WIKI_ACTION, DESIGN_ACTION, PUSH_ACTION].freeze
|
||||||
|
GIT_WRITE_ACTION = :git_write_action
|
||||||
|
|
||||||
ACTION_TRANSFORMATIONS = HashWithIndifferentAccess.new({
|
ACTION_TRANSFORMATIONS = HashWithIndifferentAccess.new({
|
||||||
wiki: {
|
wiki: {
|
||||||
created: WIKI_ACTION,
|
created: WIKI_ACTION,
|
||||||
|
|
@ -41,6 +44,8 @@ module Gitlab
|
||||||
return unless Gitlab::UsageDataCounters::HLLRedisCounter.known_event?(transformed_action.to_s)
|
return unless Gitlab::UsageDataCounters::HLLRedisCounter.known_event?(transformed_action.to_s)
|
||||||
|
|
||||||
Gitlab::UsageDataCounters::HLLRedisCounter.track_event(author_id, transformed_action.to_s, time)
|
Gitlab::UsageDataCounters::HLLRedisCounter.track_event(author_id, transformed_action.to_s, time)
|
||||||
|
|
||||||
|
track_git_write_action(author_id, transformed_action, time)
|
||||||
end
|
end
|
||||||
|
|
||||||
def count_unique_events(event_action:, date_from:, date_to:)
|
def count_unique_events(event_action:, date_from:, date_to:)
|
||||||
|
|
@ -64,6 +69,12 @@ module Gitlab
|
||||||
def valid_action?(action)
|
def valid_action?(action)
|
||||||
Event.actions.key?(action)
|
Event.actions.key?(action)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def track_git_write_action(author_id, transformed_action, time)
|
||||||
|
return unless GIT_WRITE_ACTIONS.include?(transformed_action)
|
||||||
|
|
||||||
|
Gitlab::UsageDataCounters::HLLRedisCounter.track_event(author_id, GIT_WRITE_ACTION, time)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -11208,6 +11208,11 @@ msgstr ""
|
||||||
msgid "Failed"
|
msgid "Failed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Failed %d time in the last 14 days"
|
||||||
|
msgid_plural "Failed %d times in the last 14 days"
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
msgid "Failed Jobs"
|
msgid "Failed Jobs"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -22186,6 +22191,9 @@ msgstr ""
|
||||||
msgid "Redirect to SAML provider to test configuration"
|
msgid "Redirect to SAML provider to test configuration"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Redis"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Reduce project visibility"
|
msgid "Reduce project visibility"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -22688,6 +22696,15 @@ msgstr ""
|
||||||
msgid "Reports|%{combinedString} and %{resolvedString}"
|
msgid "Reports|%{combinedString} and %{resolvedString}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Reports|%{recentlyFailed} out of %{failed} failed test has failed more than once in the last 14 days"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Reports|%{recentlyFailed} out of %{failed} failed tests has failed more than once in the last 14 days"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Reports|%{recentlyFailed} out of %{failed} failed tests have failed more than once in the last 14 days"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Reports|Accessibility scanning detected %d issue for the source branch only"
|
msgid "Reports|Accessibility scanning detected %d issue for the source branch only"
|
||||||
msgid_plural "Reports|Accessibility scanning detected %d issues for the source branch only"
|
msgid_plural "Reports|Accessibility scanning detected %d issues for the source branch only"
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
|
|
@ -31188,6 +31205,9 @@ msgstr ""
|
||||||
msgid "Your GPG keys (%{count})"
|
msgid "Your GPG keys (%{count})"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Your GitLab account request has been approved!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Your GitLab group"
|
msgid "Your GitLab group"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -31386,6 +31406,9 @@ msgstr ""
|
||||||
msgid "Your search didn't match any commits. Try a different query."
|
msgid "Your search didn't match any commits. Try a different query."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Your sign-in page is %{url}."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Your subscription expired!"
|
msgid "Your subscription expired!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -31395,6 +31418,9 @@ msgstr ""
|
||||||
msgid "Your subscription will expire in %{remaining_days}."
|
msgid "Your subscription will expire in %{remaining_days}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Your username is %{username}."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Zoom meeting added"
|
msgid "Zoom meeting added"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,20 @@ require 'spec_helper'
|
||||||
|
|
||||||
RSpec.describe Admin::DashboardController do
|
RSpec.describe Admin::DashboardController do
|
||||||
describe '#index' do
|
describe '#index' do
|
||||||
|
before do
|
||||||
|
sign_in(create(:admin))
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'retrieves Redis versions' do
|
||||||
|
get :index
|
||||||
|
|
||||||
|
expect(assigns[:redis_versions].length).to eq(1)
|
||||||
|
end
|
||||||
|
|
||||||
context 'with pending_delete projects' do
|
context 'with pending_delete projects' do
|
||||||
render_views
|
render_views
|
||||||
|
|
||||||
it 'does not retrieve projects that are pending deletion' do
|
it 'does not retrieve projects that are pending deletion' do
|
||||||
sign_in(create(:admin))
|
|
||||||
|
|
||||||
project = create(:project)
|
project = create(:project)
|
||||||
pending_delete_project = create(:project, pending_delete: true)
|
pending_delete_project = create(:project, pending_delete: true)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,11 @@ RSpec.describe Admin::UsersController do
|
||||||
expect(user).to be_active
|
expect(user).to be_active
|
||||||
expect(flash[:notice]).to eq('Successfully approved')
|
expect(flash[:notice]).to eq('Successfully approved')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'emails the user on approval' do
|
||||||
|
expect(DeviseMailer).to receive(:user_admin_approval).with(user).and_call_original
|
||||||
|
expect { subject }.to have_enqueued_mail(DeviseMailer, :user_admin_approval)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when unsuccessful' do
|
context 'when unsuccessful' do
|
||||||
|
|
@ -133,6 +138,10 @@ RSpec.describe Admin::UsersController do
|
||||||
user.reload
|
user.reload
|
||||||
expect(user).not_to be_active
|
expect(user).not_to be_active
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'does not email the pending user' do
|
||||||
|
expect { subject }.not_to have_enqueued_mail(DeviseMailer, :user_admin_approval)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import { getStoreConfig } from '~/reports/store';
|
||||||
import { failedReport } from '../mock_data/mock_data';
|
import { failedReport } from '../mock_data/mock_data';
|
||||||
import successTestReports from '../mock_data/no_failures_report.json';
|
import successTestReports from '../mock_data/no_failures_report.json';
|
||||||
import newFailedTestReports from '../mock_data/new_failures_report.json';
|
import newFailedTestReports from '../mock_data/new_failures_report.json';
|
||||||
|
import recentFailuresTestReports from '../mock_data/recent_failures_report.json';
|
||||||
import newErrorsTestReports from '../mock_data/new_errors_report.json';
|
import newErrorsTestReports from '../mock_data/new_errors_report.json';
|
||||||
import mixedResultsTestReports from '../mock_data/new_and_fixed_failures_report.json';
|
import mixedResultsTestReports from '../mock_data/new_and_fixed_failures_report.json';
|
||||||
import resolvedFailures from '../mock_data/resolved_failures.json';
|
import resolvedFailures from '../mock_data/resolved_failures.json';
|
||||||
|
|
@ -21,7 +22,7 @@ describe('Grouped test reports app', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
let mockStore;
|
let mockStore;
|
||||||
|
|
||||||
const mountComponent = ({ props = { pipelinePath } } = {}) => {
|
const mountComponent = ({ props = { pipelinePath }, testFailureHistory = false } = {}) => {
|
||||||
wrapper = mount(Component, {
|
wrapper = mount(Component, {
|
||||||
store: mockStore,
|
store: mockStore,
|
||||||
localVue,
|
localVue,
|
||||||
|
|
@ -30,6 +31,11 @@ describe('Grouped test reports app', () => {
|
||||||
pipelinePath,
|
pipelinePath,
|
||||||
...props,
|
...props,
|
||||||
},
|
},
|
||||||
|
provide: {
|
||||||
|
glFeatures: {
|
||||||
|
testFailureHistory,
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -234,6 +240,77 @@ describe('Grouped test reports app', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('recent failures counts', () => {
|
||||||
|
describe('with recent failures counts', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
setReports(recentFailuresTestReports);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with feature flag enabled', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
mountComponent({ testFailureHistory: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders the recently failed tests summary', () => {
|
||||||
|
expect(findHeader().text()).toContain(
|
||||||
|
'2 out of 3 failed tests have failed more than once in the last 14 days',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders the recently failed count on the test suite', () => {
|
||||||
|
expect(findSummaryDescription().text()).toContain(
|
||||||
|
'1 out of 2 failed tests has failed more than once in the last 14 days',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders the recent failures count on the test case', () => {
|
||||||
|
expect(findIssueDescription().text()).toContain('Failed 8 times in the last 14 days');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with feature flag disabled', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
mountComponent({ testFailureHistory: false });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not render the recently failed tests summary', () => {
|
||||||
|
expect(findHeader().text()).not.toContain('failed more than once in the last 14 days');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not render the recently failed count on the test suite', () => {
|
||||||
|
expect(findSummaryDescription().text()).not.toContain(
|
||||||
|
'failed more than once in the last 14 days',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders the recent failures count on the test case', () => {
|
||||||
|
expect(findIssueDescription().text()).not.toContain('in the last 14 days');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('without recent failures counts', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
setReports(mixedResultsTestReports);
|
||||||
|
mountComponent();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not render the recently failed tests summary', () => {
|
||||||
|
expect(findHeader().text()).not.toContain('failed more than once in the last 14 days');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not render the recently failed count on the test suite', () => {
|
||||||
|
expect(findSummaryDescription().text()).not.toContain(
|
||||||
|
'failed more than once in the last 14 days',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not render the recent failures count on the test case', () => {
|
||||||
|
expect(findIssueDescription().text()).not.toContain('in the last 14 days');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('with a report that failed to load', () => {
|
describe('with a report that failed to load', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
setReports(failedReport);
|
setReports(failedReport);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
{
|
||||||
|
"summary": { "total": 11, "resolved": 0, "errored": 0, "failed": 3, "recentlyFailed": 2 },
|
||||||
|
"suites": [
|
||||||
|
{
|
||||||
|
"name": "rspec:pg",
|
||||||
|
"summary": { "total": 8, "resolved": 0, "errored": 0, "failed": 2, "recentlyFailed": 1 },
|
||||||
|
"new_failures": [
|
||||||
|
{
|
||||||
|
"result": "failure",
|
||||||
|
"name": "Test#sum when a is 1 and b is 2 returns summary",
|
||||||
|
"execution_time": 0.009411,
|
||||||
|
"system_output": "Failure/Error: is_expected.to eq(3)\n\n expected: 3\n got: -1\n\n (compared using ==)\n./spec/test_spec.rb:12:in `block (4 levels) in <top (required)>'",
|
||||||
|
"recent_failures": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"result": "failure",
|
||||||
|
"name": "Test#sum when a is 100 and b is 200 returns summary",
|
||||||
|
"execution_time": 0.000162,
|
||||||
|
"system_output": "Failure/Error: is_expected.to eq(300)\n\n expected: 300\n got: -100\n\n (compared using ==)\n./spec/test_spec.rb:21:in `block (4 levels) in <top (required)>'"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"resolved_failures": [],
|
||||||
|
"existing_failures": [],
|
||||||
|
"new_errors": [],
|
||||||
|
"resolved_errors": [],
|
||||||
|
"existing_errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "java ant",
|
||||||
|
"summary": { "total": 3, "resolved": 0, "errored": 0, "failed": 1, "recentlyFailed": 1 },
|
||||||
|
"new_failures": [
|
||||||
|
{
|
||||||
|
"result": "failure",
|
||||||
|
"name": "Test#sum when a is 100 and b is 200 returns summary",
|
||||||
|
"execution_time": 0.000562,
|
||||||
|
"recent_failures": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"resolved_failures": [],
|
||||||
|
"existing_failures": [],
|
||||||
|
"new_errors": [],
|
||||||
|
"resolved_errors": [],
|
||||||
|
"existing_errors": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -46,6 +46,7 @@ describe('Reports Store Mutations', () => {
|
||||||
name: 'StringHelper#concatenate when a is git and b is lab returns summary',
|
name: 'StringHelper#concatenate when a is git and b is lab returns summary',
|
||||||
execution_time: 0.0092435,
|
execution_time: 0.0092435,
|
||||||
system_output: "Failure/Error: is_expected.to eq('gitlab')",
|
system_output: "Failure/Error: is_expected.to eq('gitlab')",
|
||||||
|
recent_failures: 4,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
resolved_failures: [
|
resolved_failures: [
|
||||||
|
|
@ -82,6 +83,7 @@ describe('Reports Store Mutations', () => {
|
||||||
expect(stateCopy.summary.total).toEqual(mockedResponse.summary.total);
|
expect(stateCopy.summary.total).toEqual(mockedResponse.summary.total);
|
||||||
expect(stateCopy.summary.resolved).toEqual(mockedResponse.summary.resolved);
|
expect(stateCopy.summary.resolved).toEqual(mockedResponse.summary.resolved);
|
||||||
expect(stateCopy.summary.failed).toEqual(mockedResponse.summary.failed);
|
expect(stateCopy.summary.failed).toEqual(mockedResponse.summary.failed);
|
||||||
|
expect(stateCopy.summary.recentlyFailed).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set reports', () => {
|
it('should set reports', () => {
|
||||||
|
|
|
||||||
|
|
@ -168,6 +168,54 @@ describe('Reports store utils', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('recentFailuresTextBuilder', () => {
|
||||||
|
it.each`
|
||||||
|
recentlyFailed | failed | expected
|
||||||
|
${0} | ${1} | ${''}
|
||||||
|
${1} | ${1} | ${'1 out of 1 failed test has failed more than once in the last 14 days'}
|
||||||
|
${1} | ${2} | ${'1 out of 2 failed tests has failed more than once in the last 14 days'}
|
||||||
|
${2} | ${3} | ${'2 out of 3 failed tests have failed more than once in the last 14 days'}
|
||||||
|
`(
|
||||||
|
'should render summary for $recentlyFailed out of $failed failures',
|
||||||
|
({ recentlyFailed, failed, expected }) => {
|
||||||
|
const result = utils.recentFailuresTextBuilder({ recentlyFailed, failed });
|
||||||
|
|
||||||
|
expect(result).toBe(expected);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('countRecentlyFailedTests', () => {
|
||||||
|
it('counts tests with more than one recent failure in a report', () => {
|
||||||
|
const report = {
|
||||||
|
new_failures: [{ recent_failures: 2 }],
|
||||||
|
existing_failures: [{ recent_failures: 1 }],
|
||||||
|
resolved_failures: [{ recent_failures: 20 }, { recent_failures: 5 }],
|
||||||
|
};
|
||||||
|
const result = utils.countRecentlyFailedTests(report);
|
||||||
|
|
||||||
|
expect(result).toBe(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('counts tests with more than one recent failure in an array of reports', () => {
|
||||||
|
const reports = [
|
||||||
|
{
|
||||||
|
new_failures: [{ recent_failures: 2 }],
|
||||||
|
existing_failures: [{ recent_failures: 20 }, { recent_failures: 5 }],
|
||||||
|
resolved_failures: [{ recent_failures: 2 }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new_failures: [{ recent_failures: 8 }, { recent_failures: 14 }],
|
||||||
|
existing_failures: [{ recent_failures: 1 }],
|
||||||
|
resolved_failures: [{ recent_failures: 7 }, { recent_failures: 5 }],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const result = utils.countRecentlyFailedTests(reports);
|
||||||
|
|
||||||
|
expect(result).toBe(8);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('statusIcon', () => {
|
describe('statusIcon', () => {
|
||||||
describe('with failed status', () => {
|
describe('with failed status', () => {
|
||||||
it('returns ICON_WARNING', () => {
|
it('returns ICON_WARNING', () => {
|
||||||
|
|
|
||||||
|
|
@ -243,6 +243,7 @@ ci_pipelines:
|
||||||
- vulnerability_findings
|
- vulnerability_findings
|
||||||
- pipeline_config
|
- pipeline_config
|
||||||
- security_scans
|
- security_scans
|
||||||
|
- security_findings
|
||||||
- daily_build_group_report_results
|
- daily_build_group_report_results
|
||||||
- latest_builds
|
- latest_builds
|
||||||
- daily_report_results
|
- daily_report_results
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,12 @@ RSpec.describe Gitlab::Redis::Wrapper do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '.version' do
|
||||||
|
it 'returns a version' do
|
||||||
|
expect(described_class.version).to be_present
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '.instrumentation_class' do
|
describe '.instrumentation_class' do
|
||||||
it 'raises a NotImplementedError' do
|
it 'raises a NotImplementedError' do
|
||||||
expect(described_class).to receive(:instrumentation_class).and_call_original
|
expect(described_class).to receive(:instrumentation_class).and_call_original
|
||||||
|
|
|
||||||
|
|
@ -1085,6 +1085,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
||||||
let(:user1) { build(:user, id: 1) }
|
let(:user1) { build(:user, id: 1) }
|
||||||
let(:user2) { build(:user, id: 2) }
|
let(:user2) { build(:user, id: 2) }
|
||||||
let(:user3) { build(:user, id: 3) }
|
let(:user3) { build(:user, id: 3) }
|
||||||
|
let(:user4) { build(:user, id: 4) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
counter = Gitlab::UsageDataCounters::TrackUniqueEvents
|
counter = Gitlab::UsageDataCounters::TrackUniqueEvents
|
||||||
|
|
@ -1099,6 +1100,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
||||||
counter.track_event(event_action: :pushed, event_target: project, author_id: 4, time: time - 3.days)
|
counter.track_event(event_action: :pushed, event_target: project, author_id: 4, time: time - 3.days)
|
||||||
counter.track_event(event_action: :created, event_target: wiki, author_id: 3)
|
counter.track_event(event_action: :created, event_target: wiki, author_id: 3)
|
||||||
counter.track_event(event_action: :created, event_target: design, author_id: 3)
|
counter.track_event(event_action: :created, event_target: design, author_id: 3)
|
||||||
|
counter.track_event(event_action: :created, event_target: design, author_id: 4)
|
||||||
|
|
||||||
counter = Gitlab::UsageDataCounters::EditorUniqueCounter
|
counter = Gitlab::UsageDataCounters::EditorUniqueCounter
|
||||||
|
|
||||||
|
|
@ -1118,9 +1120,10 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
|
||||||
it 'returns the distinct count of user actions within the specified time period' do
|
it 'returns the distinct count of user actions within the specified time period' do
|
||||||
expect(described_class.action_monthly_active_users(time_period)).to eq(
|
expect(described_class.action_monthly_active_users(time_period)).to eq(
|
||||||
{
|
{
|
||||||
action_monthly_active_users_design_management: 1,
|
action_monthly_active_users_design_management: 2,
|
||||||
action_monthly_active_users_project_repo: 3,
|
action_monthly_active_users_project_repo: 3,
|
||||||
action_monthly_active_users_wiki_repo: 1,
|
action_monthly_active_users_wiki_repo: 1,
|
||||||
|
action_monthly_active_users_git_write: 4,
|
||||||
action_monthly_active_users_web_ide_edit: 2,
|
action_monthly_active_users_web_ide_edit: 2,
|
||||||
action_monthly_active_users_sfe_edit: 2,
|
action_monthly_active_users_sfe_edit: 2,
|
||||||
action_monthly_active_users_snippet_editor_edit: 2,
|
action_monthly_active_users_snippet_editor_edit: 2,
|
||||||
|
|
|
||||||
|
|
@ -64,4 +64,34 @@ RSpec.describe DeviseMailer do
|
||||||
is_expected.to have_body_text /#{Gitlab.config.gitlab.url}/
|
is_expected.to have_body_text /#{Gitlab.config.gitlab.url}/
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#user_admin_approval' do
|
||||||
|
subject { described_class.user_admin_approval(user) }
|
||||||
|
|
||||||
|
let_it_be(:user) { create(:user) }
|
||||||
|
|
||||||
|
it_behaves_like 'an email sent from GitLab'
|
||||||
|
it_behaves_like 'it should not have Gmail Actions links'
|
||||||
|
it_behaves_like 'a user cannot unsubscribe through footer link'
|
||||||
|
|
||||||
|
it 'is sent to the user' do
|
||||||
|
is_expected.to deliver_to user.email
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'has the correct subject' do
|
||||||
|
is_expected.to have_subject 'Welcome to GitLab!'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'greets the user' do
|
||||||
|
is_expected.to have_body_text /Hi #{user.name}!/
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'includes the correct content' do
|
||||||
|
is_expected.to have_body_text /Your GitLab account request has been approved!/
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'includes a link to GitLab' do
|
||||||
|
is_expected.to have_link(Gitlab.config.gitlab.url)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,11 @@ RSpec.describe Users::ApproveService do
|
||||||
expect(user.reload).to be_active
|
expect(user.reload).to be_active
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'emails the user on approval' do
|
||||||
|
expect(DeviseMailer).to receive(:user_admin_approval).with(user).and_call_original
|
||||||
|
expect { subject }.to have_enqueued_mail(DeviseMailer, :user_admin_approval)
|
||||||
|
end
|
||||||
|
|
||||||
context 'email confirmation status' do
|
context 'email confirmation status' do
|
||||||
context 'user is unconfirmed' do
|
context 'user is unconfirmed' do
|
||||||
let(:user) { create(:user, :blocked_pending_approval, :unconfirmed) }
|
let(:user) { create(:user, :blocked_pending_approval, :unconfirmed) }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue