summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.rubocop_manual_todo.yml67
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--app/assets/javascripts/monitoring/stores/embed_group/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/labels/edit/index.js2
-rw-r--r--app/serializers/test_suite_comparer_entity.rb12
-rw-r--r--app/views/dashboard/_groups_head.html.haml2
-rw-r--r--app/views/dashboard/_projects_head.html.haml2
-rw-r--r--app/views/dashboard/_snippets_head.html.haml2
-rw-r--r--changelogs/unreleased/ab-remove-minergate-trigger.yml5
-rw-r--r--changelogs/unreleased/btn-confirm-home.yml5
-rw-r--r--changelogs/unreleased/dry-up-notes-build-service-spec.yml5
-rw-r--r--config/feature_flags/development/saml_group_links.yml8
-rw-r--r--danger/product_intelligence/Dangerfile24
-rw-r--r--db/migrate/20210223105256_remove_minergate_trigger_on_git_lab_com.rb28
-rw-r--r--db/schema_migrations/202102231052561
-rw-r--r--doc/ci/git_submodules.md96
-rw-r--r--doc/topics/git/index.md2
-rw-r--r--doc/user/application_security/security_dashboard/index.md2
-rw-r--r--lib/release_highlights/validator/entry.rb2
-rw-r--r--package.json2
-rw-r--r--rubocop/cop/graphql/descriptions.rb52
-rwxr-xr-xscripts/verify-tff-mapping6
-rw-r--r--spec/features/dashboard/group_spec.rb2
-rw-r--r--spec/fixtures/api/schemas/entities/test_suite_comparer.json9
-rw-r--r--spec/lib/gitlab/ci/variables/collection/sort_spec.rb1
-rw-r--r--spec/lib/release_highlights/validator/entry_spec.rb19
-rw-r--r--spec/lib/release_highlights/validator_spec.rb5
-rw-r--r--spec/rubocop/cop/graphql/descriptions_spec.rb44
-rw-r--r--spec/serializers/test_suite_comparer_entity_spec.rb44
-rw-r--r--spec/services/notes/build_service_spec.rb125
-rw-r--r--tests.yml4
-rw-r--r--tooling/danger/helper.rb1
-rw-r--r--yarn.lock29
33 files changed, 404 insertions, 208 deletions
diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml
index 06cf8b95db3..d631a7a5c5c 100644
--- a/.rubocop_manual_todo.yml
+++ b/.rubocop_manual_todo.yml
@@ -10,6 +10,73 @@
# - guidelines for use found in
# https://docs.gitlab.com/ee/development/contributing/style_guides.html#resolving-rubocop-exceptions.
+# WIP See https://gitlab.com/gitlab-org/gitlab/-/issues/322903
+Graphql/Descriptions:
+ Exclude:
+ - 'app/graphql/types/access_level_enum.rb'
+ - 'app/graphql/types/admin/analytics/usage_trends/measurement_identifier_enum.rb'
+ - 'app/graphql/types/alert_management/alert_sort_enum.rb'
+ - 'app/graphql/types/alert_management/domain_filter_enum.rb'
+ - 'app/graphql/types/alert_management/integration_type_enum.rb'
+ - 'app/graphql/types/base_enum.rb'
+ - 'app/graphql/types/ci/config/status_enum.rb'
+ - 'app/graphql/types/ci/job_artifact_file_type_enum.rb'
+ - 'app/graphql/types/ci/pipeline_config_source_enum.rb'
+ - 'app/graphql/types/ci/pipeline_status_enum.rb'
+ - 'app/graphql/types/commit_action_mode_enum.rb'
+ - 'app/graphql/types/commit_encoding_enum.rb'
+ - 'app/graphql/types/container_expiration_policy_cadence_enum.rb'
+ - 'app/graphql/types/container_expiration_policy_keep_enum.rb'
+ - 'app/graphql/types/container_expiration_policy_older_than_enum.rb'
+ - 'app/graphql/types/container_repository_sort_enum.rb'
+ - 'app/graphql/types/design_management/design_version_event_enum.rb'
+ - 'app/graphql/types/error_tracking/sentry_error_status_enum.rb'
+ - 'app/graphql/types/issuable_sort_enum.rb'
+ - 'app/graphql/types/issuable_state_enum.rb'
+ - 'app/graphql/types/issue_sort_enum.rb'
+ - 'app/graphql/types/issue_state_event_enum.rb'
+ - 'app/graphql/types/merge_request_sort_enum.rb'
+ - 'app/graphql/types/merge_request_state_enum.rb'
+ - 'app/graphql/types/milestone_state_enum.rb'
+ - 'app/graphql/types/mutation_operation_mode_enum.rb'
+ - 'app/graphql/types/notes/position_type_enum.rb'
+ - 'app/graphql/types/packages/package_type_enum.rb'
+ - 'app/graphql/types/projects/namespace_project_sort_enum.rb'
+ - 'app/graphql/types/release_sort_enum.rb'
+ - 'app/graphql/types/snippets/blob_action_enum.rb'
+ - 'app/graphql/types/snippets/type_enum.rb'
+ - 'app/graphql/types/snippets/visibility_scopes_enum.rb'
+ - 'app/graphql/types/sort_enum.rb'
+ - 'app/graphql/types/todo_action_enum.rb'
+ - 'app/graphql/types/todo_target_enum.rb'
+ - 'app/graphql/types/tree/type_enum.rb'
+ - 'app/graphql/types/user_state_enum.rb'
+ - 'ee/app/graphql/ee/types/issue_sort_enum.rb'
+ - 'ee/app/graphql/ee/types/list_limit_metric_enum.rb'
+ - 'ee/app/graphql/ee/types/todo_target_enum.rb'
+ - 'ee/app/graphql/types/alert_management/payload_alert_field_name_enum.rb'
+ - 'ee/app/graphql/types/alert_management/payload_alert_field_type_enum.rb'
+ - 'ee/app/graphql/types/boards/epic_wildcard_id_enum.rb'
+ - 'ee/app/graphql/types/boards/iteration_wildcard_id_enum.rb'
+ - 'ee/app/graphql/types/dast_site_profile_validation_status_enum.rb'
+ - 'ee/app/graphql/types/dast_site_validation_strategy_enum.rb'
+ - 'ee/app/graphql/types/epic_sort_enum.rb'
+ - 'ee/app/graphql/types/epic_state_enum.rb'
+ - 'ee/app/graphql/types/epic_state_event_enum.rb'
+ - 'ee/app/graphql/types/geo/registry_state_enum.rb'
+ - 'ee/app/graphql/types/health_status_enum.rb'
+ - 'ee/app/graphql/types/iteration_state_enum.rb'
+ - 'ee/app/graphql/types/move_type_enum.rb'
+ - 'ee/app/graphql/types/requirements_management/requirement_state_enum.rb'
+ - 'ee/app/graphql/types/requirements_management/test_report_state_enum.rb'
+ - 'ee/app/graphql/types/security_scanner_type_enum.rb'
+ - 'ee/app/graphql/types/vulnerability/issue_link_type_enum.rb'
+ - 'ee/app/graphql/types/vulnerability_grade_enum.rb'
+ - 'ee/app/graphql/types/vulnerability_report_type_enum.rb'
+ - 'ee/app/graphql/types/vulnerability_severity_enum.rb'
+ - 'ee/app/graphql/types/vulnerability_sort_enum.rb'
+ - 'ee/app/graphql/types/vulnerability_state_enum.rb'
+
# WIP See https://gitlab.com/gitlab-org/gitlab/-/issues/267606
FactoryBot/InlineAssociation:
Exclude:
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 66068a748a9..0ba19ac773f 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-5d9c71d8d7188bd58f272dc62a7939ece747909d
+7991d3def6026a252828ea6bca74df20d4532b9b
diff --git a/app/assets/javascripts/monitoring/stores/embed_group/index.js b/app/assets/javascripts/monitoring/stores/embed_group/index.js
index 773bca9f87e..66c65adc413 100644
--- a/app/assets/javascripts/monitoring/stores/embed_group/index.js
+++ b/app/assets/javascripts/monitoring/stores/embed_group/index.js
@@ -20,5 +20,3 @@ export const createStore = () =>
},
},
});
-
-export default createStore();
diff --git a/app/assets/javascripts/pages/projects/labels/edit/index.js b/app/assets/javascripts/pages/projects/labels/edit/index.js
index 83d6ac9fd14..3b7562deed9 100644
--- a/app/assets/javascripts/pages/projects/labels/edit/index.js
+++ b/app/assets/javascripts/pages/projects/labels/edit/index.js
@@ -1,3 +1,3 @@
import Labels from 'ee_else_ce/labels';
-document.addEventListener('DOMContentLoaded', () => new Labels());
+new Labels(); // eslint-disable-line no-new
diff --git a/app/serializers/test_suite_comparer_entity.rb b/app/serializers/test_suite_comparer_entity.rb
index aab805f9598..cfa728c01be 100644
--- a/app/serializers/test_suite_comparer_entity.rb
+++ b/app/serializers/test_suite_comparer_entity.rb
@@ -34,4 +34,16 @@ class TestSuiteComparerEntity < Grape::Entity
expose :resolved_errors, using: TestCaseEntity do |suite|
suite.limited_tests.resolved_errors
end
+
+ expose :suite_errors do |suite|
+ head_suite_error = suite.head_suite.suite_error
+ base_suite_error = suite.base_suite.suite_error
+
+ next unless head_suite_error.present? || base_suite_error.present?
+
+ {
+ head: head_suite_error,
+ base: base_suite_error
+ }
+ end
end
diff --git a/app/views/dashboard/_groups_head.html.haml b/app/views/dashboard/_groups_head.html.haml
index c24fe5c6307..b92f35c108c 100644
--- a/app/views/dashboard/_groups_head.html.haml
+++ b/app/views/dashboard/_groups_head.html.haml
@@ -3,7 +3,7 @@
- if current_user.can_create_group?
.page-title-controls
- = link_to _("New group"), new_group_path, class: "gl-button btn btn-success"
+ = link_to _("New group"), new_group_path, class: "gl-button btn btn-confirm", data: { testid: "new-group-button" }
.top-area
%ul.nav-links.mobile-separator.nav.nav-tabs
diff --git a/app/views/dashboard/_projects_head.html.haml b/app/views/dashboard/_projects_head.html.haml
index 6c994f3b230..57c0801074b 100644
--- a/app/views/dashboard/_projects_head.html.haml
+++ b/app/views/dashboard/_projects_head.html.haml
@@ -9,7 +9,7 @@
- if current_user.can_create_project?
.page-title-controls
- = link_to _("New project"), new_project_path, class: "gl-button btn btn-success"
+ = link_to _("New project"), new_project_path, class: "gl-button btn btn-confirm"
.top-area.scrolling-tabs-container.inner-page-scroll-tabs
.fade-left= sprite_icon('chevron-lg-left', size: 12)
diff --git a/app/views/dashboard/_snippets_head.html.haml b/app/views/dashboard/_snippets_head.html.haml
index 2640d483615..e96b5695ddc 100644
--- a/app/views/dashboard/_snippets_head.html.haml
+++ b/app/views/dashboard/_snippets_head.html.haml
@@ -4,7 +4,7 @@
- if current_user && current_user.snippets.any? || @snippets.any?
.page-title-controls
- if can?(current_user, :create_snippet)
- = link_to _("New snippet"), new_snippet_path, class: "gl-button btn btn-success", title: _("New snippet")
+ = link_to _("New snippet"), new_snippet_path, class: "gl-button btn btn-confirm", title: _("New snippet")
.top-area
%ul.nav-links.nav.nav-tabs
diff --git a/changelogs/unreleased/ab-remove-minergate-trigger.yml b/changelogs/unreleased/ab-remove-minergate-trigger.yml
new file mode 100644
index 00000000000..fd75be2845b
--- /dev/null
+++ b/changelogs/unreleased/ab-remove-minergate-trigger.yml
@@ -0,0 +1,5 @@
+---
+title: Remove historic minergate trigger (GitLab.com only)
+merge_request: 54910
+author:
+type: other
diff --git a/changelogs/unreleased/btn-confirm-home.yml b/changelogs/unreleased/btn-confirm-home.yml
new file mode 100644
index 00000000000..a8b063fc5f3
--- /dev/null
+++ b/changelogs/unreleased/btn-confirm-home.yml
@@ -0,0 +1,5 @@
+---
+title: Remove deprecated button variant in groups, projects and snippets
+merge_request: 54747
+author: Yogi (@yo)
+type: changed
diff --git a/changelogs/unreleased/dry-up-notes-build-service-spec.yml b/changelogs/unreleased/dry-up-notes-build-service-spec.yml
new file mode 100644
index 00000000000..4aadaaa6030
--- /dev/null
+++ b/changelogs/unreleased/dry-up-notes-build-service-spec.yml
@@ -0,0 +1,5 @@
+---
+title: Dry up notes build service spec
+merge_request: 54632
+author: Lee Tickett @leetickett
+type: other
diff --git a/config/feature_flags/development/saml_group_links.yml b/config/feature_flags/development/saml_group_links.yml
deleted file mode 100644
index 3b427bd83fa..00000000000
--- a/config/feature_flags/development/saml_group_links.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: saml_group_links
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/45080
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/267020
-milestone: '13.6'
-type: development
-group: group::access
-default_enabled: true
diff --git a/danger/product_intelligence/Dangerfile b/danger/product_intelligence/Dangerfile
index e9f6a867fec..5709e5eb83f 100644
--- a/danger/product_intelligence/Dangerfile
+++ b/danger/product_intelligence/Dangerfile
@@ -37,8 +37,8 @@ tracking_files = [
tracking_changed_files = all_changed_files & tracking_files
usage_data_changed_files = all_changed_files.grep(%r{(usage_data)})
-metrics_changed_files = all_changed_files.grep(%r{((ee/)?config/metrics/.*\.yml)})
dictionary_changed_file = all_changed_files.grep(%r{(doc/development/usage_ping/dictionary.md)})
+metrics_changed_files = all_changed_files.grep(%r{((ee/)?config/metrics/.*\.yml)})
def matching_files?(file, extension:, pattern:)
return unless file.end_with?(extension)
@@ -52,6 +52,16 @@ js_patterns = Regexp.union(
'data-track-event'
)
+dictionary_pattern = Regexp.union(
+ 'key_path:',
+ 'description:',
+ 'product_section:',
+ 'product_stage:',
+ 'product_group:',
+ 'status:',
+ 'tier:'
+)
+
snowplow_changed_files = all_changed_files.select do |file|
matching_files?(file, extension: '.rb', pattern: %r{Gitlab::Tracking\.event}) ||
matching_files?(file, extension: '.js', pattern: js_patterns) ||
@@ -59,7 +69,15 @@ snowplow_changed_files = all_changed_files.select do |file|
matching_files?(file, extension: '.haml', pattern: %r{data: \{ track})
end
-matching_changed_files = usage_data_changed_files + tracking_changed_files + metrics_changed_files + dictionary_changed_file + snowplow_changed_files
+required_dictionary_update_changed_files = dictionary_changed_file.select do |file|
+ matching_files?(file, extension: '.yml', pattern: dictionary_pattern)
+end
+
+matching_changed_files = usage_data_changed_files +
+ tracking_changed_files +
+ metrics_changed_files +
+ dictionary_changed_file +
+ snowplow_changed_files
if matching_changed_files.any?
@@ -71,7 +89,7 @@ if matching_changed_files.any?
warn format(CHANGED_FILES_MESSAGE, changed_files: helper.markdown_list(matching_changed_files), engineers_group: mention)
- fail format(UPDATE_DICTIONARY_MESSAGE) if metrics_changed_files.any? && dictionary_changed_file.empty?
+ fail format(UPDATE_DICTIONARY_MESSAGE) if metrics_changed_files.any? && required_dictionary_update_changed_files.empty?
labels = ['product intelligence']
labels << 'product intelligence::review pending' unless helper.mr_has_labels?('product intelligence::approved')
diff --git a/db/migrate/20210223105256_remove_minergate_trigger_on_git_lab_com.rb b/db/migrate/20210223105256_remove_minergate_trigger_on_git_lab_com.rb
new file mode 100644
index 00000000000..b5f018efa59
--- /dev/null
+++ b/db/migrate/20210223105256_remove_minergate_trigger_on_git_lab_com.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+class RemoveMinergateTriggerOnGitLabCom < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ return unless Gitlab.com?
+
+ with_lock_retries do
+ execute <<~SQL
+ DROP TRIGGER IF EXISTS ci_builds_block_minergate ON ci_builds;
+ SQL
+ end
+
+ execute <<~SQL
+ DROP FUNCTION IF EXISTS make_build_to_be_stuck_with_lock_version();
+ DROP FUNCTION IF EXISTS make_build_to_be_stuck();
+ SQL
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/schema_migrations/20210223105256 b/db/schema_migrations/20210223105256
new file mode 100644
index 00000000000..cfee761bbc1
--- /dev/null
+++ b/db/schema_migrations/20210223105256
@@ -0,0 +1 @@
+5fa0e89f9d7715309f6fd9808a07c34bcca0d556a2a4a2841f419b3279db8759 \ No newline at end of file
diff --git a/doc/ci/git_submodules.md b/doc/ci/git_submodules.md
index d9a40c1feb6..01df4f63c92 100644
--- a/doc/ci/git_submodules.md
+++ b/doc/ci/git_submodules.md
@@ -5,38 +5,23 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
-# Using Git submodules with GitLab CI
+# Using Git submodules with GitLab CI/CD
-> **Notes:**
->
-> - GitLab 8.12 introduced a new [CI job permissions model](../user/project/new_ci_build_permissions_model.md) and you
-> are encouraged to upgrade your GitLab instance if you haven't done already.
-> If you are **not** using GitLab 8.12 or higher, you would need to work your way
-> around submodules in order to access the sources of e.g., `gitlab.com/group/project`
-> with the use of [SSH keys](ssh_keys/index.md).
-> - With GitLab 8.12 onward, your permissions are used to evaluate what a CI job
-> can access. More information about how this system works can be found in the
-> [Jobs permissions model](../user/permissions.md#job-permissions).
-> - The HTTP(S) Git protocol [must be enabled](../user/admin_area/settings/visibility_and_access_controls.md#enabled-git-access-protocols) in your GitLab instance.
+Use [Git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules) to keep
+a Git repository as a subdirectory of another Git repository. You can clone another
+repository into your project and keep your commits separate.
-## Configuring the `.gitmodules` file
+## Configure the `.gitmodules` file
-If dealing with [Git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules), your project probably has a file
-named `.gitmodules`.
+When you use Git submodules, your project should have a file named `.gitmodules`.
+You might need to modify it to work in a GitLab CI/CD job.
-Let's consider the following example:
+For example, your `.gitmodules` configuration might look like the following if:
-1. Your project is located at `https://gitlab.com/secret-group/my-project`.
-1. To checkout your sources you usually use an SSH address like
- `git@gitlab.com:secret-group/my-project.git`.
-1. Your project depends on `https://gitlab.com/group/project`, which you want
- to include as a submodule.
-
-If you are using GitLab 8.12+ and your submodule is on the same GitLab server,
-you must update your `.gitmodules` file to use **relative URLs**.
-Since Git allows the usage of relative URLs for your `.gitmodules` configuration,
-this easily allows you to use HTTP(S) for cloning all your CI jobs and SSH
-for all your local checkouts. The `.gitmodules` would look like:
+- Your project is located at `https://gitlab.com/secret-group/my-project`.
+- Your project depends on `https://gitlab.com/group/project`, which you want
+ to include as a submodule.
+- You check out your sources with an SSH address like `git@gitlab.com:secret-group/my-project.git`.
```ini
[submodule "project"]
@@ -44,14 +29,16 @@ for all your local checkouts. The `.gitmodules` would look like:
url = ../../group/project.git
```
-The above configuration instructs Git to automatically deduce the URL that
-should be used when cloning sources. Whether you use HTTP(S) or SSH, Git uses
-that same channel and it makes all your CI jobs use HTTP(S).
-GitLab CI/CD only uses HTTP(S) for cloning your sources, and all your local
-clones continue using SSH.
+When your submodule is on the same GitLab server, you should use relative URLs in
+your `.gitmodules` file. Then you can clone with HTTPS in all your CI/CD jobs. You
+can also use SSH for all your local checkouts.
+
+The above configuration instructs Git to automatically deduce the URL to
+use when cloning sources. Git uses the same configuration for both HTTPS and SSH.
+GitLab CI/CD uses HTTPS for cloning your sources, and you can continue to use SSH
+to clone locally.
-For all other submodules not located on the same GitLab server, use the full
-HTTP(S) protocol URL:
+For submodules not located on the same GitLab server, use the full URL:
```ini
[submodule "project-x"]
@@ -59,45 +46,16 @@ HTTP(S) protocol URL:
url = https://gitserver.com/group/project-x.git
```
-Once `.gitmodules` is correctly configured, you can move on to
-[configuring your `.gitlab-ci.yml`](#using-git-submodules-in-your-ci-jobs).
-
-## Using Git submodules in your CI jobs
+## Use Git submodules in CI/CD jobs
-There are a few steps you need to take in order to make submodules work
-correctly with your CI jobs:
+To make submodules work correctly in CI/CD jobs:
-1. First, make sure you have used [relative URLs](#configuring-the-gitmodules-file)
- for the submodules located in the same GitLab server.
-1. Next, if you are using `gitlab-runner` v1.10+, you can set the
- `GIT_SUBMODULE_STRATEGY` variable to either `normal` or `recursive` to tell
- the runner to fetch your submodules before the job:
+1. Make sure you use [relative URLs](#configure-the-gitmodules-file)
+ for submodules located in the same GitLab server.
+1. You can set the `GIT_SUBMODULE_STRATEGY` variable to either `normal` or `recursive`
+ to tell the runner to [fetch your submodules before the job](runners/README.md#git-submodule-strategy):
```yaml
variables:
GIT_SUBMODULE_STRATEGY: recursive
```
-
- See the [GitLab Runner documentation](runners/README.md#git-submodule-strategy)
- for more details about `GIT_SUBMODULE_STRATEGY`.
-
-1. If you are using an older version of `gitlab-runner`, then use
- `git submodule sync/update` in `before_script`:
-
- ```yaml
- before_script:
- - git submodule sync --recursive
- - git submodule update --init --recursive
- ```
-
- `--recursive` should be used in either both or none (`sync/update`) depending on
- whether you have recursive submodules.
-
-The rationale to set the `sync` and `update` in `before_script` is because of
-the way Git submodules work. On a fresh runner workspace, Git sets the
-submodule URL including the token in `.git/config`
-(or `.git/modules/<submodule>/config`) based on `.gitmodules` and the current
-remote URL. On subsequent jobs on the same runner, `.git/config` is cached
-and already contains a full URL for the submodule, corresponding to the previous
-job, and to **a token from a previous job**. `sync` allows to force updating
-the full URL.
diff --git a/doc/topics/git/index.md b/doc/topics/git/index.md
index d6e1dcf0998..36de660bc18 100644
--- a/doc/topics/git/index.md
+++ b/doc/topics/git/index.md
@@ -84,7 +84,7 @@ The following are advanced topics for those who want to get the most out of Git:
- [Introduction to Git rebase, force-push, and merge conflicts](git_rebase.md)
- [Server Hooks](../../administration/server_hooks.md)
- [Git Attributes](../../user/project/git_attributes.md)
-- Git Submodules: [Using Git submodules with GitLab CI](../../ci/git_submodules.md#using-git-submodules-with-gitlab-ci)
+- Git Submodules: [Using Git submodules with GitLab CI](../../ci/git_submodules.md)
- [Partial Clone](partial_clone.md)
## API
diff --git a/doc/user/application_security/security_dashboard/index.md b/doc/user/application_security/security_dashboard/index.md
index 7f9d60d853b..007581c5d26 100644
--- a/doc/user/application_security/security_dashboard/index.md
+++ b/doc/user/application_security/security_dashboard/index.md
@@ -75,7 +75,7 @@ CSV file containing details of the resources scanned.
At the project level, the Security Dashboard displays a chart with the number of vulnerabilities over time.
Access it by navigating to **Security & Compliance > Security Dashboard**. We display historical
-data up to 365 days.
+data up to 365 days. The chart's data is updated daily.
![Project Security Dashboard](img/project_security_dashboard_chart_v13_6.png)
diff --git a/lib/release_highlights/validator/entry.rb b/lib/release_highlights/validator/entry.rb
index 3c83ca21123..133afcb52ae 100644
--- a/lib/release_highlights/validator/entry.rb
+++ b/lib/release_highlights/validator/entry.rb
@@ -11,7 +11,7 @@ module ReleaseHighlights
validates :title, :body, :stage, presence: true
validates :'self-managed', :'gitlab-com', inclusion: { in: [true, false], message: "must be a boolean" }
- validates :url, :image_url, format: { with: URI::DEFAULT_PARSER.make_regexp, message: 'must be a URL' }
+ validates :url, :image_url, public_url: { dns_rebind_protection: true }
validates :release, numericality: true
validate :validate_published_at
validate :validate_packages
diff --git a/package.json b/package.json
index 05280523aee..7814aa04964 100644
--- a/package.json
+++ b/package.json
@@ -180,7 +180,7 @@
"commander": "^2.18.0",
"custom-jquery-matchers": "^2.1.0",
"docdash": "^1.0.2",
- "eslint": "7.20.0",
+ "eslint": "7.21.0",
"eslint-import-resolver-jest": "3.0.0",
"eslint-import-resolver-webpack": "0.13.0",
"eslint-plugin-jasmine": "4.1.2",
diff --git a/rubocop/cop/graphql/descriptions.rb b/rubocop/cop/graphql/descriptions.rb
index 1585e5c9788..ec233c65874 100644
--- a/rubocop/cop/graphql/descriptions.rb
+++ b/rubocop/cop/graphql/descriptions.rb
@@ -1,26 +1,31 @@
# frozen_string_literal: true
-# This cop checks for missing GraphQL field descriptions.
+# This cop checks for missing GraphQL descriptions and enforces the description style guide:
+# https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#description-style-guide
#
-# @example
+# @examples
#
# # bad
-# class AwfulClass
+# class AwfulType
# field :some_field, GraphQL::STRING_TYPE
# end
#
-# class TerribleClass
+# class TerribleType
# argument :some_argument, GraphQL::STRING_TYPE
# end
#
-# class UngoodClass
+# class UngoodType
# field :some_argument,
# GraphQL::STRING_TYPE,
# description: "A description that does not end in a period"
# end
#
+# class BadEnum
+# value "some_value"
+# end
+#
# # good
-# class GreatClass
+# class GreatType
# argument :some_field,
# GraphQL::STRING_TYPE,
# description: "Well described - a superb description."
@@ -29,6 +34,10 @@
# GraphQL::STRING_TYPE,
# description: "A thorough and compelling description."
# end
+#
+# class GoodEnum
+# value "some_value", "Good description."
+# end
module RuboCop
module Cop
@@ -37,19 +46,26 @@ module RuboCop
MSG_NO_DESCRIPTION = 'Please add a `description` property.'
MSG_NO_PERIOD = '`description` strings must end with a `.`.'
- # ability_field and permission_field set a default description.
- def_node_matcher :field_or_argument?, <<~PATTERN
- (send nil? {:field :argument} ...)
+ def_node_matcher :graphql_describable?, <<~PATTERN
+ (send nil? {:field :argument :value} ...)
+ PATTERN
+
+ def_node_matcher :enum?, <<~PATTERN
+ (send nil? :value ...)
PATTERN
- def_node_matcher :description, <<~PATTERN
+ def_node_matcher :description_kwarg, <<~PATTERN
(... (hash <(pair (sym :description) $_) ...>))
PATTERN
+ def_node_matcher :enum_style_description, <<~PATTERN
+ (send nil? :value _ $str ...)
+ PATTERN
+
def on_send(node)
- return unless field_or_argument?(node)
+ return unless graphql_describable?(node)
- description = description(node)
+ description = locate_description(node)
return add_offense(node, location: :expression, message: MSG_NO_DESCRIPTION) unless description
@@ -59,7 +75,7 @@ module RuboCop
# Autocorrect missing periods at end of description.
def autocorrect(node)
lambda do |corrector|
- description = description(node)
+ description = locate_description(node)
next unless description
corrector.insert_after(before_end_quote(description), '.')
@@ -68,6 +84,16 @@ module RuboCop
private
+ # Fields and arguments define descriptions using a `description` keyword argument.
+ # Enums may define descriptions this way, or as a second `String` param.
+ def locate_description(node)
+ description = description_kwarg(node)
+
+ return description unless description.nil? && enum?(node)
+
+ enum_style_description(node)
+ end
+
def no_period?(description)
# Test that the description node is a `:str` (as opposed to
# a `#copy_field_description` call) before checking.
diff --git a/scripts/verify-tff-mapping b/scripts/verify-tff-mapping
index 9931e14008a..5bc4b23f99f 100755
--- a/scripts/verify-tff-mapping
+++ b/scripts/verify-tff-mapping
@@ -110,6 +110,12 @@ tests = [
explanation: 'Migration should map to its timestamped spec',
source: 'db/post_migrate/20190924152703_migrate_issue_trackers_data.rb',
expected: ['spec/migrations/20190924152703_migrate_issue_trackers_data_spec.rb']
+ },
+
+ {
+ explanation: 'Whats New should map to its respective spec',
+ source: 'data/whats_new/202101140001_13_08.yml',
+ expected: ['spec/lib/release_highlights/validator_spec.rb']
}
]
diff --git a/spec/features/dashboard/group_spec.rb b/spec/features/dashboard/group_spec.rb
index 0b99fed2a2d..bc6f449edc5 100644
--- a/spec/features/dashboard/group_spec.rb
+++ b/spec/features/dashboard/group_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe 'Dashboard Group' do
it 'creates new group', :js do
visit dashboard_groups_path
- find('.btn-success').click
+ find('[data-testid="new-group-button"]').click
new_name = 'Samurai'
fill_in 'group_name', with: new_name
diff --git a/spec/fixtures/api/schemas/entities/test_suite_comparer.json b/spec/fixtures/api/schemas/entities/test_suite_comparer.json
index ecb331ae013..ac001ef8843 100644
--- a/spec/fixtures/api/schemas/entities/test_suite_comparer.json
+++ b/spec/fixtures/api/schemas/entities/test_suite_comparer.json
@@ -26,7 +26,14 @@
"existing_failures": { "type": "array", "items": { "$ref": "test_case.json" } },
"new_errors": { "type": "array", "items": { "$ref": "test_case.json" } },
"resolved_errors": { "type": "array", "items": { "$ref": "test_case.json" } },
- "existing_errors": { "type": "array", "items": { "$ref": "test_case.json" } }
+ "existing_errors": { "type": "array", "items": { "$ref": "test_case.json" } },
+ "suite_errors": {
+ "type": ["object", "null"],
+ "properties": {
+ "head": { "type": ["string", "null"] },
+ "base": { "type": ["string", "null"] }
+ }
+ }
},
"additionalProperties": false
}
diff --git a/spec/lib/gitlab/ci/variables/collection/sort_spec.rb b/spec/lib/gitlab/ci/variables/collection/sort_spec.rb
index 6420798d6f5..c36dbe5bc07 100644
--- a/spec/lib/gitlab/ci/variables/collection/sort_spec.rb
+++ b/spec/lib/gitlab/ci/variables/collection/sort_spec.rb
@@ -214,7 +214,6 @@ RSpec.describe Gitlab::Ci::Variables::Collection::Sort do
context 'when FF :variable_inside_variable is enabled' do
before do
stub_licensed_features(group_saml_group_sync: true)
- stub_feature_flags(saml_group_links: true)
stub_feature_flags(variable_inside_variable: true)
end
diff --git a/spec/lib/release_highlights/validator/entry_spec.rb b/spec/lib/release_highlights/validator/entry_spec.rb
index da44938f165..5f7ccbf4310 100644
--- a/spec/lib/release_highlights/validator/entry_spec.rb
+++ b/spec/lib/release_highlights/validator/entry_spec.rb
@@ -40,8 +40,8 @@ RSpec.describe ReleaseHighlights::Validator::Entry do
end
it 'validates boolean value of "self-managed" and "gitlab-com"' do
- allow(entry).to receive(:value_for).with('self-managed').and_return('nope')
- allow(entry).to receive(:value_for).with('gitlab-com').and_return('yerp')
+ allow(entry).to receive(:value_for).with(:'self-managed').and_return('nope')
+ allow(entry).to receive(:value_for).with(:'gitlab-com').and_return('yerp')
subject.valid?
@@ -50,17 +50,18 @@ RSpec.describe ReleaseHighlights::Validator::Entry do
end
it 'validates URI of "url" and "image_url"' do
- allow(entry).to receive(:value_for).with('image_url').and_return('imgur/gitlab_feature.gif')
- allow(entry).to receive(:value_for).with('url').and_return('gitlab/newest_release.html')
+ stub_env('RSPEC_ALLOW_INVALID_URLS', 'false')
+ allow(entry).to receive(:value_for).with(:image_url).and_return('https://foobar.x/images/ci/gitlab-ci-cd-logo_2x.png')
+ allow(entry).to receive(:value_for).with(:url).and_return('')
subject.valid?
- expect(subject.errors[:url]).to include(/must be a URL/)
- expect(subject.errors[:image_url]).to include(/must be a URL/)
+ expect(subject.errors[:url]).to include(/must be a valid URL/)
+ expect(subject.errors[:image_url]).to include(/is blocked: Host cannot be resolved or invalid/)
end
it 'validates release is numerical' do
- allow(entry).to receive(:value_for).with('release').and_return('one')
+ allow(entry).to receive(:value_for).with(:release).and_return('one')
subject.valid?
@@ -68,7 +69,7 @@ RSpec.describe ReleaseHighlights::Validator::Entry do
end
it 'validates published_at is a date' do
- allow(entry).to receive(:value_for).with('published_at').and_return('christmas day')
+ allow(entry).to receive(:value_for).with(:published_at).and_return('christmas day')
subject.valid?
@@ -76,7 +77,7 @@ RSpec.describe ReleaseHighlights::Validator::Entry do
end
it 'validates packages are included in list' do
- allow(entry).to receive(:value_for).with('packages').and_return(['ALL'])
+ allow(entry).to receive(:value_for).with(:packages).and_return(['ALL'])
subject.valid?
diff --git a/spec/lib/release_highlights/validator_spec.rb b/spec/lib/release_highlights/validator_spec.rb
index a423e8cc5f6..f30754b4167 100644
--- a/spec/lib/release_highlights/validator_spec.rb
+++ b/spec/lib/release_highlights/validator_spec.rb
@@ -78,7 +78,10 @@ RSpec.describe ReleaseHighlights::Validator do
end
describe 'when validating all files' do
- it 'they should have no errors' do
+ # Permit DNS requests to validate all URLs in the YAML files
+ it 'they should have no errors', :permit_dns do
+ stub_env('RSPEC_ALLOW_INVALID_URLS', 'false')
+
expect(described_class.validate_all!).to be_truthy, described_class.error_message
end
end
diff --git a/spec/rubocop/cop/graphql/descriptions_spec.rb b/spec/rubocop/cop/graphql/descriptions_spec.rb
index 9ad40fad83d..276e4e03c15 100644
--- a/spec/rubocop/cop/graphql/descriptions_spec.rb
+++ b/spec/rubocop/cop/graphql/descriptions_spec.rb
@@ -91,6 +91,50 @@ RSpec.describe RuboCop::Cop::Graphql::Descriptions do
end
end
+ context 'enum values' do
+ it 'adds an offense when there is no description' do
+ expect_offense(<<~TYPE)
+ module Types
+ class FakeEnum < BaseEnum
+ value 'FOO', value: 'foo'
+ ^^^^^^^^^^^^^^^^^^^^^^^^^ Please add a `description` property.
+ end
+ end
+ TYPE
+ end
+
+ it 'adds an offense when description does not end in a period' do
+ expect_offense(<<~TYPE)
+ module Types
+ class FakeEnum < BaseEnum
+ value 'FOO', value: 'foo', description: 'bar'
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `description` strings must end with a `.`.
+ end
+ end
+ TYPE
+ end
+
+ it 'does not add an offense when description is correct (defined using `description:`)' do
+ expect_no_offenses(<<~TYPE.strip)
+ module Types
+ class FakeEnum < BaseEnum
+ value 'FOO', value: 'foo', description: 'bar.'
+ end
+ end
+ TYPE
+ end
+
+ it 'does not add an offense when description is correct (defined as a second argument)' do
+ expect_no_offenses(<<~TYPE.strip)
+ module Types
+ class FakeEnum < BaseEnum
+ value 'FOO', 'bar.', value: 'foo'
+ end
+ end
+ TYPE
+ end
+ end
+
describe 'autocorrecting descriptions without periods' do
it 'can autocorrect' do
expect_offense(<<~TYPE)
diff --git a/spec/serializers/test_suite_comparer_entity_spec.rb b/spec/serializers/test_suite_comparer_entity_spec.rb
index a63f5683779..318d1d3c1e3 100644
--- a/spec/serializers/test_suite_comparer_entity_spec.rb
+++ b/spec/serializers/test_suite_comparer_entity_spec.rb
@@ -35,6 +35,7 @@ RSpec.describe TestSuiteComparerEntity do
end
expect(subject[:resolved_failures]).to be_empty
expect(subject[:existing_failures]).to be_empty
+ expect(subject[:suite_errors]).to be_nil
end
end
@@ -56,6 +57,7 @@ RSpec.describe TestSuiteComparerEntity do
end
expect(subject[:resolved_failures]).to be_empty
expect(subject[:existing_failures]).to be_empty
+ expect(subject[:suite_errors]).to be_nil
end
end
@@ -77,6 +79,7 @@ RSpec.describe TestSuiteComparerEntity do
expect(existing_failure[:execution_time]).to eq(test_case_failed.execution_time)
expect(existing_failure[:system_output]).to eq(test_case_failed.system_output)
end
+ expect(subject[:suite_errors]).to be_nil
end
end
@@ -98,6 +101,47 @@ RSpec.describe TestSuiteComparerEntity do
expect(resolved_failure[:system_output]).to eq(test_case_success.system_output)
end
expect(subject[:existing_failures]).to be_empty
+ expect(subject[:suite_errors]).to be_nil
+ end
+ end
+
+ context 'when head suite has suite error' do
+ before do
+ allow(head_suite).to receive(:suite_error).and_return('some error')
+ end
+
+ it 'contains suite error for head suite' do
+ expect(subject[:suite_errors]).to eq(
+ head: 'some error',
+ base: nil
+ )
+ end
+ end
+
+ context 'when base suite has suite error' do
+ before do
+ allow(base_suite).to receive(:suite_error).and_return('some error')
+ end
+
+ it 'contains suite error for head suite' do
+ expect(subject[:suite_errors]).to eq(
+ head: nil,
+ base: 'some error'
+ )
+ end
+ end
+
+ context 'when base and head suite both have suite errors' do
+ before do
+ allow(head_suite).to receive(:suite_error).and_return('head error')
+ allow(base_suite).to receive(:suite_error).and_return('base error')
+ end
+
+ it 'contains suite error for head suite' do
+ expect(subject[:suite_errors]).to eq(
+ head: 'head error',
+ base: 'base error'
+ )
end
end
end
diff --git a/spec/services/notes/build_service_spec.rb b/spec/services/notes/build_service_spec.rb
index 2a8c3bd75fa..deeab66c4e9 100644
--- a/spec/services/notes/build_service_spec.rb
+++ b/spec/services/notes/build_service_spec.rb
@@ -8,26 +8,33 @@ RSpec.describe Notes::BuildService do
let(:note) { create(:discussion_note_on_issue) }
let(:project) { note.project }
let(:author) { note.author }
+ let(:user) { author }
let(:merge_request) { create(:merge_request, source_project: project) }
- let(:mr_note) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project, author: author) }
+ let(:mr_note) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project, author: note.author) }
+ let(:base_params) { { note: 'Test' } }
+ let(:params) { {} }
+
+ subject(:new_note) { described_class.new(project, user, base_params.merge(params)).execute }
describe '#execute' do
context 'when in_reply_to_discussion_id is specified' do
+ let(:params) { { in_reply_to_discussion_id: note.discussion_id } }
+
context 'when a note with that original discussion ID exists' do
it 'sets the note up to be in reply to that note' do
- new_note = described_class.new(project, author, note: 'Test', in_reply_to_discussion_id: note.discussion_id).execute
expect(new_note).to be_valid
expect(new_note.in_reply_to?(note)).to be_truthy
expect(new_note.resolved?).to be_falsey
end
context 'when discussion is resolved' do
+ let(:params) { { in_reply_to_discussion_id: mr_note.discussion_id } }
+
before do
mr_note.resolve!(author)
end
it 'resolves the note' do
- new_note = described_class.new(project, author, note: 'Test', in_reply_to_discussion_id: mr_note.discussion_id).execute
expect(new_note).to be_valid
expect(new_note.resolved?).to be_truthy
end
@@ -36,24 +43,23 @@ RSpec.describe Notes::BuildService do
context 'when a note with that discussion ID exists' do
it 'sets the note up to be in reply to that note' do
- new_note = described_class.new(project, author, note: 'Test', in_reply_to_discussion_id: note.discussion_id).execute
expect(new_note).to be_valid
expect(new_note.in_reply_to?(note)).to be_truthy
end
end
context 'when no note with that discussion ID exists' do
+ let(:params) { { in_reply_to_discussion_id: 'foo' } }
+
it 'sets an error' do
- new_note = described_class.new(project, author, note: 'Test', in_reply_to_discussion_id: 'foo').execute
expect(new_note.errors[:base]).to include('Discussion to reply to cannot be found')
end
end
context 'when user has no access to discussion' do
- it 'sets an error' do
- another_user = create(:user)
- new_note = described_class.new(project, another_user, note: 'Test', in_reply_to_discussion_id: note.discussion_id).execute
+ let(:user) { create(:user) }
+ it 'sets an error' do
expect(new_note.errors[:base]).to include('Discussion to reply to cannot be found')
end
end
@@ -129,22 +135,21 @@ RSpec.describe Notes::BuildService do
context 'when replying to individual note' do
let(:note) { create(:note_on_issue) }
-
- subject { described_class.new(project, author, note: 'Test', in_reply_to_discussion_id: note.discussion_id).execute }
+ let(:params) { { in_reply_to_discussion_id: note.discussion_id } }
it 'sets the note up to be in reply to that note' do
- expect(subject).to be_valid
- expect(subject).to be_a(DiscussionNote)
- expect(subject.discussion_id).to eq(note.discussion_id)
+ expect(new_note).to be_valid
+ expect(new_note).to be_a(DiscussionNote)
+ expect(new_note.discussion_id).to eq(note.discussion_id)
end
context 'when noteable does not support replies' do
let(:note) { create(:note_on_commit) }
it 'builds another individual note' do
- expect(subject).to be_valid
- expect(subject).to be_a(Note)
- expect(subject.discussion_id).not_to eq(note.discussion_id)
+ expect(new_note).to be_valid
+ expect(new_note).to be_a(Note)
+ expect(new_note.discussion_id).not_to eq(note.discussion_id)
end
end
end
@@ -156,124 +161,92 @@ RSpec.describe Notes::BuildService do
context 'when replying to a confidential comment' do
let(:note) { create(:note_on_issue, confidential: true) }
+ let(:params) { { in_reply_to_discussion_id: note.discussion_id, confidential: false } }
context 'when the user can read confidential comments' do
- subject do
- described_class.new(
- project,
- author,
- note: 'Test',
- in_reply_to_discussion_id: note.discussion_id,
- confidential: false
- ).execute
- end
-
it '`confidential` param is ignored and set to `true`' do
- expect(subject.confidential).to be_truthy
+ expect(new_note.confidential).to be_truthy
end
end
context 'when the user cannot read confidential comments' do
- let(:another_user) { create(:user) }
-
- subject do
- described_class.new(
- project,
- another_user,
- note: 'Test',
- in_reply_to_discussion_id: note.discussion_id,
- confidential: false
- ).execute
- end
+ let(:user) { create(:user) }
it 'returns `Discussion to reply to cannot be found` error' do
- expect(subject.errors.first).to include("Discussion to reply to cannot be found")
+ expect(new_note.errors.first).to include("Discussion to reply to cannot be found")
end
end
end
context 'when replying to a public comment' do
let(:note) { create(:note_on_issue, confidential: false) }
-
- subject do
- described_class.new(
- project,
- author,
- note: 'Test',
- in_reply_to_discussion_id: note.discussion_id,
- confidential: true
- ).execute
- end
+ let(:params) { { in_reply_to_discussion_id: note.discussion_id, confidential: true } }
it '`confidential` param is ignored and set to `false`' do
- expect(subject.confidential).to be_falsey
+ expect(new_note.confidential).to be_falsey
end
end
context 'when creating a new comment' do
context 'when the `confidential` note flag is set to `true`' do
context 'when the user is allowed (reporter)' do
- subject { described_class.new(project, author, note: 'Test', noteable: merge_request, confidential: true).execute }
+ let(:params) { { confidential: true, noteable: merge_request } }
it 'note `confidential` flag is set to `true`' do
- expect(subject.confidential).to be_truthy
+ expect(new_note.confidential).to be_truthy
end
end
context 'when the user is allowed (issuable author)' do
- let(:another_user) { create(:user) }
- let(:issue) { create(:issue, author: another_user) }
-
- subject { described_class.new(project, another_user, note: 'Test', noteable: issue, confidential: true).execute }
+ let(:user) { create(:user) }
+ let(:issue) { create(:issue, author: user) }
+ let(:params) { { confidential: true, noteable: issue } }
it 'note `confidential` flag is set to `true`' do
- expect(subject.confidential).to be_truthy
+ expect(new_note.confidential).to be_truthy
end
end
context 'when the user is allowed (admin)' do
before do
- enable_admin_mode!(another_user)
+ enable_admin_mode!(admin)
end
- let(:another_user) { create(:admin) }
-
- subject { described_class.new(project, another_user, note: 'Test', noteable: merge_request, confidential: true).execute }
+ let(:admin) { create(:admin) }
+ let(:params) { { confidential: true, noteable: merge_request } }
it 'note `confidential` flag is set to `true`' do
- expect(subject.confidential).to be_truthy
+ expect(new_note.confidential).to be_truthy
end
end
context 'when the user is not allowed' do
- let(:another_user) { create(:user) }
-
- subject { described_class.new(project, another_user, note: 'Test', noteable: merge_request, confidential: true).execute }
+ let(:user) { create(:user) }
+ let(:params) { { confidential: true, noteable: merge_request } }
it 'note `confidential` flag is set to `false`' do
- expect(subject.confidential).to be_falsey
+ expect(new_note.confidential).to be_falsey
end
end
end
context 'when the `confidential` note flag is set to `false`' do
- subject { described_class.new(project, author, note: 'Test', noteable: merge_request, confidential: false).execute }
+ let(:params) { { confidential: false, noteable: merge_request } }
it 'note `confidential` flag is set to `false`' do
- expect(subject.confidential).to be_falsey
+ expect(new_note.confidential).to be_falsey
end
end
end
end
- it 'builds a note without saving it' do
- new_note = described_class.new(project,
- author,
- noteable_type: note.noteable_type,
- noteable_id: note.noteable_id,
- note: 'Test').execute
- expect(new_note).to be_valid
- expect(new_note).not_to be_persisted
+ context 'when noteable is not set' do
+ let(:params) { { noteable_type: note.noteable_type, noteable_id: note.noteable_id } }
+
+ it 'builds a note without saving it' do
+ expect(new_note).to be_valid
+ expect(new_note).not_to be_persisted
+ end
end
end
end
diff --git a/tests.yml b/tests.yml
index d24cc44a403..15b1814df3a 100644
--- a/tests.yml
+++ b/tests.yml
@@ -52,3 +52,7 @@ mapping:
# EE/FOSS factory should map to factories spec
- source: (ee/)?spec/factories/.+\.rb
test: spec/factories_spec.rb
+
+ # Whats New should map to its respective spec
+ - source: data/whats_new/\w*.yml
+ test: spec/lib/release_highlights/validator_spec.rb
diff --git a/tooling/danger/helper.rb b/tooling/danger/helper.rb
index 96a51806d31..ef5b2e16bb0 100644
--- a/tooling/danger/helper.rb
+++ b/tooling/danger/helper.rb
@@ -209,6 +209,7 @@ module Tooling
%r{\Adoc/.*(\.(md|png|gif|jpg))\z} => :docs,
%r{\A(CONTRIBUTING|LICENSE|MAINTENANCE|PHILOSOPHY|PROCESS|README)(\.md)?\z} => :docs,
+ %r{\Adata/whats_new/} => :docs,
%r{\A(ee/)?app/(assets|views)/} => :frontend,
%r{\A(ee/)?public/} => :frontend,
diff --git a/yarn.lock b/yarn.lock
index f85f6161e4b..a38dd3822a1 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -847,10 +847,10 @@
exec-sh "^0.3.2"
minimist "^1.2.0"
-"@eslint/eslintrc@^0.3.0":
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.3.0.tgz#d736d6963d7003b6514e6324bec9c602ac340318"
- integrity sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg==
+"@eslint/eslintrc@^0.4.0":
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.0.tgz#99cc0a0584d72f1df38b900fb062ba995f395547"
+ integrity sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==
dependencies:
ajv "^6.12.4"
debug "^4.1.1"
@@ -859,7 +859,6 @@
ignore "^4.0.6"
import-fresh "^3.2.1"
js-yaml "^3.13.1"
- lodash "^4.17.20"
minimatch "^3.0.4"
strip-json-comments "^3.1.1"
@@ -4791,13 +4790,13 @@ eslint-visitor-keys@^2.0.0:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8"
integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==
-eslint@7.20.0:
- version "7.20.0"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.20.0.tgz#db07c4ca4eda2e2316e7aa57ac7fc91ec550bdc7"
- integrity sha512-qGi0CTcOGP2OtCQBgWZlQjcTuP0XkIpYFj25XtRTQSHC+umNnp7UMshr2G8SLsRFYDdAPFeHOsiteadmMH02Yw==
+eslint@7.21.0:
+ version "7.21.0"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.21.0.tgz#4ecd5b8c5b44f5dedc9b8a110b01bbfeb15d1c83"
+ integrity sha512-W2aJbXpMNofUp0ztQaF40fveSsJBjlSCSWpy//gzfTvwC+USs/nceBrKmlJOiM8r1bLwP2EuYkCqArn/6QTIgg==
dependencies:
"@babel/code-frame" "7.12.11"
- "@eslint/eslintrc" "^0.3.0"
+ "@eslint/eslintrc" "^0.4.0"
ajv "^6.10.0"
chalk "^4.0.0"
cross-spawn "^7.0.2"
@@ -4810,7 +4809,7 @@ eslint@7.20.0:
espree "^7.3.1"
esquery "^1.4.0"
esutils "^2.0.2"
- file-entry-cache "^6.0.0"
+ file-entry-cache "^6.0.1"
functional-red-black-tree "^1.0.1"
glob-parent "^5.0.0"
globals "^12.1.0"
@@ -5173,10 +5172,10 @@ figgy-pudding@^3.5.1:
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==
-file-entry-cache@^6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.0.tgz#7921a89c391c6d93efec2169ac6bf300c527ea0a"
- integrity sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==
+file-entry-cache@^6.0.0, file-entry-cache@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027"
+ integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==
dependencies:
flat-cache "^3.0.4"