From 6456305e5810391463cdf58d9b4952903047c05a Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Tue, 27 Jul 2021 21:09:42 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- .gitlab/ci/frontend.gitlab-ci.yml | 7 ++ .gitlab/ci/rails.gitlab-ci.yml | 3 + Gemfile | 2 +- Gemfile.lock | 4 +- app/assets/javascripts/blob/csv/csv_viewer.vue | 13 +- .../components/toolbar_link_button.vue | 13 +- .../content_editor/extensions/blockquote.js | 6 +- .../javascripts/content_editor/extensions/bold.js | 6 +- .../content_editor/extensions/bullet_list.js | 6 +- .../javascripts/content_editor/extensions/code.js | 6 +- .../extensions/code_block_highlight.js | 6 +- .../content_editor/extensions/document.js | 4 +- .../content_editor/extensions/dropcursor.js | 4 +- .../content_editor/extensions/gapcursor.js | 4 +- .../content_editor/extensions/hard_break.js | 6 +- .../content_editor/extensions/heading.js | 6 +- .../content_editor/extensions/history.js | 4 +- .../content_editor/extensions/horizontal_rule.js | 4 +- .../javascripts/content_editor/extensions/image.js | 17 +-- .../content_editor/extensions/italic.js | 5 +- .../javascripts/content_editor/extensions/link.js | 12 +- .../content_editor/extensions/list_item.js | 6 +- .../content_editor/extensions/ordered_list.js | 6 +- .../content_editor/extensions/paragraph.js | 6 +- .../content_editor/extensions/strike.js | 10 +- .../javascripts/content_editor/extensions/table.js | 8 +- .../content_editor/extensions/table_cell.js | 6 +- .../content_editor/extensions/table_header.js | 6 +- .../content_editor/extensions/table_row.js | 48 +------- .../javascripts/content_editor/extensions/text.js | 6 +- .../services/build_serializer_config.js | 22 ---- .../services/create_content_editor.js | 58 +++++---- .../content_editor/services/markdown_serializer.js | 134 ++++++++++++++++++++- .../vue_shared/components/papa_parse_alert.vue | 44 +++++++ app/policies/project_policy.rb | 9 +- app/policies/release_policy.rb | 6 +- app/services/releases/base_service.rb | 9 -- app/services/releases/create_service.rb | 4 - app/services/releases/destroy_service.rb | 2 - app/services/releases/update_service.rb | 2 - ...alute_protected_tag_for_release_permissions.yml | 8 -- danger/specialization_labels/Dangerfile | 2 +- doc/administration/get_started.md | 2 + doc/api/experiments.md | 50 +++++++- doc/api/users.md | 1 + doc/development/documentation/styleguide/index.md | 4 +- doc/user/application_security/dast/index.md | 4 +- doc/user/group/settings/img/export_panel_v13_0.png | Bin 47857 -> 0 bytes doc/user/group/settings/import_export.md | 31 ++--- doc/user/project/releases/index.md | 19 --- doc/user/project/wiki/index.md | 8 ++ locale/gitlab.pot | 18 +++ spec/frontend/blob/csv/csv_viewer_spec.js | 13 +- .../components/toolbar_image_button_spec.js | 14 +-- .../components/toolbar_link_button_spec.js | 6 +- .../components/toolbar_table_button_spec.js | 8 +- .../components/toolbar_text_style_dropdown_spec.js | 2 +- .../extensions/code_block_highlight_spec.js | 2 +- .../content_editor/extensions/hard_break_spec.js | 2 +- .../content_editor/extensions/image_spec.js | 10 +- .../services/build_serializer_config_spec.js | 38 ------ .../services/create_content_editor_spec.js | 4 +- .../track_input_rules_and_shortcuts_spec.js | 8 +- .../vue_shared/components/papa_parse_alert_spec.js | 44 +++++++ spec/policies/release_policy_spec.rb | 23 ---- spec/services/releases/create_service_spec.rb | 15 --- spec/services/releases/destroy_service_spec.rb | 15 --- spec/services/releases/update_service_spec.rb | 15 --- spec/tooling/danger/project_helper_spec.rb | 34 +++--- tooling/danger/project_helper.rb | 22 ++-- 70 files changed, 452 insertions(+), 500 deletions(-) delete mode 100644 app/assets/javascripts/content_editor/services/build_serializer_config.js create mode 100644 app/assets/javascripts/vue_shared/components/papa_parse_alert.vue delete mode 100644 config/feature_flags/development/evalute_protected_tag_for_release_permissions.yml delete mode 100644 doc/user/group/settings/img/export_panel_v13_0.png delete mode 100644 spec/frontend/content_editor/services/build_serializer_config_spec.js create mode 100644 spec/frontend/vue_shared/components/papa_parse_alert_spec.js diff --git a/.gitlab/ci/frontend.gitlab-ci.yml b/.gitlab/ci/frontend.gitlab-ci.yml index 3aa8ab1591a..318ac20435e 100644 --- a/.gitlab/ci/frontend.gitlab-ci.yml +++ b/.gitlab/ci/frontend.gitlab-ci.yml @@ -15,6 +15,9 @@ variables: SETUP_DB: "false" WEBPACK_VENDOR_DLL: "true" + # Disable warnings in browserslist which can break on backports + # https://github.com/browserslist/browserslist/blob/a287ec6/node.js#L367-L384 + BROWSERSLIST_IGNORE_OLD_DATA: "true" stage: prepare script: - *yarn-install @@ -164,6 +167,10 @@ graphql-schema-dump: extends: - .default-retry - .yarn-cache + variables: + # Disable warnings in browserslist which can break on backports + # https://github.com/browserslist/browserslist/blob/a287ec6/node.js#L367-L384 + BROWSERSLIST_IGNORE_OLD_DATA: "true" stage: test eslint-as-if-foss: diff --git a/.gitlab/ci/rails.gitlab-ci.yml b/.gitlab/ci/rails.gitlab-ci.yml index eda1ba49254..af0861dd8b3 100644 --- a/.gitlab/ci/rails.gitlab-ci.yml +++ b/.gitlab/ci/rails.gitlab-ci.yml @@ -234,6 +234,9 @@ update-gitaly-binaries-cache: variables: SETUP_DB: "false" ENABLE_SPRING: "1" + # Disable warnings in browserslist which can break on backports + # https://github.com/browserslist/browserslist/blob/a287ec6/node.js#L367-L384 + BROWSERSLIST_IGNORE_OLD_DATA: "true" update-static-analysis-cache: extends: diff --git a/Gemfile b/Gemfile index c14418ba7e3..2e2227d9875 100644 --- a/Gemfile +++ b/Gemfile @@ -394,7 +394,7 @@ group :development, :test do end group :development, :test, :danger do - gem 'gitlab-dangerfiles', '~> 2.2.2', require: false + gem 'gitlab-dangerfiles', '~> 2.3.0', require: false end group :development, :test, :coverage do diff --git a/Gemfile.lock b/Gemfile.lock index 617e1f18caa..7cd04312b94 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -460,7 +460,7 @@ GEM terminal-table (~> 1.5, >= 1.5.1) gitlab-chronic (0.10.5) numerizer (~> 0.2) - gitlab-dangerfiles (2.2.2) + gitlab-dangerfiles (2.3.0) danger (>= 8.3.1) danger-gitlab (>= 8.0.0) gitlab-experiment (0.6.2) @@ -1467,7 +1467,7 @@ DEPENDENCIES gitaly (~> 14.1.0.pre.rc4) github-markup (~> 1.7.0) gitlab-chronic (~> 0.10.5) - gitlab-dangerfiles (~> 2.2.2) + gitlab-dangerfiles (~> 2.3.0) gitlab-experiment (~> 0.6.2) gitlab-fog-azure-rm (~> 1.1.1) gitlab-labkit (~> 0.21.0) diff --git a/app/assets/javascripts/blob/csv/csv_viewer.vue b/app/assets/javascripts/blob/csv/csv_viewer.vue index 050f2785d9a..1f9d20a487f 100644 --- a/app/assets/javascripts/blob/csv/csv_viewer.vue +++ b/app/assets/javascripts/blob/csv/csv_viewer.vue @@ -1,11 +1,12 @@ + + diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb index 85547834a2e..b6e063f5584 100644 --- a/app/policies/project_policy.rb +++ b/app/policies/project_policy.rb @@ -159,10 +159,6 @@ class ProjectPolicy < BasePolicy ::Feature.enabled?(:build_service_proxy, @subject) end - condition(:respect_protected_tag_for_release_permissions) do - ::Feature.enabled?(:evalute_protected_tag_for_release_permissions, @subject, default_enabled: :yaml) - end - condition(:user_defined_variables_allowed) do !@subject.restrict_user_defined_variables? end @@ -374,6 +370,7 @@ class ProjectPolicy < BasePolicy enable :update_deployment enable :create_release enable :update_release + enable :destroy_release enable :create_metrics_dashboard_annotation enable :delete_metrics_dashboard_annotation enable :update_metrics_dashboard_annotation @@ -657,10 +654,6 @@ class ProjectPolicy < BasePolicy rule { build_service_proxy_enabled }.enable :build_service_proxy_enabled - rule { respect_protected_tag_for_release_permissions & can?(:developer_access) }.policy do - enable :destroy_release - end - rule { can?(:download_code) }.policy do enable :read_repository_graphs end diff --git a/app/policies/release_policy.rb b/app/policies/release_policy.rb index bff80d83bef..077e4764b34 100644 --- a/app/policies/release_policy.rb +++ b/app/policies/release_policy.rb @@ -9,11 +9,7 @@ class ReleasePolicy < BasePolicy !access.can_create_tag?(@subject.tag) end - condition(:respect_protected_tag) do - ::Feature.enabled?(:evalute_protected_tag_for_release_permissions, @subject.project, default_enabled: :yaml) - end - - rule { respect_protected_tag & protected_tag }.policy do + rule { protected_tag }.policy do prevent :create_release prevent :update_release prevent :destroy_release diff --git a/app/services/releases/base_service.rb b/app/services/releases/base_service.rb index b4b493624e7..249333e6d13 100644 --- a/app/services/releases/base_service.rb +++ b/app/services/releases/base_service.rb @@ -83,15 +83,6 @@ module Releases release.execute_hooks(action) end - def track_protected_tag_access_error! - unless ::Gitlab::UserAccess.new(current_user, container: project).can_create_tag?(tag_name) - Gitlab::ErrorTracking.log_exception( - ReleaseProtectedTagAccessError.new, - project_id: project.id, - user_id: current_user.id) - end - end - # overridden in EE def project_group_id; end end diff --git a/app/services/releases/create_service.rb b/app/services/releases/create_service.rb index 2aac5644b84..caa6a003205 100644 --- a/app/services/releases/create_service.rb +++ b/app/services/releases/create_service.rb @@ -7,8 +7,6 @@ module Releases return error('Release already exists', 409) if release return error("Milestone(s) not found: #{inexistent_milestones.join(', ')}", 400) if inexistent_milestones.any? - track_protected_tag_access_error! - # should be found before the creation of new tag # because tag creation can spawn new pipeline # which won't have any data for evidence yet @@ -48,8 +46,6 @@ module Releases end def can_create_tag? - return true unless ::Feature.enabled?(:evalute_protected_tag_for_release_permissions, project, default_enabled: :yaml) - ::Gitlab::UserAccess.new(current_user, container: project).can_create_tag?(tag_name) end diff --git a/app/services/releases/destroy_service.rb b/app/services/releases/destroy_service.rb index 36cf29c955d..8abf9308689 100644 --- a/app/services/releases/destroy_service.rb +++ b/app/services/releases/destroy_service.rb @@ -6,8 +6,6 @@ module Releases return error('Release does not exist', 404) unless release return error('Access Denied', 403) unless allowed? - track_protected_tag_access_error! - if release.destroy success(tag: existing_tag, release: release) else diff --git a/app/services/releases/update_service.rb b/app/services/releases/update_service.rb index 011cb2e481d..2e0a2f8488a 100644 --- a/app/services/releases/update_service.rb +++ b/app/services/releases/update_service.rb @@ -7,8 +7,6 @@ module Releases return error end - track_protected_tag_access_error! - if param_for_milestone_titles_provided? previous_milestones = release.milestones.map(&:title) params[:milestones] = milestones diff --git a/config/feature_flags/development/evalute_protected_tag_for_release_permissions.yml b/config/feature_flags/development/evalute_protected_tag_for_release_permissions.yml deleted file mode 100644 index a314c0263ba..00000000000 --- a/config/feature_flags/development/evalute_protected_tag_for_release_permissions.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: evalute_protected_tag_for_release_permissions -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64693 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/334368 -milestone: '14.1' -type: development -group: group::release -default_enabled: true diff --git a/danger/specialization_labels/Dangerfile b/danger/specialization_labels/Dangerfile index 35125f20b14..e86d66f5fbc 100644 --- a/danger/specialization_labels/Dangerfile +++ b/danger/specialization_labels/Dangerfile @@ -8,7 +8,7 @@ SPECIALIZATIONS = { frontend: 'frontend', docs: 'documentation', qa: 'QA', - engineering_productivity: 'Engineering Productivity', + tooling: 'tooling', ci_template: 'ci::templates', feature_flag: 'feature flag' }.freeze diff --git a/doc/administration/get_started.md b/doc/administration/get_started.md index 7d1080148ea..ac717769d4f 100644 --- a/doc/administration/get_started.md +++ b/doc/administration/get_started.md @@ -83,6 +83,8 @@ While this isn't an exhaustive list, following these steps gives you a solid sta - Configure [user and IP rate limits](https://about.gitlab.com/blog/2020/05/20/gitlab-instance-security-best-practices/#user-and-ip-rate-limits). - Limit [webhooks local access](https://about.gitlab.com/blog/2020/05/20/gitlab-instance-security-best-practices/#webhooks). - Set [rate limits for protected paths](../user/admin_area/settings/protected_paths.md). +- Sign up for [Security Alerts](https://about.gitlab.com/company/preference-center/) from the Communication Preference Center. +- Keep track of security best practices on our [blog page](https://about.gitlab.com/blog/2020/05/20/gitlab-instance-security-best-practices/). ## Monitor GitLab performance diff --git a/doc/api/experiments.md b/doc/api/experiments.md index 3c8efa35b78..c5e217a3d66 100644 --- a/doc/api/experiments.md +++ b/doc/api/experiments.md @@ -28,13 +28,51 @@ Example response: ```json [ - { - "key": "experiment_1", - "enabled": true + { + "key": "code_quality_walkthrough", + "definition": { + "name": "code_quality_walkthrough", + "introduced_by_url": "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900", + "rollout_issue_url": "https://gitlab.com/gitlab-org/gitlab/-/issues/327229", + "milestone": "13.12", + "type": "experiment", + "group": "group::activation", + "default_enabled": false }, - { - "key": "experiment_2", - "enabled": false + "current_status": { + "state": "conditional", + "gates": [ + { + "key": "boolean", + "value": false + }, + { + "key": "percentage_of_actors", + "value": 25 + } + ] } + }, + { + "key": "ci_runner_templates", + "definition": { + "name": "ci_runner_templates", + "introduced_by_url": "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58357", + "rollout_issue_url": "https://gitlab.com/gitlab-org/gitlab/-/issues/326725", + "milestone": "14.0", + "type": "experiment", + "group": "group::activation", + "default_enabled": false + }, + "current_status": { + "state": "off", + "gates": [ + { + "key": "boolean", + "value": false + } + ] + } + } ] ``` diff --git a/doc/api/users.md b/doc/api/users.md index e074bd44c7a..15fa397823e 100644 --- a/doc/api/users.md +++ b/doc/api/users.md @@ -109,6 +109,7 @@ GET /users | `two_factor` | string | no | Filter users by Two-factor authentication. Filter values are `enabled` or `disabled`. By default it returns all users | | `without_projects` | boolean | no | Filter users without projects. Default is `false`, which means that all users are returned, with and without projects. | | `admins` | boolean | no | Return only admin users. Default is `false` | +| `saml_provider_id` **(PREMIUM)** | number | no | Return only users created by the specified SAML provider ID. If not included, it returns all users. | ```json [ diff --git a/doc/development/documentation/styleguide/index.md b/doc/development/documentation/styleguide/index.md index b0f0168c42c..903c2543de5 100644 --- a/doc/development/documentation/styleguide/index.md +++ b/doc/development/documentation/styleguide/index.md @@ -1,7 +1,5 @@ --- -stage: none -group: Style Guide -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 +info: For assistance with this Style Guide page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-other-projects-and-subjects. description: 'Writing styles, markup, formatting, and other standards for GitLab Documentation.' --- diff --git a/doc/user/application_security/dast/index.md b/doc/user/application_security/dast/index.md index d694bb4fb1a..78197cb32f3 100644 --- a/doc/user/application_security/dast/index.md +++ b/doc/user/application_security/dast/index.md @@ -304,7 +304,7 @@ For more details, including setup instructions, see [DAST browser-based crawler] ### Full scan -DAST can be configured to perform [ZAP Full Scan](https://github.com/zaproxy/zaproxy/wiki/ZAP-Full-Scan), which +DAST can be configured to perform [ZAP Full Scan](https://www.zaproxy.org/docs/docker/full-scan/), which includes both passive and active scanning against the same target website: ```yaml @@ -786,7 +786,7 @@ You can use CI/CD variables to customize DAST. | `DAST_SKIP_TARGET_CHECK` | boolean | Set to `true` to prevent DAST from checking that the target is available before scanning. Default: `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/229067) in GitLab 13.8. | | `DAST_MASK_HTTP_HEADERS` | string | Comma-separated list of request and response headers to be masked (GitLab 13.1). Must contain **all** headers to be masked. Refer to [list of headers that are masked by default](#hide-sensitive-information). | | `DAST_EXCLUDE_URLS` 1 | URLs | The URLs to skip during the authenticated scan; comma-separated. Regular expression syntax can be used to match multiple URLs. For example, `.*` matches an arbitrary character sequence. Not supported for API scans. | -| `DAST_FULL_SCAN_ENABLED` 1 | boolean | Set to `true` to run a [ZAP Full Scan](https://github.com/zaproxy/zaproxy/wiki/ZAP-Full-Scan) instead of a [ZAP Baseline Scan](https://github.com/zaproxy/zaproxy/wiki/ZAP-Baseline-Scan). Default: `false` | +| `DAST_FULL_SCAN_ENABLED` 1 | boolean | Set to `true` to run a [ZAP Full Scan](https://www.zaproxy.org/docs/docker/full-scan/) instead of a [ZAP Baseline Scan](https://www.zaproxy.org/docs/docker/baseline-scan/). Default: `false` | | `DAST_FULL_SCAN_DOMAIN_VALIDATION_REQUIRED` | boolean | **{warning}** **[Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/293595)** in GitLab 14.0. Set to `true` to require domain validation when running DAST full scans. Not supported for API scans. Default: `false` | | `DAST_AUTO_UPDATE_ADDONS` | boolean | ZAP add-ons are pinned to specific versions in the DAST Docker image. Set to `true` to download the latest versions when the scan starts. Default: `false` | | `DAST_API_HOST_OVERRIDE` 1 | string | Used to override domains defined in API specification files. Only supported when importing the API specification from a URL. Example: `example.com:8080` | diff --git a/doc/user/group/settings/img/export_panel_v13_0.png b/doc/user/group/settings/img/export_panel_v13_0.png deleted file mode 100644 index 36549e1f3f5..00000000000 Binary files a/doc/user/group/settings/img/export_panel_v13_0.png and /dev/null differ diff --git a/doc/user/group/settings/import_export.md b/doc/user/group/settings/import_export.md index 4ed781b82cb..a0930867b2a 100644 --- a/doc/user/group/settings/import_export.md +++ b/doc/user/group/settings/import_export.md @@ -19,9 +19,11 @@ See also: - [Project Import/Export](../../project/settings/import_export.md) - [Project Import/Export API](../../../api/project_import_export.md) -To enable GitLab import/export: +Users with the [Owner role](../../permissions.md) for a group can enable +import and export for that group: -1. On the top bar, go to **Menu > Admin > Settings > General > Visibility and access controls**. +1. On the top bar, select **Menu >** **{admin}** **Admin**. +1. On the left sidebar, select **Settings > General > Visibility and access controls**. 1. Scroll to **Import sources**. 1. Enable the desired **Import sources**. @@ -48,7 +50,8 @@ The following items are exported: - Subgroups (including all the aforementioned data) - Epics - Events -- Wikis **(PREMIUM SELF)** (Introduced in [GitLab 13.9](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53247)) +- [Wikis](../../project/wiki/index.md#group-wikis) **(PREMIUM SELF)** + (Introduced in [GitLab 13.9](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53247)) The following items are **not** exported: @@ -60,21 +63,21 @@ NOTE: For more details on the specific data persisted in a group export, see the [`import_export.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/import_export/group/import_export.yml) file. -## Exporting a Group +## Export a group -1. Navigate to your group's homepage. - -1. Click **Settings** in the sidebar. - -1. In the **Advanced** section, click the **Export Group** button. - - ![Export group panel](img/export_panel_v13_0.png) +Users with the [Owner role](../../permissions.md) for a group can export the +contents of that group: +1. On the top bar, select **Menu >** **Groups** and find your group. +1. In the left sidebar, select **Settings**. +1. Scroll to the **Advanced** section, and select **Export Group**. 1. After the export is generated, you should receive an email with a link to the [exported contents](#exported-contents) in a compressed tar archive, with contents in NDJSON format. +1. Alternatively, you can download the export from the UI: -1. Alternatively, you can come back to the project settings and download the - file from there by clicking **Download export**, or generate a new file by clicking **Regenerate export**. + 1. Return to your group's **Settings > General** page. + 1. Scroll to the **Advanced** section, and select **Download export**. + You can also generate a new file by clicking **Regenerate export**. NOTE: The maximum import file size can be set by the Administrator, default is `0` (unlimited). @@ -103,7 +106,7 @@ on an existing group's page. 1. Click **Choose file** -1. Select the file that you exported in the [exporting a group](#exporting-a-group) section. +1. Select the file that you exported in the [Export a group](#export-a-group) section. 1. Click **Import group** to begin importing. Your newly imported group page appears after the operation completes. diff --git a/doc/user/project/releases/index.md b/doc/user/project/releases/index.md index 3a25b148fdf..6a10e3747c4 100644 --- a/doc/user/project/releases/index.md +++ b/doc/user/project/releases/index.md @@ -589,25 +589,6 @@ As an example of release permission control, you can allow only to create, update, and delete releases by protecting the tag with a wildcard (`*`), and set **Maintainer** in the **Allowed to create** column. -#### Enable or disable protected tag evaluation on releases **(FREE SELF)** - -Protected tag evaluation on release permissions is under development but ready for production use. -It is deployed behind a feature flag that is **enabled by default**. -[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md) -can opt to disable it. - -To enable it: - -```ruby -Feature.enable(:evalute_protected_tag_for_release_permissions) -``` - -To disable it: - -```ruby -Feature.disable(:evalute_protected_tag_for_release_permissions) -``` - ## Release Command Line > [Introduced](https://gitlab.com/gitlab-org/release-cli/-/merge_requests/6) in GitLab 12.10. diff --git a/doc/user/project/wiki/index.md b/doc/user/project/wiki/index.md index f657b541aae..a1ebe5bc2ee 100644 --- a/doc/user/project/wiki/index.md +++ b/doc/user/project/wiki/index.md @@ -253,6 +253,14 @@ Group wikis can be edited by members with the [Developer role](../../permissions and above. Group wiki repositories can be moved using the [Group repository storage moves API](../../../api/group_repository_storage_moves.md). +### Export a group wiki **(PREMIUM)** + +Users with the [Owner role](../../permissions.md) in a group can +[import and export group wikis](../../group/settings/import_export.md) when importing +or exporting a group. + +Content created in a group wiki is not deleted when an account is downgraded or a GitLab trial ends. + ## Link an external wiki To add a link to an external wiki from a project's left sidebar: diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 260922a00ca..80242fddd64 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -9642,6 +9642,24 @@ msgstr "" msgid "Crowd" msgstr "" +msgid "CsvParser|Failed to render the CSV file for the following reasons:" +msgstr "" + +msgid "CsvParser|Quoted field unterminated" +msgstr "" + +msgid "CsvParser|Too few fields" +msgstr "" + +msgid "CsvParser|Too many fields" +msgstr "" + +msgid "CsvParser|Trailing quote on quoted field is malformed" +msgstr "" + +msgid "CsvParser|Unable to auto-detect delimiter; defaulted to \",\"" +msgstr "" + msgid "Current" msgstr "" diff --git a/spec/frontend/blob/csv/csv_viewer_spec.js b/spec/frontend/blob/csv/csv_viewer_spec.js index abb914b8f57..17973c709c1 100644 --- a/spec/frontend/blob/csv/csv_viewer_spec.js +++ b/spec/frontend/blob/csv/csv_viewer_spec.js @@ -1,8 +1,9 @@ -import { GlAlert, GlLoadingIcon, GlTable } from '@gitlab/ui'; +import { GlLoadingIcon, GlTable } from '@gitlab/ui'; import { getAllByRole } from '@testing-library/dom'; import { shallowMount, mount } from '@vue/test-utils'; import { nextTick } from 'vue'; -import CSVViewer from '~/blob/csv/csv_viewer.vue'; +import CsvViewer from '~/blob/csv/csv_viewer.vue'; +import PapaParseAlert from '~/vue_shared/components/papa_parse_alert.vue'; const validCsv = 'one,two,three'; const brokenCsv = '{\n "json": 1,\n "key": [1, 2, 3]\n}'; @@ -11,7 +12,7 @@ describe('app/assets/javascripts/blob/csv/csv_viewer.vue', () => { let wrapper; const createComponent = ({ csv = validCsv, mountFunction = shallowMount } = {}) => { - wrapper = mountFunction(CSVViewer, { + wrapper = mountFunction(CsvViewer, { propsData: { csv, }, @@ -20,7 +21,7 @@ describe('app/assets/javascripts/blob/csv/csv_viewer.vue', () => { const findCsvTable = () => wrapper.findComponent(GlTable); const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon); - const findAlert = () => wrapper.findComponent(GlAlert); + const findAlert = () => wrapper.findComponent(PapaParseAlert); afterEach(() => { wrapper.destroy(); @@ -35,12 +36,12 @@ describe('app/assets/javascripts/blob/csv/csv_viewer.vue', () => { }); describe('when the CSV contains errors', () => { - it('should render alert', async () => { + it('should render alert with correct props', async () => { createComponent({ csv: brokenCsv }); await nextTick; expect(findAlert().props()).toMatchObject({ - variant: 'danger', + papaParseErrors: [{ code: 'UndetectableDelimiter' }], }); }); }); diff --git a/spec/frontend/content_editor/components/toolbar_image_button_spec.js b/spec/frontend/content_editor/components/toolbar_image_button_spec.js index 701dcf83476..6553d8fd357 100644 --- a/spec/frontend/content_editor/components/toolbar_image_button_spec.js +++ b/spec/frontend/content_editor/components/toolbar_image_button_spec.js @@ -1,7 +1,7 @@ import { GlButton, GlFormInputGroup } from '@gitlab/ui'; import { mountExtended } from 'helpers/vue_test_utils_helper'; import ToolbarImageButton from '~/content_editor/components/toolbar_image_button.vue'; -import { configure as configureImageExtension } from '~/content_editor/extensions/image'; +import Image from '~/content_editor/extensions/image'; import { createTestEditor, mockChainedCommands } from '../test_utils'; describe('content_editor/components/toolbar_image_button', () => { @@ -29,13 +29,13 @@ describe('content_editor/components/toolbar_image_button', () => { }; beforeEach(() => { - const { tiptapExtension: Image } = configureImageExtension({ - renderMarkdown: jest.fn(), - uploadsPath: '/uploads/', - }); - editor = createTestEditor({ - extensions: [Image], + extensions: [ + Image.configure({ + renderMarkdown: jest.fn(), + uploadsPath: '/uploads/', + }), + ], }); buildWrapper(); diff --git a/spec/frontend/content_editor/components/toolbar_link_button_spec.js b/spec/frontend/content_editor/components/toolbar_link_button_spec.js index 576a2912f72..89a40c42590 100644 --- a/spec/frontend/content_editor/components/toolbar_link_button_spec.js +++ b/spec/frontend/content_editor/components/toolbar_link_button_spec.js @@ -1,7 +1,7 @@ import { GlDropdown, GlDropdownDivider, GlButton, GlFormInputGroup } from '@gitlab/ui'; import { mountExtended } from 'helpers/vue_test_utils_helper'; import ToolbarLinkButton from '~/content_editor/components/toolbar_link_button.vue'; -import { tiptapExtension as Link } from '~/content_editor/extensions/link'; +import Link from '~/content_editor/extensions/link'; import { hasSelection } from '~/content_editor/services/utils'; import { createTestEditor, mockChainedCommands } from '../test_utils'; @@ -25,9 +25,7 @@ describe('content_editor/components/toolbar_link_button', () => { const findRemoveLinkButton = () => wrapper.findByText('Remove link'); beforeEach(() => { - editor = createTestEditor({ - extensions: [Link], - }); + editor = createTestEditor(); }); afterEach(() => { diff --git a/spec/frontend/content_editor/components/toolbar_table_button_spec.js b/spec/frontend/content_editor/components/toolbar_table_button_spec.js index 237b2848246..fe5212cfe3c 100644 --- a/spec/frontend/content_editor/components/toolbar_table_button_spec.js +++ b/spec/frontend/content_editor/components/toolbar_table_button_spec.js @@ -1,10 +1,6 @@ import { GlDropdown, GlButton } from '@gitlab/ui'; import { mountExtended } from 'helpers/vue_test_utils_helper'; import ToolbarTableButton from '~/content_editor/components/toolbar_table_button.vue'; -import { tiptapExtension as Table } from '~/content_editor/extensions/table'; -import { tiptapExtension as TableCell } from '~/content_editor/extensions/table_cell'; -import { tiptapExtension as TableHeader } from '~/content_editor/extensions/table_header'; -import { tiptapExtension as TableRow } from '~/content_editor/extensions/table_row'; import { createTestEditor, mockChainedCommands } from '../test_utils'; describe('content_editor/components/toolbar_table_button', () => { @@ -23,9 +19,7 @@ describe('content_editor/components/toolbar_table_button', () => { const getNumButtons = () => findDropdown().findAllComponents(GlButton).length; beforeEach(() => { - editor = createTestEditor({ - extensions: [Table, TableCell, TableRow, TableHeader], - }); + editor = createTestEditor(); buildWrapper(); }); diff --git a/spec/frontend/content_editor/components/toolbar_text_style_dropdown_spec.js b/spec/frontend/content_editor/components/toolbar_text_style_dropdown_spec.js index 9a46e27404f..8c98fe95bd4 100644 --- a/spec/frontend/content_editor/components/toolbar_text_style_dropdown_spec.js +++ b/spec/frontend/content_editor/components/toolbar_text_style_dropdown_spec.js @@ -2,7 +2,7 @@ import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import ToolbarTextStyleDropdown from '~/content_editor/components/toolbar_text_style_dropdown.vue'; import { TEXT_STYLE_DROPDOWN_ITEMS } from '~/content_editor/constants'; -import { tiptapExtension as Heading } from '~/content_editor/extensions/heading'; +import Heading from '~/content_editor/extensions/heading'; import { createTestEditor, mockChainedCommands } from '../test_utils'; describe('content_editor/components/toolbar_headings_dropdown', () => { diff --git a/spec/frontend/content_editor/extensions/code_block_highlight_spec.js b/spec/frontend/content_editor/extensions/code_block_highlight_spec.js index cc695ffe241..79e55db30cd 100644 --- a/spec/frontend/content_editor/extensions/code_block_highlight_spec.js +++ b/spec/frontend/content_editor/extensions/code_block_highlight_spec.js @@ -1,4 +1,4 @@ -import { tiptapExtension as CodeBlockHighlight } from '~/content_editor/extensions/code_block_highlight'; +import CodeBlockHighlight from '~/content_editor/extensions/code_block_highlight'; import { loadMarkdownApiResult } from '../markdown_processing_examples'; import { createTestEditor } from '../test_utils'; diff --git a/spec/frontend/content_editor/extensions/hard_break_spec.js b/spec/frontend/content_editor/extensions/hard_break_spec.js index ebd58e60b0c..9e2e28b6e72 100644 --- a/spec/frontend/content_editor/extensions/hard_break_spec.js +++ b/spec/frontend/content_editor/extensions/hard_break_spec.js @@ -1,4 +1,4 @@ -import { tiptapExtension as HardBreak } from '~/content_editor/extensions/hard_break'; +import HardBreak from '~/content_editor/extensions/hard_break'; import { createTestEditor, createDocBuilder } from '../test_utils'; describe('content_editor/extensions/hard_break', () => { diff --git a/spec/frontend/content_editor/extensions/image_spec.js b/spec/frontend/content_editor/extensions/image_spec.js index 922966b813a..09b7274839e 100644 --- a/spec/frontend/content_editor/extensions/image_spec.js +++ b/spec/frontend/content_editor/extensions/image_spec.js @@ -2,7 +2,7 @@ import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; import { once } from 'lodash'; import waitForPromises from 'helpers/wait_for_promises'; -import * as Image from '~/content_editor/extensions/image'; +import Image from '~/content_editor/extensions/image'; import httpStatus from '~/lib/utils/http_status'; import { loadMarkdownApiResult } from '../markdown_processing_examples'; import { createTestEditor, createDocBuilder } from '../test_utils'; @@ -24,16 +24,16 @@ describe('content_editor/extensions/image', () => { .fn() .mockResolvedValue(loadMarkdownApiResult('project_wiki_attachment_image').body); - const { tiptapExtension } = Image.configure({ renderMarkdown, uploadsPath }); - - tiptapEditor = createTestEditor({ extensions: [tiptapExtension] }); + tiptapEditor = createTestEditor({ + extensions: [Image.configure({ renderMarkdown, uploadsPath })], + }); ({ builders: { doc, p, image }, eq, } = createDocBuilder({ tiptapEditor, - names: { image: { nodeType: tiptapExtension.name } }, + names: { image: { nodeType: Image.name } }, })); mock = new MockAdapter(axios); diff --git a/spec/frontend/content_editor/services/build_serializer_config_spec.js b/spec/frontend/content_editor/services/build_serializer_config_spec.js deleted file mode 100644 index 532e0493830..00000000000 --- a/spec/frontend/content_editor/services/build_serializer_config_spec.js +++ /dev/null @@ -1,38 +0,0 @@ -import * as Blockquote from '~/content_editor/extensions/blockquote'; -import * as Bold from '~/content_editor/extensions/bold'; -import * as Dropcursor from '~/content_editor/extensions/dropcursor'; -import * as Paragraph from '~/content_editor/extensions/paragraph'; - -import buildSerializerConfig from '~/content_editor/services/build_serializer_config'; - -describe('content_editor/services/build_serializer_config', () => { - describe('given one or more content editor extensions', () => { - it('creates a serializer config that collects all extension serializers by type', () => { - const extensions = [Bold, Blockquote, Paragraph]; - const serializerConfig = buildSerializerConfig(extensions); - - extensions.forEach(({ tiptapExtension, serializer }) => { - const { name, type } = tiptapExtension; - expect(serializerConfig[`${type}s`][name]).toBe(serializer); - }); - }); - }); - - describe('given an extension without serializer', () => { - it('does not include the extension in the serializer config', () => { - const serializerConfig = buildSerializerConfig([Dropcursor]); - - expect(serializerConfig.marks[Dropcursor.tiptapExtension.name]).toBe(undefined); - expect(serializerConfig.nodes[Dropcursor.tiptapExtension.name]).toBe(undefined); - }); - }); - - describe('given no extensions', () => { - it('creates an empty serializer config', () => { - expect(buildSerializerConfig()).toStrictEqual({ - marks: {}, - nodes: {}, - }); - }); - }); -}); diff --git a/spec/frontend/content_editor/services/create_content_editor_spec.js b/spec/frontend/content_editor/services/create_content_editor_spec.js index b614efd954a..a6d52ddabef 100644 --- a/spec/frontend/content_editor/services/create_content_editor_spec.js +++ b/spec/frontend/content_editor/services/create_content_editor_spec.js @@ -32,13 +32,15 @@ describe('content_editor/services/create_editor', () => { it('allows providing external content editor extensions', async () => { const labelReference = 'this is a ~group::editor'; + const { tiptapExtension, serializer } = createTestContentEditorExtension(); renderMarkdown.mockReturnValueOnce( '

