Commit 2dcdcf69 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents ee7f7597 33686d04
......@@ -126,6 +126,8 @@
.frontend-dependency-patterns: &frontend-dependency-patterns
- "{package.json,yarn.lock}"
- "config/webpack.config.js"
- "config/helpers/*.js"
.frontend-patterns: &frontend-patterns
- "{package.json,yarn.lock}"
......
b3a047a5626ff654ad998dd7a94c6a51624f54b4
2b34fc78dfb8e7f55f7f2fc30602381b43c54fc3
......@@ -118,12 +118,10 @@ export default {
};
</script>
<template>
<div class="gl-mt-5">
<gl-search-box-by-type
:value="searchTerm"
:debounce="$options.TYPING_DELAY"
:placeholder="__('Search settings')"
@input="search"
/>
</div>
<gl-search-box-by-type
:value="searchTerm"
:debounce="$options.TYPING_DELAY"
:placeholder="__('Search settings')"
@input="search"
/>
</template>
- container_class = local_assigns.fetch(:container_class, 'gl-mt-5')
- if Feature.enabled?(:search_settings_in_page, @project, default_enabled: false)
.js-search-settings-app
%div{ class: container_class }
.js-search-settings-app
%input.gl-form-input.form-control{ type: "text", placeholder: _("Search settings"), aria_label: _("Search settings"), disabled: true }
......@@ -8,7 +8,9 @@ const log = (msg, ...rest) => console.log(`IncrementalWebpackCompiler: ${msg}`,
const TIMEOUT = 5000;
class NoopCompiler {
enabled = false;
constructor() {
this.enabled = false;
}
filterEntryPoints(entryPoints) {
return entryPoints;
......@@ -20,8 +22,6 @@ class NoopCompiler {
}
class IncrementalWebpackCompiler extends NoopCompiler {
enabled = true;
constructor(historyFilePath) {
super();
this.history = {};
......@@ -33,6 +33,7 @@ class IncrementalWebpackCompiler extends NoopCompiler {
]);
this.historyFilePath = historyFilePath;
this.loadFromHistory();
this.enabled = true;
}
filterEntryPoints(entrypoints) {
......
......@@ -64,9 +64,10 @@ Repository storage paths:
GitLab Shell path: /opt/gitlab/embedded/service/gitlab-shell
```
## Show GitLab license information **(STARTER ONLY)**
## Show GitLab license information **(PREMIUM SELF)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20501) in GitLab Starter 12.6.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20501) in GitLab 12.6.
> - [Moved](../../subscriptions/bronze_starter.md) to GitLab Premium in 13.9.
This command shows information about your [GitLab license](../../user/admin_area/license.md) and
how many seats are used. It is only available on GitLab Enterprise
......
......@@ -1983,7 +1983,7 @@ work.
</a>
</div>
## Configure Advanced Search **(STARTER ONLY)**
## Configure Advanced Search **(PREMIUM SELF)**
You can leverage Elasticsearch and [enable Advanced Search](../../integration/elasticsearch.md)
for faster, more advanced code search across your entire GitLab instance.
......
......@@ -47,7 +47,7 @@ You can also optionally configure GitLab to use an [external PostgreSQL service]
or an [external object storage service](../object_storage.md) for added
performance and reliability at an increased complexity cost.
## Configure Advanced Search **(STARTER ONLY)**
## Configure Advanced Search **(PREMIUM SELF)**
You can leverage Elasticsearch and [enable Advanced Search](../../integration/elasticsearch.md)
for faster, more advanced code search across your entire GitLab instance.
......
......@@ -1983,7 +1983,7 @@ work.
</a>
</div>
## Configure Advanced Search **(STARTER ONLY)**
## Configure Advanced Search **(PREMIUM SELF)**
You can leverage Elasticsearch and [enable Advanced Search](../../integration/elasticsearch.md)
for faster, more advanced code search across your entire GitLab instance.
......
......@@ -932,7 +932,7 @@ functioning backups is encountered.
</a>
</div>
## Configure Advanced Search **(STARTER ONLY)**
## Configure Advanced Search **(PREMIUM SELF)**
You can leverage Elasticsearch and [enable Advanced Search](../../integration/elasticsearch.md)
for faster, more advanced code search across your entire GitLab instance.
......
......@@ -1676,7 +1676,7 @@ work.
</a>
</div>
## Configure Advanced Search **(STARTER ONLY)**
## Configure Advanced Search **(PREMIUM SELF)**
You can leverage Elasticsearch and [enable Advanced Search](../../integration/elasticsearch.md)
for faster, more advanced code search across your entire GitLab instance.
......
......@@ -1983,7 +1983,7 @@ work.
</a>
</div>
## Configure Advanced Search **(STARTER ONLY)**
## Configure Advanced Search **(PREMIUM SELF)**
You can leverage Elasticsearch and [enable Advanced Search](../../integration/elasticsearch.md)
for faster, more advanced code search across your entire GitLab instance.
......
......@@ -1675,7 +1675,7 @@ work.
</a>
</div>
## Configure Advanced Search **(STARTER ONLY)**
## Configure Advanced Search **(PREMIUM SELF)**
You can leverage Elasticsearch and [enable Advanced Search](../../integration/elasticsearch.md)
for faster, more advanced code search across your entire GitLab instance.
......
......@@ -102,7 +102,7 @@ this can be an optimal solution if you don't have strict requirements.
[Automated backups](../../raketasks/backup_restore.md#configuring-cron-to-make-daily-backups)
is the least complex to setup. This provides a point-in-time recovery of a predetermined schedule.
### Traffic load balancer **(STARTER ONLY)**
### Traffic load balancer **(PREMIUM SELF)**
> - Level of complexity: **Medium**
> - Required domain knowledge: HAProxy, shared storage, distributed systems
......@@ -124,7 +124,7 @@ to the default installation:
For more details on how to configure a traffic load balancer with GitLab, you can refer
to any of the [available reference architectures](#available-reference-architectures) with more than 1,000 users.
### Zero downtime updates **(STARTER ONLY)**
### Zero downtime updates **(PREMIUM SELF)**
> - Level of complexity: **Medium**
> - Required domain knowledge: PostgreSQL, HAProxy, shared storage, distributed systems
......
......@@ -4,7 +4,7 @@ group: Global Search
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Elasticsearch knowledge **(STARTER ONLY)**
# Elasticsearch knowledge **(PREMIUM SELF)**
This area is to maintain a compendium of useful information when working with Elasticsearch.
......
......@@ -603,7 +603,7 @@ You can specify a different Git repository by providing it as an extra parameter
sudo -u git -H bundle exec rake "gitlab:workhorse:install[/home/git/gitlab-workhorse,https://example.com/gitlab-workhorse.git]" RAILS_ENV=production
```
### Install GitLab-Elasticsearch-indexer on Enterprise Edition **(STARTER ONLY)**
### Install GitLab-Elasticsearch-indexer on Enterprise Edition **(PREMIUM SELF)**
GitLab-Elasticsearch-Indexer uses [GNU Make](https://www.gnu.org/software/make/). The
following command-line installs GitLab-Elasticsearch-Indexer in `/home/git/gitlab-elasticsearch-indexer`
......
......@@ -5,10 +5,11 @@ group: Global Search
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Elasticsearch integration **(STARTER ONLY)**
# Elasticsearch integration **(PREMIUM SELF)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/109 "Elasticsearch Merge Request") in GitLab [Starter](https://about.gitlab.com/pricing/) 8.4.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/109 "Elasticsearch Merge Request") in GitLab 8.4.
> - Support for [Amazon Elasticsearch](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-gsg.html) was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/1305) in GitLab [Starter](https://about.gitlab.com/pricing/) 9.0.
> - [Moved](../subscriptions/bronze_starter.md) to GitLab Premium in 13.9.
This document describes how to enable Advanced Search. After
Advanced Search is enabled, you'll have the benefit of fast search response times
......
......@@ -24,7 +24,7 @@ The following are available Rake tasks:
| [Clean up](cleanup.md) | Clean up unneeded items from GitLab instances. |
| [Development](../development/rake_tasks.md) | Tasks for GitLab contributors. |
| [Doctor tasks](../administration/raketasks/doctor.md) | Checks for data integrity issues. |
| [Elasticsearch](../integration/elasticsearch.md#gitlab-advanced-search-rake-tasks) **(STARTER ONLY)** | Maintain Elasticsearch in a GitLab instance. |
| [Elasticsearch](../integration/elasticsearch.md#gitlab-advanced-search-rake-tasks) **(PREMIUM SELF)** | Maintain Elasticsearch in a GitLab instance. |
| [Enable namespaces](features.md) | Enable usernames and namespaces for user projects. |
| [General maintenance](../administration/raketasks/maintenance.md) | General maintenance and self-check tasks. |
| [Geo maintenance](../administration/raketasks/geo.md) **(PREMIUM SELF)** | [Geo](../administration/geo/index.md)-related maintenance. |
......
......@@ -63,6 +63,7 @@ the tiers are no longer mentioned in GitLab documentation:
- [`audit_json.log`](../administration/logs.md#audit_jsonlog) (specific entries)
- [`elasticsearch.log`](../administration/logs.md#elasticsearchlog)
- Merge requests:
- [Full code quality reports in the code quality tab](../user/project/merge_requests/code_quality.md#code-quality-reports)
- [Merge request approvals](../user/project/merge_requests/merge_request_approvals.md)
- [Multiple assignees](../user/project/merge_requests/getting_started.md#multiple-assignees)
- [Approval Rule information for Reviewers](../user/project/merge_requests/getting_started.md#approval-rule-information-for-reviewers), and [enabling or disabling it](../user/project/merge_requests/getting_started.md#enable-or-disable-approval-rule-information-for-reviewers)
......
......@@ -96,7 +96,7 @@ sudo -u git -H git checkout v$(</home/git/gitlab/GITLAB_PAGES_VERSION)
sudo -u git -H make
```
### 8. Install/Update `gitlab-elasticsearch-indexer` **(STARTER ONLY)**
### 8. Install/Update `gitlab-elasticsearch-indexer` **(PREMIUM SELF)**
Please follow the [install instruction](../integration/elasticsearch.md#installing-elasticsearch).
......
......@@ -81,7 +81,7 @@ sudo -u git -H bundle exec rake yarn:install gitlab:assets:clean gitlab:assets:c
sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production
```
### 4. Install `gitlab-elasticsearch-indexer` **(STARTER ONLY)**
### 4. Install `gitlab-elasticsearch-indexer` **(PREMIUM SELF)**
Please follow the [install instruction](../integration/elasticsearch.md#installing-elasticsearch).
......
......@@ -5,9 +5,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference, howto
---
# Code Quality
# Code Quality **(FREE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/1984) in [GitLab Starter](https://about.gitlab.com/pricing/) 9.3.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/1984) in GitLab 9.3.
> - Made [available in all tiers](https://gitlab.com/gitlab-org/gitlab/-/issues/212499) in 13.2.
Ensuring your project's code stays simple, readable and easy to contribute to can be problematic. With the help of [GitLab CI/CD](../../../ci/README.md), you can analyze your
......@@ -28,7 +28,7 @@ Code Quality:
## Code Quality Widget
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/1984) in [GitLab Starter](https://about.gitlab.com/pricing/) 9.3.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/1984) in GitLab 9.3.
> - Made [available in all tiers](https://gitlab.com/gitlab-org/gitlab/-/issues/212499) in 13.2.
Going a step further, GitLab can show the Code Quality report right
......@@ -358,7 +358,7 @@ After the Code Quality job completes:
[downloadable artifact](../../../ci/pipelines/job_artifacts.md#downloading-artifacts)
for the `code_quality` job.
- The full list of code quality violations generated by a pipeline is shown in the
Code Quality tab of the Pipeline Details page. **(STARTER)**
Code Quality tab of the Pipeline Details page. **(PREMIUM)**
### Generating an HTML report
......
......@@ -5,9 +5,10 @@ info: "To determine the technical writer assigned to the Stage/Group associated
type: reference
---
# Advanced Search **(STARTER)**
# Advanced Search **(PREMIUM)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/109) in GitLab [Starter](https://about.gitlab.com/pricing/) 8.4.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/109) in GitLab 8.4.
> - [Moved](../../subscriptions/bronze_starter.md) to GitLab Premium in 13.9.
NOTE:
Advanced Search (powered by Elasticsearch) is enabled for Bronze and above on GitLab.com since 2020-07-10.
......
......@@ -5,12 +5,10 @@ info: "To determine the technical writer assigned to the Stage/Group associated
type: reference
---
# Advanced Search Syntax **(STARTER)**
# Advanced Search Syntax **(PREMIUM)**
> - Introduced in [GitLab Enterprise Starter](https://about.gitlab.com/pricing/) 9.2
NOTE:
Advanced Search (powered by Elasticsearch) is enabled for Bronze and above on GitLab.com since 2020-07-10.
> - Introduced in [GitLab](https://about.gitlab.com/pricing/) 9.2.
> - [Moved](../../subscriptions/bronze_starter.md) to GitLab Premium in 13.9.
Use advanced queries for more targeted search results.
......
......@@ -36,7 +36,7 @@ in the search field in the upper right corner:
> - Filtering by Epics was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/195704) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.9.
> - Filtering by child Epics was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9029) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.0.
> - Filtering by Iterations was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.6.
> - Filtering by Iterations was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6. [Moved](../../subscriptions/bronze_starter.md) to GitLab Premium in 13.9.
Follow these steps to filter the **Issues** and **Merge Requests** list pages in projects and
groups:
......@@ -99,18 +99,20 @@ You can filter the **Issues** list to individual instances by their ID. For exam
![filter issues by specific id](img/issue_search_by_id.png)
### Filtering merge requests by approvers **(STARTER)**
### Filtering merge requests by approvers **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/9468) in [GitLab Starter](https://about.gitlab.com/pricing/) 11.9.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/9468) in GitLab 11.9.
> - [Moved](../../subscriptions/bronze_starter.md) to GitLab Premium in 13.9.
To filter merge requests by an individual approver, you can type (or select from
the dropdown) **Approver** and select the user.
![Filter MRs by an approver](img/filter_approver_merge_requests.png)
### Filtering merge requests by "approved by" **(STARTER)**
### Filtering merge requests by "approved by" **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30335) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.0.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30335) in GitLab 13.0.
> - [Moved](../../subscriptions/bronze_starter.md) to GitLab Premium in 13.9.
To filter merge requests already approved by a specific individual, you can type (or select from
the dropdown) **Approved-By** and select the user.
......@@ -291,14 +293,14 @@ redirected to the commit result and given the option to return to the search res
![project SHA search redirect](img/project_search_sha_redirect.png)
## Advanced Search **(STARTER)**
## Advanced Search **(PREMIUM)**
Leverage Elasticsearch for faster, more advanced code search across your entire
GitLab instance.
[Learn how to use the Advanced Search.](advanced_global_search.md)
## Advanced Search Syntax **(STARTER)**
## Advanced Search Syntax **(PREMIUM)**
Use advanced queries for more targeted search results.
......
<script>
import { visitUrl } from '~/lib/utils/url_utility';
import { s__ } from '~/locale';
import * as Sentry from '~/sentry/wrapper';
import SharedForm from './shared_form.vue';
import createComplianceFrameworkMutation from '../graphql/queries/create_compliance_framework.mutation.graphql';
export default {
components: {
SharedForm,
},
props: {
groupEditPath: {
type: String,
required: true,
},
groupPath: {
type: String,
required: true,
},
},
data() {
return {
errorMessage: '',
};
},
computed: {
isLoading() {
return this.$apollo.loading;
},
},
methods: {
setError(error, userFriendlyText) {
this.errorMessage = userFriendlyText;
Sentry.captureException(error);
},
async onSubmit(formData) {
try {
const { data } = await this.$apollo.mutate({
mutation: createComplianceFrameworkMutation,
variables: {
input: {
namespacePath: this.groupPath,
params: {
name: formData.name,
description: formData.description,
color: formData.color,
},
},
},
});
const [error] = data?.createComplianceFramework?.errors || [];
if (error) {
this.setError(new Error(error), error);
} else {
visitUrl(this.groupEditPath);
}
} catch (e) {
this.setError(e, this.$options.i18n.saveError);
}
},
},
i18n: {
saveError: s__(
'ComplianceFrameworks|Unable to save this compliance framework. Please try again',
),
},
};
</script>
<template>
<shared-form
:group-edit-path="groupEditPath"
:loading="isLoading"
:render-form="!isLoading"
:error="errorMessage"
@submit="onSubmit"
/>
</template>
mutation createComplianceFramework($input: CreateComplianceFrameworkInput!) {
createComplianceFramework(input: $input) {
framework {
id
name
description
color
}
errors
}
}
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import CreateForm from './components/create_form.vue';
import createDefaultClient from '~/lib/graphql';
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
});
const createComplianceFrameworksFormApp = (el) => {
if (!el) {
return false;
}
const { groupEditPath, groupPath } = el.dataset;
return new Vue({
el,
apolloProvider,
render(createElement) {
const element = CreateForm;
const props = { groupEditPath, groupPath };
return createElement(element, {
props,
});
},
});
};
export { createComplianceFrameworksFormApp };
......@@ -10,7 +10,7 @@ module EE
def resolve(**args)
parsed_params = parse_arguments(args)
super(parsed_params)
super(**parsed_params)
end
def ready?(**args)
......
import VueApollo from 'vue-apollo';
import { createLocalVue, shallowMount } from '@vue/test-utils';
import waitForPromises from 'helpers/wait_for_promises';
import createMockApollo from 'helpers/mock_apollo_helper';
import createComplianceFrameworkMutation from 'ee/groups/settings/compliance_frameworks/graphql/queries/create_compliance_framework.mutation.graphql';
import CreateForm from 'ee/groups/settings/compliance_frameworks/components/create_form.vue';
import SharedForm from 'ee/groups/settings/compliance_frameworks/components/shared_form.vue';
import { visitUrl } from '~/lib/utils/url_utility';
import { validCreateResponse, errorCreateResponse } from '../mock_data';
import * as Sentry from '~/sentry/wrapper';
const localVue = createLocalVue();
localVue.use(VueApollo);
jest.mock('~/lib/utils/url_utility');
describe('Form', () => {
let wrapper;
const sentryError = new Error('Network error');
const sentrySaveError = new Error('Invalid values given');
const propsData = {
groupPath: 'group-1',
groupEditPath: 'group-1/edit',
scopedLabelsHelpPath: 'help/scoped-labels',
};
const create = jest.fn().mockResolvedValue(validCreateResponse);
const createWithNetworkErrors = jest.fn().mockRejectedValue(sentryError);
const createWithErrors = jest.fn().mockResolvedValue(errorCreateResponse);
const findForm = () => wrapper.findComponent(SharedForm);
function createMockApolloProvider(requestHandlers) {
localVue.use(VueApollo);
return createMockApollo(requestHandlers);
}
function createComponent(requestHandlers = []) {
return shallowMount(CreateForm, {
localVue,
apolloProvider: createMockApolloProvider(requestHandlers),
propsData,
});
}
afterEach(() => {
wrapper.destroy();
});
describe('loading', () => {
beforeEach(() => {
wrapper = createComponent();
});
it('passes the loading state to the form', () => {
expect(findForm().props('loading')).toBe(false);
expect(findForm().props('renderForm')).toBe(true);
});
});
describe('onSubmit', () => {
const name = 'Test';
const description = 'Test description';
const color = '#000000';
const creationProps = {
input: {
namespacePath: 'group-1',
params: {
name,
description,
color,
},
},
};
it('passes the error to the form when saving causes an exception and does not redirect', async () => {
jest.spyOn(Sentry, 'captureException');
wrapper = createComponent([[createComplianceFrameworkMutation, createWithNetworkErrors]]);
await waitForPromises();
findForm().vm.$emit('submit', { name, description, color });
await waitForPromises();
expect(createWithNetworkErrors).toHaveBeenCalledWith(creationProps);
expect(findForm().props('loading')).toBe(false);
expect(findForm().props('renderForm')).toBe(true);
expect(visitUrl).not.toHaveBeenCalled();
expect(findForm().props('error')).toBe(
'Unable to save this compliance framework. Please try again',
);
expect(Sentry.captureException.mock.calls[0][0].networkError).toStrictEqual(sentryError);
});
it('passes the errors to the form when saving fails and does not redirect', async () => {
jest.spyOn(Sentry, 'captureException');
wrapper = createComponent([[createComplianceFrameworkMutation, createWithErrors]]);
await waitForPromises();
findForm().vm.$emit('submit', { name, description, color });
await waitForPromises();
expect(createWithErrors).toHaveBeenCalledWith(creationProps);
expect(findForm().props('loading')).toBe(false);
expect(findForm().props('renderForm')).toBe(true);
expect(visitUrl).not.toHaveBeenCalled();
expect(findForm().props('error')).toBe('Invalid values given');
expect(Sentry.captureException.mock.calls[0][0]).toStrictEqual(sentrySaveError);
});
it('saves inputted values and redirects', async () => {
wrapper = createComponent([[createComplianceFrameworkMutation, create]]);
await waitForPromises();
findForm().vm.$emit('submit', { name, description, color });
await waitForPromises();
expect(create).toHaveBeenCalledWith(creationProps);
expect(findForm().props('loading')).toBe(false);
expect(findForm().props('renderForm')).toBe(true);
expect(visitUrl).toHaveBeenCalledWith(propsData.groupEditPath);
});
});
});
......@@ -48,3 +48,29 @@ export const frameworkFoundResponse = {
color: '#1aaa55',
parsedId: 1,
};
export const validCreateResponse = {
data: {
createComplianceFramework: {
framework: {
id: 'gid://gitlab/ComplianceManagement::Framework/1',
name: 'GDPR',
description: 'General Data Protection Regulation',
color: '#1aaa55',
__typename: 'ComplianceFramework',
},
errors: [],
__typename: 'CreateComplianceFrameworkPayload',
},
},
};
export const errorCreateResponse = {
data: {
createComplianceFramework: {
framework: null,
errors: ['Invalid values given'],
__typename: 'CreateComplianceFrameworkPayload',
},
},
};
......@@ -7335,6 +7335,9 @@ msgstr ""
msgid "ComplianceFrameworks|There are no compliance frameworks set up yet"
msgstr ""
msgid "ComplianceFrameworks|Unable to save this compliance framework. Please try again"
msgstr ""
msgid "ComplianceFrameworks|Use %{codeStart}::%{codeEnd} to create a %{linkStart}scoped set%{linkEnd} (eg. %{codeStart}SOX::AWS%{codeEnd})"
msgstr ""
......
# frozen_string_literal: true
if ENV.key?('RECORD_DEPRECATIONS')
require 'deprecation_toolkit'
require 'deprecation_toolkit/rspec'
DeprecationToolkit::Configuration.test_runner = :rspec
DeprecationToolkit::Configuration.deprecation_path = 'deprecations'
DeprecationToolkit::Configuration.behavior = DeprecationToolkit::Behaviors::Record
# Enable ruby deprecations for keywords, it's suppressed by default in Ruby 2.7.2
Warning[:deprecated] = true
kwargs_warnings = [
# Taken from https://github.com/jeremyevans/ruby-warning/blob/1.1.0/lib/warning.rb#L18
require 'deprecation_toolkit'
require 'deprecation_toolkit/rspec'
module DeprecationToolkitEnv
module DeprecationBehaviors
class SelectiveRaise
attr_reader :disallowed_deprecations_proc
class RaiseDisallowedDeprecation < StandardError
def initialize(test, current_deprecations)
message = <<~EOF
Disallowed deprecations detected while running test #{test}:
#{current_deprecations.deprecations.join("\n")}
EOF
super(message)
end
end
def initialize(disallowed_deprecations_proc)
@disallowed_deprecations_proc = disallowed_deprecations_proc
end
# Note: trigger does not get called if the current_deprecations matches recorded_deprecations
# See https://github.com/Shopify/deprecation_toolkit/blob/2398f38acb62220fb79a6cd720f61d9cea26bc06/lib/deprecation_toolkit/test_triggerer.rb#L8-L11
def trigger(test, current_deprecations, recorded_deprecations)
if selected_for_raise?(current_deprecations)
raise RaiseDisallowedDeprecation.new(test, current_deprecations)
elsif ENV['RECORD_DEPRECATIONS']
record(test, current_deprecations, recorded_deprecations)
end
end
private
def selected_for_raise?(current_deprecations)
disallowed_deprecations_proc.call(current_deprecations.deprecations_without_stacktrace)
end
def record(test, current_deprecations, recorded_deprecations)
::DeprecationToolkit::Behaviors::Record.trigger(test, current_deprecations, recorded_deprecations)
end
end
end
# Taken from https://github.com/jeremyevans/ruby-warning/blob/1.1.0/lib/warning.rb#L18
def self.kwargs_warning
%r{warning: (?:Using the last argument (?:for `.+' )?as keyword parameters is deprecated; maybe \*\* should be added to the call|Passing the keyword argument (?:for `.+' )?as the last hash parameter is deprecated|Splitting the last argument (?:for `.+' )?into positional and keyword parameters is deprecated|The called method (?:`.+' )?is defined here)\n\z}
]
DeprecationToolkit::Configuration.warnings_treated_as_deprecation = kwargs_warnings
end
# Allow these Gem paths to trigger keyword warnings as we upgrade these gems
# one by one
def self.allowed_kwarg_warning_paths
%w[
ee/lib/ee/gitlab/usage_data.rb
spec/lib/gitlab/utils/usage_data_spec.rb
spec/support/gitlab_experiment.rb
spec/support/helpers/next_instance_of.rb
rspec-mocks-3.10.0/lib/rspec/mocks/message_expectation.rb
activerecord-6.0.3.4/lib/active_record/migration.rb
devise-4.7.3/lib/devise/test/controller_helpers.rb
attr_encrypted-3.1.0/lib/attr_encrypted/adapters/active_record.rb
rspec-mocks-3.10.0/lib/rspec/mocks/message_expectation.rb
rspec-expectations-3.10.0/lib/rspec/matchers/built_in/has.rb
grape-1.5.1/lib/grape/middleware/stack.rb
grape-1.5.1/lib/grape/validations/validators/coerce.rb
grape_logging-1.8.3/lib/grape_logging/middleware/request_logger.rb
activesupport-6.0.3.4/lib/active_support/cache.rb
factory_bot-6.1.0/lib/factory_bot/decorator.rb
doorkeeper-5.4.0/lib/doorkeeper/models/access_token_mixin.rb
rouge-3.26.0/lib/rouge/formatter.rb
batch-loader-1.4.0/lib/batch_loader/graphql.rb
carrierwave-1.3.1/lib/carrierwave/sanitized_file.rb
activerecord-6.0.3.4/lib/active_record/relation.rb
]
end
def self.configure!
# Enable ruby deprecations for keywords, it's suppressed by default in Ruby 2.7.2
Warning[:deprecated] = true
DeprecationToolkit::Configuration.test_runner = :rspec
DeprecationToolkit::Configuration.deprecation_path = 'deprecations'
DeprecationToolkit::Configuration.warnings_treated_as_deprecation = [kwargs_warning]
disallowed_deprecations = -> (deprecations) do
deprecations.any? do |deprecation|
kwargs_warning.match?(deprecation) &&
allowed_kwarg_warning_paths.none? { |path| deprecation.include?(path) }
end
end
DeprecationToolkit::Configuration.behavior = DeprecationBehaviors::SelectiveRaise.new(disallowed_deprecations)
end
end
......@@ -13,6 +13,7 @@ end
Warning[:deprecated] = true unless ENV.key?('SILENCE_DEPRECATIONS')
require './spec/deprecation_toolkit_env'
DeprecationToolkitEnv.configure!
require './spec/simplecov_env'
SimpleCovEnv.start!
......@@ -174,6 +175,7 @@ RSpec.configure do |config|
if ENV['CI'] || ENV['RETRIES']
# This includes the first try, i.e. tests will be run 4 times before failing.
config.default_retry_count = ENV.fetch('RETRIES', 3).to_i + 1
config.exceptions_to_hard_fail = [DeprecationToolkitEnv::DeprecationBehaviors::SelectiveRaise::RaiseDisallowedDeprecation]
end
if ENV['FLAKY_RSPEC_GENERATE_REPORT']
......
......@@ -4,7 +4,7 @@ RSpec.shared_examples 'timebox(milestone or iteration) resource events creator'
let_it_be(:user) { create(:user) }
context 'when milestone/iteration is added' do
let(:service) { described_class.new(resource, user, add_timebox_args) }
let(:service) { described_class.new(resource, user, **add_timebox_args) }
before do
set_timebox(timebox_event_class, timebox)
......@@ -18,7 +18,7 @@ RSpec.shared_examples 'timebox(milestone or iteration) resource events creator'
end
context 'when milestone/iteration is removed' do
let(:service) { described_class.new(resource, user, remove_timebox_args) }
let(:service) { described_class.new(resource, user, **remove_timebox_args) }
before do
set_timebox(timebox_event_class, nil)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment