From 53f7c2edf478dac9e6b8e52c4b9a59c53659eb31 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Mon, 9 Aug 2021 03:10:10 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- .../Change Documentation Location.md | 10 +- .../merge_request_templates/Documentation.md | 33 +++++-- app/graphql/gitlab_schema.rb | 24 ++--- app/graphql/types/query_type.rb | 2 +- ...p_index_approval_project_rules_scanners.rb | 20 ++++ ...ge_scanning_from_approval_project_rules.rb | 11 +++ db/schema_migrations/20210804150624 | 1 + db/schema_migrations/20210804202057 | 1 + db/structure.sql | 2 + doc/administration/auth/atlassian.md | 13 +-- doc/api/graphql/reference/index.md | 1 + doc/development/contributing/style_guides.md | 1 + doc/user/permissions.md | 30 +++--- lefthook.yml | 7 +- lib/tasks/gitlab/graphql.rake | 4 +- scripts/lint-doc.sh | 4 +- scripts/lint-docs-metadata.sh | 75 ++++++++++++++ spec/deprecation_toolkit_env.rb | 1 + spec/graphql/gitlab_schema_spec.rb | 99 +++++++++---------- spec/requests/api/graphql_spec.rb | 2 +- .../namespaces/traversal_examples.rb | 86 +++++++++++++++- 21 files changed, 303 insertions(+), 124 deletions(-) create mode 100644 db/migrate/20210804202057_add_tmp_index_approval_project_rules_scanners.rb create mode 100644 db/post_migrate/20210804150624_remove_cluster_image_scanning_from_approval_project_rules.rb create mode 100644 db/schema_migrations/20210804150624 create mode 100644 db/schema_migrations/20210804202057 create mode 100755 scripts/lint-docs-metadata.sh diff --git a/.gitlab/merge_request_templates/Change Documentation Location.md b/.gitlab/merge_request_templates/Change Documentation Location.md index 0c675d8d0c6..623d1597744 100644 --- a/.gitlab/merge_request_templates/Change Documentation Location.md +++ b/.gitlab/merge_request_templates/Change Documentation Location.md @@ -1,6 +1,8 @@ - - - + ## What does this MR do? @@ -25,4 +27,4 @@ https://docs.gitlab.com/ee/development/documentation/index.html#move-or-rename-a - [ ] Update the link in `features.yml` (if applicable) - [ ] Assign one of the technical writers for review. -/label ~documentation +/label ~documentation ~"Technical Writing" diff --git a/.gitlab/merge_request_templates/Documentation.md b/.gitlab/merge_request_templates/Documentation.md index 99ad233c7e0..e97ae9a0c43 100644 --- a/.gitlab/merge_request_templates/Documentation.md +++ b/.gitlab/merge_request_templates/Documentation.md @@ -1,9 +1,12 @@ - - - + - + Mention "documentation" or "docs" in the MR title + For changing documentation location use the Change Documentation Location.md template +--> ## What does this MR do? @@ -15,11 +18,23 @@ ## Author's checklist -- [ ] Follow the [Documentation Guidelines](https://docs.gitlab.com/ee/development/documentation/) and [Style Guide](https://docs.gitlab.com/ee/development/documentation/styleguide/). -- [ ] Ensure that the [product tier badge](https://docs.gitlab.com/ee/development/documentation/styleguide/index.html#product-tier-badges) is added to doc's `h1`. -- [ ] [Request a review](https://docs.gitlab.com/ee/development/code_review.html#dogfooding-the-reviewers-feature) based on the documentation page's metadata and [associated Technical Writer](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments). +- [ ] Follow the: + - [Documentation Guidelines](https://docs.gitlab.com/ee/development/documentation/). + - [Style Guide](https://docs.gitlab.com/ee/development/documentation/styleguide/). +- [ ] Ensure that the [product tier badge](https://docs.gitlab.com/ee/development/documentation/styleguide/index.html#product-tier-badges) is added to topic's `h1`. +- [ ] [Request a review](https://docs.gitlab.com/ee/development/code_review.html#dogfooding-the-reviewers-feature) based on the: + - The documentation page's [metadata](https://docs.gitlab.com/ee/development/documentation/#metadata). + - The [associated Technical Writer](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments). -To avoid having this MR be added to code verification QA issues, don't add these labels: ~"feature", ~"frontend", ~"backend", ~"bug", or ~"database" +If you are only adding documentation, do not add any of the following labels: + +- `~"feature"` +- `~"frontend"` +- `~"backend"` +- `~"bug"` +- `~"database"` + +These labels cause the MR to be added to code verification QA issues. ## Review checklist diff --git a/app/graphql/gitlab_schema.rb b/app/graphql/gitlab_schema.rb index 8e95bd501ff..38ba1611c48 100644 --- a/app/graphql/gitlab_schema.rb +++ b/app/graphql/gitlab_schema.rb @@ -3,9 +3,9 @@ class GitlabSchema < GraphQL::Schema # Currently an IntrospectionQuery has a complexity of 179. # These values will evolve over time. - DEFAULT_MAX_COMPLEXITY = 200 - AUTHENTICATED_COMPLEXITY = 250 - ADMIN_COMPLEXITY = 300 + DEFAULT_MAX_COMPLEXITY = 200 + AUTHENTICATED_MAX_COMPLEXITY = 250 + ADMIN_MAX_COMPLEXITY = 300 DEFAULT_MAX_DEPTH = 15 AUTHENTICATED_MAX_DEPTH = 20 @@ -20,9 +20,6 @@ class GitlabSchema < GraphQL::Schema query_analyzer Gitlab::Graphql::QueryAnalyzers::LoggerAnalyzer.new query_analyzer Gitlab::Graphql::QueryAnalyzers::RecursionAnalyzer.new - max_complexity DEFAULT_MAX_COMPLEXITY - max_depth DEFAULT_MAX_DEPTH - query Types::QueryType mutation Types::MutationType subscription Types::SubscriptionType @@ -36,20 +33,13 @@ class GitlabSchema < GraphQL::Schema kwargs[:max_complexity] ||= max_query_complexity(kwargs[:context]) unless kwargs.key?(:max_complexity) queries.each do |query| - query[:max_complexity] ||= max_query_complexity(kwargs[:context]) unless query.key?(:max_complexity) - query[:max_depth] = max_query_depth(kwargs[:context]) + query[:max_complexity] ||= max_query_complexity(query[:context]) unless query.key?(:max_complexity) + query[:max_depth] = max_query_depth(query[:context]) unless query.key?(:max_depth) end super(queries, **kwargs) end - def execute(query_str = nil, **kwargs) - kwargs[:max_complexity] ||= max_query_complexity(kwargs[:context]) - kwargs[:max_depth] ||= max_query_depth(kwargs[:context]) - - super(query_str, **kwargs) - end - def get_type(type_name) type_name = Gitlab::GlobalId::Deprecations.apply_to_graphql_name(type_name) @@ -142,9 +132,9 @@ class GitlabSchema < GraphQL::Schema current_user = ctx&.fetch(:current_user, nil) if current_user&.admin - ADMIN_COMPLEXITY + ADMIN_MAX_COMPLEXITY elsif current_user - AUTHENTICATED_COMPLEXITY + AUTHENTICATED_MAX_COMPLEXITY else DEFAULT_MAX_COMPLEXITY end diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb index d2c67aea95c..f01a23984e7 100644 --- a/app/graphql/types/query_type.rb +++ b/app/graphql/types/query_type.rb @@ -129,7 +129,7 @@ module Types description: "Find runners visible to the current user.", feature_flag: :runner_graphql_query - field :ci_config, resolver: Resolvers::Ci::ConfigResolver, complexity: 126 # AUTHENTICATED_COMPLEXITY / 2 + 1 + field :ci_config, resolver: Resolvers::Ci::ConfigResolver, complexity: 126 # AUTHENTICATED_MAX_COMPLEXITY / 2 + 1 def design_management DesignManagementObject.new(nil) diff --git a/db/migrate/20210804202057_add_tmp_index_approval_project_rules_scanners.rb b/db/migrate/20210804202057_add_tmp_index_approval_project_rules_scanners.rb new file mode 100644 index 00000000000..66fcf485b2f --- /dev/null +++ b/db/migrate/20210804202057_add_tmp_index_approval_project_rules_scanners.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +# See https://docs.gitlab.com/ee/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddTmpIndexApprovalProjectRulesScanners < ActiveRecord::Migration[6.1] + include Gitlab::Database::MigrationHelpers + + INDEX_NAME = 'tmp_index_approval_project_rules_scanners' + + disable_ddl_transaction! + + def up + add_concurrent_index :approval_project_rules, :scanners, name: INDEX_NAME, using: :gin, where: "scanners @> '{cluster_image_scanning}'" + end + + def down + remove_concurrent_index_by_name :approval_project_rules, INDEX_NAME + end +end diff --git a/db/post_migrate/20210804150624_remove_cluster_image_scanning_from_approval_project_rules.rb b/db/post_migrate/20210804150624_remove_cluster_image_scanning_from_approval_project_rules.rb new file mode 100644 index 00000000000..a2736a563c7 --- /dev/null +++ b/db/post_migrate/20210804150624_remove_cluster_image_scanning_from_approval_project_rules.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class RemoveClusterImageScanningFromApprovalProjectRules < ActiveRecord::Migration[6.1] + def up + execute("update approval_project_rules set scanners = array_remove(scanners, 'cluster_image_scanning') where scanners @> '{cluster_image_scanning}'") + end + + def down + # nothing to do here + end +end diff --git a/db/schema_migrations/20210804150624 b/db/schema_migrations/20210804150624 new file mode 100644 index 00000000000..135519b6b93 --- /dev/null +++ b/db/schema_migrations/20210804150624 @@ -0,0 +1 @@ +52e71aa3ec92473006b37e9319797133356f7747b91c32b09a746e183501655f \ No newline at end of file diff --git a/db/schema_migrations/20210804202057 b/db/schema_migrations/20210804202057 new file mode 100644 index 00000000000..dd592038d11 --- /dev/null +++ b/db/schema_migrations/20210804202057 @@ -0,0 +1 @@ +48f140728fede7cf38469c8dfcb5480b4f2b8e29af4b1edd5d38024548493c2d \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 93b4d62bfea..373fc573419 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -25596,6 +25596,8 @@ CREATE INDEX tmp_idx_deduplicate_vulnerability_occurrences ON vulnerability_occu CREATE INDEX tmp_idx_on_namespaces_delayed_project_removal ON namespaces USING btree (id) WHERE (delayed_project_removal = true); +CREATE INDEX tmp_index_approval_project_rules_scanners ON approval_project_rules USING gin (scanners) WHERE (scanners @> '{cluster_image_scanning}'::text[]); + CREATE INDEX tmp_index_merge_requests_draft_and_status ON merge_requests USING btree (id) WHERE ((draft = false) AND (state_id = 1) AND ((title)::text ~* '^\[draft\]|\(draft\)|draft:|draft|\[WIP\]|WIP:|WIP'::text)); CREATE INDEX tmp_index_namespaces_empty_traversal_ids_with_child_namespaces ON namespaces USING btree (id) WHERE ((parent_id IS NOT NULL) AND (traversal_ids = '{}'::integer[])); diff --git a/doc/administration/auth/atlassian.md b/doc/administration/auth/atlassian.md index b3892f8f5d9..868482148e5 100644 --- a/doc/administration/auth/atlassian.md +++ b/doc/administration/auth/atlassian.md @@ -12,22 +12,14 @@ To enable the Atlassian OmniAuth provider for passwordless authentication you mu ## Atlassian application registration 1. Go to and sign-in with the Atlassian - account that will administer the application. - + account to administer the application. 1. Click **Create a new app**. - 1. Choose an App Name, such as 'GitLab', and click **Create**. - 1. Note the `Client ID` and `Secret` for the [GitLab configuration](#gitlab-configuration) steps. - 1. In the left sidebar under **APIS AND FEATURES**, click **OAuth 2.0 (3LO)**. - 1. Enter the GitLab callback URL using the format `https://gitlab.example.com/users/auth/atlassian_oauth2/callback` and click **Save changes**. - 1. Click **+ Add** in the left sidebar under **APIS AND FEATURES**. - 1. Click **Add** for **Jira platform REST API** and then **Configure**. - 1. Click **Add** next to the following scopes: - **View Jira issue data** - **View user profiles** @@ -50,7 +42,6 @@ To enable the Atlassian OmniAuth provider for passwordless authentication you mu ``` 1. See [Initial OmniAuth Configuration](../../integration/omniauth.md#initial-omniauth-configuration) for initial settings to enable single sign-on and add `atlassian_oauth2` as an OAuth provider. - 1. Add the provider configuration for Atlassian: For Omnibus GitLab installations: @@ -76,9 +67,7 @@ To enable the Atlassian OmniAuth provider for passwordless authentication you mu ``` 1. Change `YOUR_CLIENT_ID` and `YOUR_CLIENT_SECRET` to the Client credentials you received in [application registration](#atlassian-application-registration) steps. - 1. Save the configuration file. - 1. [Reconfigure](../restart_gitlab.md#omnibus-gitlab-reconfigure) or [restart GitLab](../restart_gitlab.md#installations-from-source) for the changes to take effect if you installed GitLab via Omnibus or from source respectively. On the sign-in page there should now be an Atlassian icon below the regular sign in form. Click the icon to begin the authentication process. diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index d95590e5410..6e1c47208aa 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -13885,6 +13885,7 @@ Represents a vulnerability. | `dismissedAt` | [`Time`](#time) | Timestamp of when the vulnerability state was changed to dismissed. | | `dismissedBy` | [`UserCore`](#usercore) | The user that dismissed the vulnerability. | | `externalIssueLinks` | [`VulnerabilityExternalIssueLinkConnection!`](#vulnerabilityexternalissuelinkconnection) | List of external issue links related to the vulnerability. (see [Connections](#connections)) | +| `falsePositive` | [`Boolean`](#boolean) | Indicates whether the vulnerability is a false positive. Available only when feature flag `vulnerability_flags` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. | | `hasSolutions` | [`Boolean`](#boolean) | Indicates whether there is a solution available for this vulnerability. | | `id` | [`ID!`](#id) | GraphQL ID of the vulnerability. | | `identifiers` | [`[VulnerabilityIdentifier!]!`](#vulnerabilityidentifier) | Identifiers of the vulnerability. | diff --git a/doc/development/contributing/style_guides.md b/doc/development/contributing/style_guides.md index e737e4095f1..1b339b7f252 100644 --- a/doc/development/contributing/style_guides.md +++ b/doc/development/contributing/style_guides.md @@ -62,6 +62,7 @@ Before you push your changes, Lefthook automatically runs the following checks: - SCSS lint: Run `yarn lint:stylelint` checks (with the [`.stylelintrc`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.stylelintrc) configuration) on the modified `*.scss{,.css}` files. Tags: `stylesheet`, `css`, `style`. - RuboCop: Run `bundle exec rubocop` checks (with the [`.rubocop.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.rubocop.yml) configuration) on the modified `*.rb` files. Tags: `backend`, `style`. - Vale: Run `vale` checks (with the [`.vale.ini`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.vale.ini) configuration) on the modified `*.md` files. Tags: `documentation`, `style`. +- Documentation metadata: Run checks for the absence of [documentation metadata](../documentation/index.md#metadata). In addition to the default configuration, you can define a [local configuration](https://github.com/Arkweid/lefthook/blob/master/docs/full_guide.md#local-config). diff --git a/doc/user/permissions.md b/doc/user/permissions.md index 5534bac3af4..ca4bb58fd05 100644 --- a/doc/user/permissions.md +++ b/doc/user/permissions.md @@ -59,6 +59,21 @@ The following table lists project permissions available for each role: | [Application security](application_security/index.md):
View [threats list](application_security/threat_monitoring/index.md#threat-monitoring) **(ULTIMATE)** | | | ✓ | ✓ | ✓ | | [Application security](application_security/index.md):
Create a [CVE ID Request](application_security/cve_id_request.md) **(FREE SAAS)** | | | | ✓ | ✓ | | [Application security](application_security/index.md):
Create or assign [security policy project](application_security/policies/index.md) **(ULTIMATE)** | | | | | ✓ | +| [CI/CD](../ci/README.md):
Download and browse job artifacts | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ | +| [CI/CD](../ci/README.md):
View a job log | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ | +| [CI/CD](../ci/README.md):
View list of jobs | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ | +| [CI/CD](../ci/README.md):
View [environments](../ci/environments/index.md) | | ✓ | ✓ | ✓ | ✓ | +| [CI/CD](../ci/README.md):
Cancel and retry jobs | | | ✓ | ✓ | ✓ | +| [CI/CD](../ci/README.md):
Create new [environments](../ci/environments/index.md) | | | ✓ | ✓ | ✓ | +| [CI/CD](../ci/README.md):
Run CI/CD pipeline against a protected branch | | | ✓ (*5*) | ✓ | ✓ | +| [CI/CD](../ci/README.md):
Stop [environments](../ci/environments/index.md) | | | ✓ | ✓ | ✓ | +| [CI/CD](../ci/README.md):
View a job with [debug logging](../ci/variables/index.md#debug-logging) | | | ✓ | ✓ | ✓ | +| [CI/CD](../ci/README.md):
Manage CI/CD variables | | | | ✓ | ✓ | +| [CI/CD](../ci/README.md):
Manage job triggers | | | | ✓ | ✓ | +| [CI/CD](../ci/README.md):
Manage runners | | | | ✓ | ✓ | +| [CI/CD](../ci/README.md):
Run Web IDE's Interactive Web Terminals **(ULTIMATE ONLY)** | | | | ✓ | ✓ | +| [CI/CD](../ci/README.md):
Use [environment terminals](../ci/environments/index.md#web-terminals) | | | | ✓ | ✓ | +| [CI/CD](../ci/README.md):
Delete pipelines | | | | | ✓ | | [Security dashboard](application_security/security_dashboard/index.md):
View Security reports **(ULTIMATE)** | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ | | [Security dashboard](application_security/security_dashboard/index.md):
Create issue from vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ | | [Security dashboard](application_security/security_dashboard/index.md):
Create vulnerability from vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ | @@ -72,15 +87,12 @@ The following table lists project permissions available for each role: | Assign issues | ✓ (*16*)| ✓ | ✓ | ✓ | ✓ | | Create [confidential issue](project/issues/confidential_issues.md) | ✓ | ✓ | ✓ | ✓ | ✓ | | Create new issue | ✓ | ✓ | ✓ | ✓ | ✓ | -| Download and browse job artifacts | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ | | Download project | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | | Label issues | ✓ (*16*)| ✓ | ✓ | ✓ | ✓ | | Leave comments | ✓ | ✓ | ✓ | ✓ | ✓ | | Manage user-starred metrics dashboards (*7*) | ✓ | ✓ | ✓ | ✓ | ✓ | | Pull project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ | | Reposition comments on images (posted by any user)| ✓ (*10*)| ✓ (*10*) | ✓ (*10*) | ✓ | ✓ | -| See a job log | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ | -| See a list of jobs | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ | | See linked issues | ✓ | ✓ | ✓ | ✓ | ✓ | | Set issue weight | ✓ (*16*)| ✓ | ✓ | ✓ | ✓ | | View [Design Management](project/issues/design_management.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ | @@ -110,7 +122,6 @@ The following table lists project permissions available for each role: | Reopen [test case](../ci/test_cases/index.md) | | ✓ | ✓ | ✓ | ✓ | | See a commit status | | ✓ | ✓ | ✓ | ✓ | | See a list of merge requests | | ✓ | ✓ | ✓ | ✓ | -| See environments | | ✓ | ✓ | ✓ | ✓ | | [Set issue estimate and record time spent](project/time_tracking.md) | | ✓ | ✓ | ✓ | ✓ | | View [confidential issues](project/issues/confidential_issues.md) | (*2*) | ✓ | ✓ | ✓ | ✓ | | View Error Tracking list | | ✓ | ✓ | ✓ | ✓ | @@ -121,10 +132,8 @@ The following table lists project permissions available for each role: | Apply code change suggestions | | | ✓ | ✓ | ✓ | | Approve merge requests (*9*) | | | ✓ | ✓ | ✓ | | Assign merge requests | | | ✓ | ✓ | ✓ | -| Cancel and retry jobs | | | ✓ | ✓ | ✓ | | Create and edit wiki pages | | | ✓ | ✓ | ✓ | | Create new branches | | | ✓ | ✓ | ✓ | -| Create new environments | | | ✓ | ✓ | ✓ | | Create new merge request | | | ✓ | ✓ | ✓ | | Create or update commit status | | | ✓ (*5*) | ✓ | ✓ | | Create/edit/delete [releases](project/releases/index.md)| | | ✓ (*13*) | ✓ (*13*) | ✓ (*13*) | @@ -143,9 +152,6 @@ The following table lists project permissions available for each role: | Remove a container registry image | | | ✓ | ✓ | ✓ | | Remove non-protected branches | | | ✓ | ✓ | ✓ | | Rewrite/remove Git tags | | | ✓ | ✓ | ✓ | -| Run CI/CD pipeline against a protected branch | | | ✓ (*5*) | ✓ | ✓ | -| See a job with [debug logging](../ci/variables/index.md#debug-logging) | | | ✓ | ✓ | ✓ | -| Stop environments | | | ✓ | ✓ | ✓ | | Update a container registry | | | ✓ | ✓ | ✓ | | Upload [Design Management](project/issues/design_management.md) files | | | ✓ | ✓ | ✓ | | View Pods logs | | | ✓ | ✓ | ✓ | @@ -164,30 +170,24 @@ The following table lists project permissions available for each role: | Export project | | | | ✓ | ✓ | | Manage [project access tokens](project/settings/project_access_tokens.md) **(FREE SELF)** **(PREMIUM SAAS)** (*12*) | | | | ✓ | ✓ | | Manage [push rules](../push_rules/push_rules.md) | | | | ✓ | ✓ | -| Manage CI/CD variables | | | | ✓ | ✓ | | Manage clusters | | | | ✓ | ✓ | | Manage Error Tracking | | | | ✓ | ✓ | | Manage GitLab Pages | | | | ✓ | ✓ | | Manage GitLab Pages domains and certificates | | | | ✓ | ✓ | -| Manage job triggers | | | | ✓ | ✓ | | Manage license policy **(ULTIMATE)** | | | | ✓ | ✓ | | Manage merge approval rules (project settings) | | | | ✓ | ✓ | | Manage Project Operations | | | | ✓ | ✓ | -| Manage runners | | | | ✓ | ✓ | | Manage Terraform state | | | | ✓ | ✓ | | Push to protected branches | | | | ✓ | ✓ | | Remove GitLab Pages | | | | ✓ | ✓ | -| Run Web IDE's Interactive Web Terminals **(ULTIMATE SELF)** | | | | ✓ | ✓ | | Share (invite) projects with groups | | | | ✓ (*8*) | ✓ (*8*)| | Turn on/off protected branch push for developers | | | | ✓ | ✓ | -| Use environment terminals | | | | ✓ | ✓ | | View 2FA status of members | | | | ✓ | ✓ | | Administer project compliance frameworks | | | | | ✓ | | Archive project | | | | | ✓ | | Change project visibility level | | | | | ✓ | | Delete issues | | | | | ✓ | | Delete merge request | | | | | ✓ | -| Delete pipelines | | | | | ✓ | | Delete project | | | | | ✓ | | Disable notification emails | | | | | ✓ | | Remove fork relationship | | | | | ✓ | diff --git a/lefthook.yml b/lefthook.yml index 81ff2ecdada..55027f6bf59 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -39,8 +39,13 @@ pre-push: glob: 'doc/*.md' run: if command -v vale 2> /dev/null; then vale --config .vale.ini --minAlertLevel error {files}; else echo "Vale not found. Install Vale"; fi gettext: - skip: true # This is disabled by default. You can enable this check by adding skip: false in lefhook-local.yml https://github.com/evilmartians/lefthook/blob/master/docs/full_guide.md#skipping-commands + skip: true # This is disabled by default. You can enable this check by adding skip: false in lefhook-local.yml https://github.com/evilmartians/lefthook/blob/master/docs/full_guide.md#skipping-commands tags: backend frontend view haml files: git diff --name-only --diff-filter=d $(git merge-base origin/master HEAD)..HEAD | while read file;do git diff --unified=1 $(git merge-base origin/master HEAD)..HEAD $file | grep -Fqe '_(' && echo $file;done; true glob: "*.{haml,rb,js,vue}" run: bin/rake gettext:updated_check + docs-metadata: # See https://docs.gitlab.com/ee/development/documentation/#metadata + tags: documentation style + files: git diff --name-only --diff-filter=d $(git merge-base origin/master HEAD)..HEAD + glob: 'doc/*.md' + run: scripts/lint-docs-metadata.sh {files} diff --git a/lib/tasks/gitlab/graphql.rake b/lib/tasks/gitlab/graphql.rake index b405cbd3f68..52c5c680292 100644 --- a/lib/tasks/gitlab/graphql.rake +++ b/lib/tasks/gitlab/graphql.rake @@ -56,9 +56,9 @@ namespace :gitlab do color = case complexity when 0..GitlabSchema::DEFAULT_MAX_COMPLEXITY :green - when GitlabSchema::DEFAULT_MAX_COMPLEXITY..GitlabSchema::AUTHENTICATED_COMPLEXITY + when GitlabSchema::DEFAULT_MAX_COMPLEXITY..GitlabSchema::AUTHENTICATED_MAX_COMPLEXITY :yellow - when GitlabSchema::AUTHENTICATED_COMPLEXITY..GitlabSchema::ADMIN_COMPLEXITY + when GitlabSchema::AUTHENTICATED_MAX_COMPLEXITY..GitlabSchema::ADMIN_MAX_COMPLEXITY :orange else :red diff --git a/scripts/lint-doc.sh b/scripts/lint-doc.sh index 33a46e73ee2..0b8e0010e2f 100755 --- a/scripts/lint-doc.sh +++ b/scripts/lint-doc.sh @@ -21,11 +21,9 @@ fi # Documentation pages need front matter for tracking purposes. echo '=> Checking documentation for front matter...' echo -no_frontmatter=$(find doc -name "*.md" -exec head -n1 {} \; | grep -v --count -- ---) -if [ $no_frontmatter -ne 0 ] +if ! scripts/lint-docs-metadata.sh then echo '✖ ERROR: These documentation pages need front matter. See https://docs.gitlab.com/ee/development/documentation/index.html#stage-and-group-metadata for how to add it.' >&2 - find doc -name "*.md" -exec sh -c 'if (head -n 1 "{}" | grep -v -- --- >/dev/null); then echo "{}"; fi' \; 2>&1 echo ((ERRORCODE++)) fi diff --git a/scripts/lint-docs-metadata.sh b/scripts/lint-docs-metadata.sh new file mode 100755 index 00000000000..4212adfd3f1 --- /dev/null +++ b/scripts/lint-docs-metadata.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash +set -euo pipefail +IFS=$'\n\t' + +COLOR_RED="\e[31m" +COLOR_GREEN="\e[32m" +COLOR_RESET="\e[39m" +VERBOSE=false +CHECK_ALL=true + +FAILING_FILES=0 +TOTAL_FILES=0 + +# Parse arguments +for arg in "$@"; do + case $arg in + + --verbose) + VERBOSE=true + ;; + --help | -h) + cat < + +If no files are provided, all markdown files in doc/ are checked. +EOF + exit 0 + ;; + *) + CHECK_ALL=false + ;; + + esac +done + +function check_file { + local file + file="$1" + TOTAL_FILES=$((TOTAL_FILES + 1)) + if [ "$(head -n1 "$file")" != "---" ]; then + printf "${COLOR_RED}Documentation metadata missing in %s.${COLOR_RESET}\n" "$file" >&2 + FAILING_FILES=$((FAILING_FILES + 1)) + elif [ "$VERBOSE" == "true" ]; then + printf "Documentation metadata found in %s.\n" "$file" + fi +} + +function check_all_files { + while IFS= read -r -d '' file; do + check_file "$file" + done < <(find "doc" -name "*.md" -type f -print0) +} + +if [[ "$CHECK_ALL" = "true" ]]; then + # shellcheck disable=SC2059 + printf "No files supplied. Checking all markdown files in doc/.\n" + check_all_files +else + # Takes a list of Markdown files as a parameter + for file in "$@"; do + # Skipping parameters + [[ $file = --* ]] && continue + check_file "$file" + done +fi + +if [ "$FAILING_FILES" -gt 0 ]; then + # shellcheck disable=SC2059 + printf "\n${COLOR_RED}Documentation metadata is missing in ${FAILING_FILES} of ${TOTAL_FILES} documentation files.${COLOR_RESET} For more information, see https://docs.gitlab.com/ee/development/documentation/#metadata.\n" >&2 + exit 1 +else + # shellcheck disable=SC2059 + printf "${COLOR_GREEN}Documentation metadata found in ${TOTAL_FILES} documentation files.${COLOR_RESET}\n" + exit 0 +fi diff --git a/spec/deprecation_toolkit_env.rb b/spec/deprecation_toolkit_env.rb index d7fea46a8aa..7077118a5d5 100644 --- a/spec/deprecation_toolkit_env.rb +++ b/spec/deprecation_toolkit_env.rb @@ -56,6 +56,7 @@ module DeprecationToolkitEnv def self.allowed_kwarg_warning_paths %w[ actionpack-6.1.3.2/lib/action_dispatch/routing/route_set.rb + graphql-1.11.8/lib/graphql/schema.rb ] end diff --git a/spec/graphql/gitlab_schema_spec.rb b/spec/graphql/gitlab_schema_spec.rb index 06505536b09..1b5ecc4fe1b 100644 --- a/spec/graphql/gitlab_schema_spec.rb +++ b/spec/graphql/gitlab_schema_spec.rb @@ -36,75 +36,66 @@ RSpec.describe GitlabSchema do end describe '.execute' do - context 'with different types of users' do - context 'when no context' do - it 'returns DEFAULT_MAX_COMPLEXITY' do - expect(GraphQL::Schema) - .to receive(:execute) - .with('query', hash_including(max_complexity: GitlabSchema::DEFAULT_MAX_COMPLEXITY)) + describe 'setting query `max_complexity` and `max_depth`' do + subject(:result) { described_class.execute('query', kwargs).query } - described_class.execute('query') + shared_examples 'sets default limits' do + specify do + expect(result).to have_attributes( + max_complexity: GitlabSchema::DEFAULT_MAX_COMPLEXITY, + max_depth: GitlabSchema::DEFAULT_MAX_DEPTH + ) end end - context 'when no user' do - it 'returns DEFAULT_MAX_COMPLEXITY' do - expect(GraphQL::Schema) - .to receive(:execute) - .with('query', hash_including(max_complexity: GitlabSchema::DEFAULT_MAX_COMPLEXITY)) + context 'with no context' do + let(:kwargs) { {} } - described_class.execute('query', context: {}) - end + include_examples 'sets default limits' + end - it 'returns DEFAULT_MAX_DEPTH' do - expect(GraphQL::Schema) - .to receive(:execute) - .with('query', hash_including(max_depth: GitlabSchema::DEFAULT_MAX_DEPTH)) + context 'with no :current_user' do + let(:kwargs) { { context: {} } } - described_class.execute('query', context: {}) + include_examples 'sets default limits' + end + + context 'with anonymous user' do + let(:kwargs) { { context: { current_user: nil } } } + + include_examples 'sets default limits' + end + + context 'with a logged in user' do + let(:kwargs) { { context: { current_user: user } } } + + it 'sets authenticated user limits' do + expect(result).to have_attributes( + max_complexity: GitlabSchema::AUTHENTICATED_MAX_COMPLEXITY, + max_depth: GitlabSchema::AUTHENTICATED_MAX_DEPTH + ) end end - context 'when a logged in user' do - it 'returns AUTHENTICATED_COMPLEXITY' do - expect(GraphQL::Schema).to receive(:execute) - .with('query', hash_including(max_complexity: GitlabSchema::AUTHENTICATED_COMPLEXITY)) + context 'with an admin user' do + let(:kwargs) { { context: { current_user: build(:user, :admin) } } } - described_class.execute('query', context: { current_user: user }) - end - - it 'returns AUTHENTICATED_MAX_DEPTH' do - expect(GraphQL::Schema).to receive(:execute) - .with('query', hash_including(max_depth: GitlabSchema::AUTHENTICATED_MAX_DEPTH)) - - described_class.execute('query', context: { current_user: user }) + it 'sets admin/authenticated user limits' do + expect(result).to have_attributes( + max_complexity: GitlabSchema::ADMIN_MAX_COMPLEXITY, + max_depth: GitlabSchema::AUTHENTICATED_MAX_DEPTH + ) end end - context 'when an admin user' do - it 'returns ADMIN_COMPLEXITY' do - user = build :user, :admin + context 'when limits passed as kwargs' do + let(:kwargs) { { max_complexity: 1234, max_depth: 4321 } } - expect(GraphQL::Schema).to receive(:execute) - .with('query', hash_including(max_complexity: GitlabSchema::ADMIN_COMPLEXITY)) - - described_class.execute('query', context: { current_user: user }) - end - end - - context 'when max_complexity passed on the query' do - it 'returns what was passed on the query' do - expect(GraphQL::Schema).to receive(:execute).with('query', hash_including(max_complexity: 1234)) - - described_class.execute('query', max_complexity: 1234) - end - end - - context 'when max_depth passed on the query' do - it 'returns what was passed on the query' do - expect(GraphQL::Schema).to receive(:execute).with('query', hash_including(max_depth: 1234)) - - described_class.execute('query', max_depth: 1234) + it 'sets limits from the kwargs' do + expect(result).to have_attributes( + max_complexity: 1234, + max_depth: 4321 + ) end end end diff --git a/spec/requests/api/graphql_spec.rb b/spec/requests/api/graphql_spec.rb index 7b081bb7568..7d182a3414b 100644 --- a/spec/requests/api/graphql_spec.rb +++ b/spec/requests/api/graphql_spec.rb @@ -385,7 +385,7 @@ RSpec.describe 'GraphQL' do context 'authenticated user' do subject { post_graphql(query, current_user: user) } - it 'does not raise an error as it uses the `AUTHENTICATED_COMPLEXITY`' do + it 'does not raise an error as it uses the `AUTHENTICATED_MAX_COMPLEXITY`' do subject expect(graphql_errors).to be_nil diff --git a/spec/support/shared_examples/namespaces/traversal_examples.rb b/spec/support/shared_examples/namespaces/traversal_examples.rb index f09634556c3..d126b242fb0 100644 --- a/spec/support/shared_examples/namespaces/traversal_examples.rb +++ b/spec/support/shared_examples/namespaces/traversal_examples.rb @@ -55,12 +55,34 @@ RSpec.shared_examples 'namespace traversal' do end describe '#ancestors' do - it 'returns the correct ancestors' do + before do # #reload is called to make sure traversal_ids are reloaded - expect(very_deep_nested_group.reload.ancestors).to contain_exactly(group, nested_group, deep_nested_group) - expect(deep_nested_group.reload.ancestors).to contain_exactly(group, nested_group) - expect(nested_group.reload.ancestors).to contain_exactly(group) - expect(group.reload.ancestors).to eq([]) + reload_models(group, nested_group, deep_nested_group, very_deep_nested_group) + end + + it 'returns the correct ancestors' do + expect(very_deep_nested_group.ancestors).to contain_exactly(group, nested_group, deep_nested_group) + expect(deep_nested_group.ancestors).to contain_exactly(group, nested_group) + expect(nested_group.ancestors).to contain_exactly(group) + expect(group.ancestors).to eq([]) + end + + context 'with asc hierarchy_order' do + it 'returns the correct ancestors' do + expect(very_deep_nested_group.ancestors(hierarchy_order: :asc)).to eq [deep_nested_group, nested_group, group] + expect(deep_nested_group.ancestors(hierarchy_order: :asc)).to eq [nested_group, group] + expect(nested_group.ancestors(hierarchy_order: :asc)).to eq [group] + expect(group.ancestors(hierarchy_order: :asc)).to eq([]) + end + end + + context 'with desc hierarchy_order' do + it 'returns the correct ancestors' do + expect(very_deep_nested_group.ancestors(hierarchy_order: :desc)).to eq [group, nested_group, deep_nested_group] + expect(deep_nested_group.ancestors(hierarchy_order: :desc)).to eq [group, nested_group] + expect(nested_group.ancestors(hierarchy_order: :desc)).to eq [group] + expect(group.ancestors(hierarchy_order: :desc)).to eq([]) + end end describe '#recursive_ancestors' do @@ -78,6 +100,24 @@ RSpec.shared_examples 'namespace traversal' do expect(group.ancestor_ids).to be_empty end + context 'with asc hierarchy_order' do + it 'returns the correct ancestor ids' do + expect(very_deep_nested_group.ancestor_ids(hierarchy_order: :asc)).to eq [deep_nested_group.id, nested_group.id, group.id] + expect(deep_nested_group.ancestor_ids(hierarchy_order: :asc)).to eq [nested_group.id, group.id] + expect(nested_group.ancestor_ids(hierarchy_order: :asc)).to eq [group.id] + expect(group.ancestor_ids(hierarchy_order: :asc)).to eq([]) + end + end + + context 'with desc hierarchy_order' do + it 'returns the correct ancestor ids' do + expect(very_deep_nested_group.ancestor_ids(hierarchy_order: :desc)).to eq [group.id, nested_group.id, deep_nested_group.id] + expect(deep_nested_group.ancestor_ids(hierarchy_order: :desc)).to eq [group.id, nested_group.id] + expect(nested_group.ancestor_ids(hierarchy_order: :desc)).to eq [group.id] + expect(group.ancestor_ids(hierarchy_order: :desc)).to eq([]) + end + end + describe '#recursive_ancestor_ids' do let_it_be(:groups) { [nested_group, deep_nested_group, very_deep_nested_group] } @@ -93,6 +133,24 @@ RSpec.shared_examples 'namespace traversal' do expect(group.self_and_ancestors).to contain_exactly(group) end + context 'with asc hierarchy_order' do + it 'returns the correct ancestors' do + expect(very_deep_nested_group.self_and_ancestors(hierarchy_order: :asc)).to eq [very_deep_nested_group, deep_nested_group, nested_group, group] + expect(deep_nested_group.self_and_ancestors(hierarchy_order: :asc)).to eq [deep_nested_group, nested_group, group] + expect(nested_group.self_and_ancestors(hierarchy_order: :asc)).to eq [nested_group, group] + expect(group.self_and_ancestors(hierarchy_order: :asc)).to eq([group]) + end + end + + context 'with desc hierarchy_order' do + it 'returns the correct ancestors' do + expect(very_deep_nested_group.self_and_ancestors(hierarchy_order: :desc)).to eq [group, nested_group, deep_nested_group, very_deep_nested_group] + expect(deep_nested_group.self_and_ancestors(hierarchy_order: :desc)).to eq [group, nested_group, deep_nested_group] + expect(nested_group.self_and_ancestors(hierarchy_order: :desc)).to eq [group, nested_group] + expect(group.self_and_ancestors(hierarchy_order: :desc)).to eq([group]) + end + end + describe '#recursive_self_and_ancestors' do let_it_be(:groups) { [nested_group, deep_nested_group, very_deep_nested_group] } @@ -108,6 +166,24 @@ RSpec.shared_examples 'namespace traversal' do expect(group.self_and_ancestor_ids).to contain_exactly(group.id) end + context 'with asc hierarchy_order' do + it 'returns the correct ancestor ids' do + expect(very_deep_nested_group.self_and_ancestor_ids(hierarchy_order: :asc)).to eq [very_deep_nested_group.id, deep_nested_group.id, nested_group.id, group.id] + expect(deep_nested_group.self_and_ancestor_ids(hierarchy_order: :asc)).to eq [deep_nested_group.id, nested_group.id, group.id] + expect(nested_group.self_and_ancestor_ids(hierarchy_order: :asc)).to eq [nested_group.id, group.id] + expect(group.self_and_ancestor_ids(hierarchy_order: :asc)).to eq([group.id]) + end + end + + context 'with desc hierarchy_order' do + it 'returns the correct ancestor ids' do + expect(very_deep_nested_group.self_and_ancestor_ids(hierarchy_order: :desc)).to eq [group.id, nested_group.id, deep_nested_group.id, very_deep_nested_group.id] + expect(deep_nested_group.self_and_ancestor_ids(hierarchy_order: :desc)).to eq [group.id, nested_group.id, deep_nested_group.id] + expect(nested_group.self_and_ancestor_ids(hierarchy_order: :desc)).to eq [group.id, nested_group.id] + expect(group.self_and_ancestor_ids(hierarchy_order: :desc)).to eq([group.id]) + end + end + describe '#recursive_self_and_ancestor_ids' do let_it_be(:groups) { [nested_group, deep_nested_group, very_deep_nested_group] }