this is a group::editor

', ); editor = createContentEditor({ renderMarkdown, - extensions: [createTestContentEditorExtension()], + extensions: [tiptapExtension], + serializerConfig: { nodes: { [tiptapExtension.name]: serializer } }, }); await editor.setSerializedContent(labelReference); diff --git a/spec/frontend/content_editor/services/track_input_rules_and_shortcuts_spec.js b/spec/frontend/content_editor/services/track_input_rules_and_shortcuts_spec.js index 64f3d8df6e0..afe09a75f16 100644 --- a/spec/frontend/content_editor/services/track_input_rules_and_shortcuts_spec.js +++ b/spec/frontend/content_editor/services/track_input_rules_and_shortcuts_spec.js @@ -4,10 +4,10 @@ import { INPUT_RULE_TRACKING_ACTION, CONTENT_EDITOR_TRACKING_LABEL, } from '~/content_editor/constants'; -import { tiptapExtension as BulletList } from '~/content_editor/extensions/bullet_list'; -import { tiptapExtension as CodeBlockLowlight } from '~/content_editor/extensions/code_block_highlight'; -import { tiptapExtension as Heading } from '~/content_editor/extensions/heading'; -import { tiptapExtension as ListItem } from '~/content_editor/extensions/list_item'; +import BulletList from '~/content_editor/extensions/bullet_list'; +import CodeBlockLowlight from '~/content_editor/extensions/code_block_highlight'; +import Heading from '~/content_editor/extensions/heading'; +import ListItem from '~/content_editor/extensions/list_item'; import trackInputRulesAndShortcuts from '~/content_editor/services/track_input_rules_and_shortcuts'; import { ENTER_KEY, BACKSPACE_KEY } from '~/lib/utils/keys'; import { createTestEditor } from '../test_utils'; diff --git a/spec/frontend/vue_shared/components/papa_parse_alert_spec.js b/spec/frontend/vue_shared/components/papa_parse_alert_spec.js new file mode 100644 index 00000000000..9be2de17d01 --- /dev/null +++ b/spec/frontend/vue_shared/components/papa_parse_alert_spec.js @@ -0,0 +1,44 @@ +import { GlAlert } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import { nextTick } from 'vue'; +import PapaParseAlert from '~/vue_shared/components/papa_parse_alert.vue'; + +describe('app/assets/javascripts/vue_shared/components/papa_parse_alert.vue', () => { + let wrapper; + + const createComponent = ({ errorMessages } = {}) => { + wrapper = shallowMount(PapaParseAlert, { + propsData: { + papaParseErrors: errorMessages, + }, + }); + }; + + const findAlert = () => wrapper.findComponent(GlAlert); + + afterEach(() => { + wrapper.destroy(); + }); + + it('should render alert with correct props', async () => { + createComponent({ errorMessages: [{ code: 'MissingQuotes' }] }); + await nextTick; + + expect(findAlert().props()).toMatchObject({ + variant: 'danger', + }); + expect(findAlert().text()).toContain( + 'Failed to render the CSV file for the following reasons:', + ); + expect(findAlert().text()).toContain('Quoted field unterminated'); + }); + + it('should render original message if no translation available', async () => { + createComponent({ + errorMessages: [{ code: 'NotDefined', message: 'Error code is undefined' }], + }); + await nextTick; + + expect(findAlert().text()).toContain('Error code is undefined'); + }); +}); diff --git a/spec/policies/release_policy_spec.rb b/spec/policies/release_policy_spec.rb index 25468ae2ea2..5a34b1f4236 100644 --- a/spec/policies/release_policy_spec.rb +++ b/spec/policies/release_policy_spec.rb @@ -17,29 +17,6 @@ RSpec.describe ReleasePolicy, :request_store do subject { described_class.new(user, release) } - context 'when the evalute_protected_tag_for_release_permissions feature flag is disabled' do - before do - stub_feature_flags(evalute_protected_tag_for_release_permissions: false) - end - - it 'allows the user to create and update a release' do - is_expected.to be_allowed(:create_release) - is_expected.to be_allowed(:update_release) - end - - it 'prevents the user from destroying a release' do - is_expected.to be_disallowed(:destroy_release) - end - - context 'when the user is maintainer' do - let(:user) { maintainer } - - it 'allows the user to destroy a release' do - is_expected.to be_allowed(:destroy_release) - end - end - end - context 'when the user has access to the protected tag' do let_it_be(:protected_tag) { create(:protected_tag, :developers_can_create, name: release.tag, project: project) } diff --git a/spec/services/releases/create_service_spec.rb b/spec/services/releases/create_service_spec.rb index bf28fde3d90..7287825a0be 100644 --- a/spec/services/releases/create_service_spec.rb +++ b/spec/services/releases/create_service_spec.rb @@ -44,21 +44,6 @@ RSpec.describe Releases::CreateService do it_behaves_like 'a successful release creation' - context 'when tag is protected and user does not have access to it' do - let!(:protected_tag) { create(:protected_tag, :no_one_can_create, name: '*', project: project) } - - it 'track the error event' do - stub_feature_flags(evalute_protected_tag_for_release_permissions: false) - - expect(Gitlab::ErrorTracking).to receive(:log_exception).with( - kind_of(described_class::ReleaseProtectedTagAccessError), - project_id: project.id, - user_id: user.id) - - service.execute - end - end - context 'when the tag does not exist' do let(:tag_name) { 'non-exist-tag' } diff --git a/spec/services/releases/destroy_service_spec.rb b/spec/services/releases/destroy_service_spec.rb index 38cdcef3825..bc5bff0b31d 100644 --- a/spec/services/releases/destroy_service_spec.rb +++ b/spec/services/releases/destroy_service_spec.rb @@ -28,21 +28,6 @@ RSpec.describe Releases::DestroyService do it 'returns the destroyed object' do is_expected.to include(status: :success, release: release) end - - context 'when tag is protected and user does not have access to it' do - let!(:protected_tag) { create(:protected_tag, :no_one_can_create, name: '*', project: project) } - - it 'track the error event' do - stub_feature_flags(evalute_protected_tag_for_release_permissions: false) - - expect(Gitlab::ErrorTracking).to receive(:log_exception).with( - kind_of(described_class::ReleaseProtectedTagAccessError), - project_id: project.id, - user_id: user.id) - - service.execute - end - end end context 'when tag does not exist in the repository' do diff --git a/spec/services/releases/update_service_spec.rb b/spec/services/releases/update_service_spec.rb index 96b562a8071..932a7fab5ec 100644 --- a/spec/services/releases/update_service_spec.rb +++ b/spec/services/releases/update_service_spec.rb @@ -38,21 +38,6 @@ RSpec.describe Releases::UpdateService do service.execute end - context 'when tag is protected and user does not have access to it' do - let!(:protected_tag) { create(:protected_tag, :no_one_can_create, name: '*', project: project) } - - it 'track the error event' do - stub_feature_flags(evalute_protected_tag_for_release_permissions: false) - - expect(Gitlab::ErrorTracking).to receive(:log_exception).with( - kind_of(described_class::ReleaseProtectedTagAccessError), - project_id: project.id, - user_id: user.id) - - service.execute - end - end - context 'when the tag does not exists' do let(:tag_name) { 'foobar' } diff --git a/spec/tooling/danger/project_helper_spec.rb b/spec/tooling/danger/project_helper_spec.rb index 8bcfac5a699..1d95fd1fd6b 100644 --- a/spec/tooling/danger/project_helper_spec.rb +++ b/spec/tooling/danger/project_helper_spec.rb @@ -77,7 +77,7 @@ RSpec.describe Tooling::Danger::ProjectHelper do 'ee/spec/frontend/bar' | [:frontend] 'ee/spec/frontend_integration/bar' | [:frontend] - '.gitlab/ci/frontend.gitlab-ci.yml' | %i[frontend engineering_productivity] + '.gitlab/ci/frontend.gitlab-ci.yml' | %i[frontend tooling] 'app/models/foo' | [:backend] 'bin/foo' | [:backend] @@ -113,22 +113,22 @@ RSpec.describe Tooling::Danger::ProjectHelper do 'Rakefile' | [:backend] 'FOO_VERSION' | [:backend] - 'Dangerfile' | [:engineering_productivity] - 'danger/bundle_size/Dangerfile' | [:engineering_productivity] - 'ee/danger/bundle_size/Dangerfile' | [:engineering_productivity] - 'danger/bundle_size/' | [:engineering_productivity] - 'ee/danger/bundle_size/' | [:engineering_productivity] - '.gitlab-ci.yml' | [:engineering_productivity] - '.gitlab/ci/cng.gitlab-ci.yml' | [:engineering_productivity] - '.gitlab/ci/ee-specific-checks.gitlab-ci.yml' | [:engineering_productivity] - 'scripts/foo' | [:engineering_productivity] - 'tooling/danger/foo' | [:engineering_productivity] - 'ee/tooling/danger/foo' | [:engineering_productivity] - 'lefthook.yml' | [:engineering_productivity] - '.editorconfig' | [:engineering_productivity] - 'tooling/bin/find_foss_tests' | [:engineering_productivity] - '.codeclimate.yml' | [:engineering_productivity] - '.gitlab/CODEOWNERS' | [:engineering_productivity] + 'Dangerfile' | [:tooling] + 'danger/bundle_size/Dangerfile' | [:tooling] + 'ee/danger/bundle_size/Dangerfile' | [:tooling] + 'danger/bundle_size/' | [:tooling] + 'ee/danger/bundle_size/' | [:tooling] + '.gitlab-ci.yml' | [:tooling] + '.gitlab/ci/cng.gitlab-ci.yml' | [:tooling] + '.gitlab/ci/ee-specific-checks.gitlab-ci.yml' | [:tooling] + 'scripts/foo' | [:tooling] + 'tooling/danger/foo' | [:tooling] + 'ee/tooling/danger/foo' | [:tooling] + 'lefthook.yml' | [:tooling] + '.editorconfig' | [:tooling] + 'tooling/bin/find_foss_tests' | [:tooling] + '.codeclimate.yml' | [:tooling] + '.gitlab/CODEOWNERS' | [:tooling] 'lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml' | [:ci_template] 'lib/gitlab/ci/templates/dotNET-Core.yml' | [:ci_template] diff --git a/tooling/danger/project_helper.rb b/tooling/danger/project_helper.rb index 8151e074096..4bcc398fa52 100644 --- a/tooling/danger/project_helper.rb +++ b/tooling/danger/project_helper.rb @@ -74,7 +74,7 @@ module Tooling %r{(\A|/)( \.gitlab/ci/frontend\.gitlab-ci\.yml - )\z}x => %i[frontend engineering_productivity], + )\z}x => %i[frontend tooling], %r{\A(ee/)?db/(geo/)?(migrate|post_migrate)/} => [:database, :migration], %r{\A(ee/)?db/(?!fixtures)[^/]+} => [:database], @@ -84,16 +84,16 @@ module Tooling %r{\A(ee/)?app/finders/} => [:database, :backend], %r{\Arubocop/cop/migration(/|\.rb)} => :database, - %r{\A(\.gitlab-ci\.yml\z|\.gitlab\/ci)} => :engineering_productivity, - %r{\A\.codeclimate\.yml\z} => :engineering_productivity, - %r{\Alefthook.yml\z} => :engineering_productivity, - %r{\A\.editorconfig\z} => :engineering_productivity, - %r{Dangerfile\z} => :engineering_productivity, - %r{\A(ee/)?(danger/|tooling/danger/)} => :engineering_productivity, - %r{\A(ee/)?scripts/} => :engineering_productivity, - %r{\Atooling/} => :engineering_productivity, - %r{(CODEOWNERS)} => :engineering_productivity, - %r{(tests.yml)} => :engineering_productivity, + %r{\A(\.gitlab-ci\.yml\z|\.gitlab\/ci)} => :tooling, + %r{\A\.codeclimate\.yml\z} => :tooling, + %r{\Alefthook.yml\z} => :tooling, + %r{\A\.editorconfig\z} => :tooling, + %r{Dangerfile\z} => :tooling, + %r{\A(ee/)?(danger/|tooling/danger/)} => :tooling, + %r{\A(ee/)?scripts/} => :tooling, + %r{\Atooling/} => :tooling, + %r{(CODEOWNERS)} => :tooling, + %r{(tests.yml)} => :tooling, %r{\Alib/gitlab/ci/templates} => :ci_template, -- cgit v1.2.3