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] }