Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-10-31 21:11:07 +00:00
parent 30b8ea126f
commit 16776d7f4f
60 changed files with 406 additions and 208 deletions

View File

@ -351,10 +351,25 @@ Dangerfile @gl-quality/eng-prod
/spec/frontend/batch_comments/ @viktomas @jboyson @iamphill @thomasrandolph
^[Product Intelligence]
/ee/lib/gitlab/usage_data_counters/ @gitlab-org/growth/product-intelligence/engineers
/ee/lib/ee/gitlab/usage_data.rb @gitlab-org/growth/product-intelligence/engineers
/lib/gitlab/usage_data.rb @gitlab-org/growth/product_intelligence/engineers
/lib/gitlab/usage_data_counters/ @gitlab-org/growth/product-intelligence/engineers
/ee/lib/gitlab/usage_data_counters/ @gitlab-org/analytics-section/product-intelligence/engineers
/ee/lib/ee/gitlab/usage_data.rb @gitlab-org/analytics-section/product-intelligence/engineers
/lib/gitlab/usage_data.rb @gitlab-org/analytics-section/product-intelligence/engineers
/lib/gitlab/usage_data_counters/ @gitlab-org/analytics-section/product-intelligence/engineers
/lib/gitlab/usage/ @gitlab-org/analytics-section/product-intelligence/engineers
/ee/lib/ee/gitlab/usage_data_counters/ @gitlab-org/analytics-section/product-intelligence/engineers
/ee/lib/ee/gitlab/usage/ @gitlab-org/analytics-section/product-intelligence/engineers
/config/metrics/ @gitlab-org/analytics-section/product-intelligence/engineers
/ee/config/metrics/ @gitlab-org/analytics-section/product-intelligence/engineers
/app/workers/gitlab_service_ping_worker.rb @gitlab-org/analytics-section/product-intelligence/engineers
/spec/workers/gitlab_service_ping_worker_spec.rb @gitlab-org/analytics-section/product-intelligence/engineers
/ee/spec/lib/gitlab/usage_data_counters/ @gitlab-org/analytics-section/product-intelligence/engineers
/ee/spec/lib/ee/gitlab/usage_data_spec.rb @gitlab-org/analytics-section/product-intelligence/engineers
/spec/lib/gitlab/usage_data_spec.rb @gitlab-org/analytics-section/product-intelligence/engineers
/spec/lib/gitlab/usage_data_counters/ @gitlab-org/analytics-section/product-intelligence/engineers
/spec/lib/gitlab/usage/ @gitlab-org/analytics-section/product-intelligence/engineers
/ee/spec/lib/ee/gitlab/usage_data_counters/ @gitlab-org/analytics-section/product-intelligence/engineers
/ee/spec/lib/ee/gitlab/usage/ @gitlab-org/analytics-section/product-intelligence/engineers
/ee/spec/config/metrics/ @gitlab-org/analytics-section/product-intelligence/engineers
^[Growth Experiments]
/app/experiments/ @gitlab-org/growth/experiment-devs

View File

@ -398,5 +398,5 @@ compile-storybook as-if-foss:
- .as-if-foss
- .frontend:rules:default-frontend-jobs-as-if-foss
needs:
- !reference [.compile-storybook-base, needs]
- job: "graphql-schema-dump as-if-foss"
- job: "rspec-all frontend_fixture as-if-foss"

View File

@ -278,7 +278,7 @@
- "Dockerfile.assets"
- "config/**/*.js"
- "vendor/assets/**/*"
- "{app/assets,app/components,app/helpers,app/presenters,app/views,locale,public,spec/frontend,symbol}/**/*"
- "{app/assets,app/components,app/helpers,app/presenters,app/views,locale,public,spec/frontend,storybook,symbol}/**/*"
.controllers-patterns: &controllers-patterns
- "{,ee/,jh/}{app/controllers}/**/*"
@ -393,7 +393,7 @@
- "Rakefile"
- "tests.yml"
- "config.ru"
- "{,ee/,jh/}{app,bin,config,db,generator_templates,haml_lint,lib,locale,public,scripts,symbol,vendor}/**/*"
- "{,ee/,jh/}{app,bin,config,db,generator_templates,haml_lint,lib,locale,public,scripts,storybook,symbol,vendor}/**/*"
- "doc/api/graphql/reference/*" # Files in this folder are auto-generated
# CI changes
- ".gitlab-ci.yml"
@ -450,7 +450,7 @@
- "Rakefile"
- "tests.yml"
- "config.ru"
- "{,ee/,jh/}{app,bin,config,db,generator_templates,haml_lint,lib,locale,public,scripts,symbol,vendor}/**/*"
- "{,ee/,jh/}{app,bin,config,db,generator_templates,haml_lint,lib,locale,public,scripts,storybook,symbol,vendor}/**/*"
- "doc/api/graphql/reference/*" # Files in this folder are auto-generated
# CI changes
- ".gitlab-ci.yml"
@ -487,7 +487,7 @@
- "Rakefile"
- "tests.yml"
- "config.ru"
- "{,ee/,jh/}{app,bin,config,db,generator_templates,haml_lint,lib,locale,public,scripts,symbol,vendor}/**/*"
- "{,ee/,jh/}{app,bin,config,db,generator_templates,haml_lint,lib,locale,public,scripts,storybook,symbol,vendor}/**/*"
- "doc/api/graphql/reference/*" # Files in this folder are auto-generated
- "data/whats_new/*.yml"
# CI changes
@ -877,6 +877,8 @@
- <<: *if-merge-request-labels-run-all-rspec
- <<: *if-merge-request
changes: *startup-css-patterns
- <<: *if-merge-request
changes: *frontend-patterns-for-as-if-foss
.frontend:rules:frontend_fixture-as-if-foss:
rules:

View File

@ -198,31 +198,6 @@ Layout/SpaceInsideParens:
- 'spec/policies/clusters/agent_policy_spec.rb'
- 'spec/presenters/ci/build_presenter_spec.rb'
- 'spec/presenters/packages/conan/package_presenter_spec.rb'
- 'spec/requests/api/boards_spec.rb'
- 'spec/requests/api/ci/runner/jobs_artifacts_spec.rb'
- 'spec/requests/api/ci/runner/jobs_request_post_spec.rb'
- 'spec/requests/api/ci/runners_reset_registration_token_spec.rb'
- 'spec/requests/api/ci/runners_spec.rb'
- 'spec/requests/api/dependency_proxy_spec.rb'
- 'spec/requests/api/deployments_spec.rb'
- 'spec/requests/api/files_spec.rb'
- 'spec/requests/api/go_proxy_spec.rb'
- 'spec/requests/api/graphql/boards/board_list_issues_query_spec.rb'
- 'spec/requests/api/graphql/ci/jobs_spec.rb'
- 'spec/requests/api/graphql/ci/pipelines_spec.rb'
- 'spec/requests/api/graphql/mutations/award_emojis/remove_spec.rb'
- 'spec/requests/api/graphql/mutations/award_emojis/toggle_spec.rb'
- 'spec/requests/api/graphql/mutations/ci/runners_registration_token/reset_spec.rb'
- 'spec/requests/api/group_boards_spec.rb'
- 'spec/requests/api/issues/issues_spec.rb'
- 'spec/requests/api/issues/post_projects_issues_spec.rb'
- 'spec/requests/api/labels_spec.rb'
- 'spec/requests/api/merge_requests_spec.rb'
- 'spec/requests/api/pages/pages_spec.rb'
- 'spec/requests/api/project_milestones_spec.rb'
- 'spec/requests/api/project_snippets_spec.rb'
- 'spec/requests/api/snippets_spec.rb'
- 'spec/requests/api/submodules_spec.rb'
- 'spec/requests/jwt_controller_spec.rb'
- 'spec/requests/projects/merge_requests/diffs_spec.rb'
- 'spec/requests/projects/merge_requests_spec.rb'

View File

@ -57,7 +57,9 @@ export const config = {
return incoming;
}
return existing.map((existingWidget) => {
const incomingWidget = incoming.find((w) => w.type === existingWidget.type);
const incomingWidget = incoming.find(
(w) => w.type && w.type === existingWidget.type,
);
return incomingWidget || existingWidget;
});
},

View File

@ -190,7 +190,8 @@ class GraphqlController < ApplicationController
current_user: current_user,
is_sessionless_user: api_user,
request: request,
scope_validator: ::Gitlab::Auth::ScopeValidator.new(api_user, request_authenticator)
scope_validator: ::Gitlab::Auth::ScopeValidator.new(api_user, request_authenticator),
remove_deprecated: Gitlab::Utils.to_boolean(params[:remove_deprecated], default: false)
}
end

View File

@ -34,14 +34,14 @@ class RegistrationsController < Devise::RegistrationsController
def create
set_user_state
token = set_custom_confirmation_token
set_custom_confirmation_token
super do |new_user|
accept_pending_invitations if new_user.persisted?
persist_accepted_terms_if_required(new_user)
set_role_required(new_user)
send_custom_confirmation_instructions(new_user, token)
send_custom_confirmation_instructions
track_weak_password_error(new_user, self.class.name, 'create')
if pending_approval?
@ -128,7 +128,7 @@ class RegistrationsController < Devise::RegistrationsController
# after user confirms and comes back, he will be redirected
store_location_for(:redirect, users_sign_up_welcome_path(glm_tracking_params))
return identity_verification_redirect_path if custom_confirmation_enabled?(resource)
return identity_verification_redirect_path if custom_confirmation_enabled?
users_almost_there_path(email: resource.email)
end
@ -244,7 +244,7 @@ class RegistrationsController < Devise::RegistrationsController
# overridden by EE module
end
def custom_confirmation_enabled?(resource)
def custom_confirmation_enabled?
# overridden by EE module
end
@ -252,7 +252,7 @@ class RegistrationsController < Devise::RegistrationsController
# overridden by EE module
end
def send_custom_confirmation_instructions(user, token)
def send_custom_confirmation_instructions
# overridden by EE module
end
end

View File

@ -4,10 +4,10 @@ module Types
class BaseArgument < GraphQL::Schema::Argument
include GitlabStyleDeprecations
attr_reader :deprecation, :doc_reference
attr_reader :doc_reference
def initialize(*args, **kwargs, &block)
@deprecation = gitlab_deprecation(kwargs)
init_gitlab_deprecation(kwargs)
@doc_reference = kwargs.delete(:see)
# our custom addition `nullable` which allows us to declare

View File

@ -6,10 +6,8 @@ module Types
class CustomValue < GraphQL::Schema::EnumValue
include ::GitlabStyleDeprecations
attr_reader :deprecation
def initialize(name, desc = nil, **kwargs)
@deprecation = gitlab_deprecation(kwargs)
init_gitlab_deprecation(kwargs)
super(name, desc, **kwargs)
end

View File

@ -8,16 +8,16 @@ module Types
DEFAULT_COMPLEXITY = 1
attr_reader :deprecation, :doc_reference
attr_reader :doc_reference
def initialize(**kwargs, &block)
init_gitlab_deprecation(kwargs)
@calls_gitaly = !!kwargs.delete(:calls_gitaly)
@doc_reference = kwargs.delete(:see)
@constant_complexity = kwargs[:complexity].is_a?(Integer) && kwargs[:complexity] > 0
@requires_argument = !!kwargs.delete(:requires_argument)
@authorize = Array.wrap(kwargs.delete(:authorize))
kwargs[:complexity] = field_complexity(kwargs[:resolver_class], kwargs[:complexity])
@deprecation = gitlab_deprecation(kwargs)
after_connection_extensions = kwargs.delete(:late_extensions) || []
super(**kwargs, &block)

View File

@ -1,14 +1,22 @@
# frozen_string_literal: true
# Concern for handling deprecation arguments.
# Concern for handling GraphQL deprecations.
# https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#deprecating-schema-items
module GitlabStyleDeprecations
extend ActiveSupport::Concern
included do
attr_accessor :deprecation
end
def visible?(ctx)
super && ctx[:remove_deprecated] == true ? deprecation.nil? : true
end
private
# Mutate the arguments, returns the deprecation
def gitlab_deprecation(kwargs)
# Set deprecation, mutate the arguments
def init_gitlab_deprecation(kwargs)
if kwargs[:deprecation_reason].present?
raise ArgumentError, 'Use `deprecated` property instead of `deprecation_reason`. ' \
'See https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#deprecating-schema-items'
@ -17,14 +25,12 @@ module GitlabStyleDeprecations
# GitLab allows items to be marked as "alpha", which leverages GraphQL deprecations.
deprecation_args = kwargs.extract!(:alpha, :deprecated)
deprecation = ::Gitlab::Graphql::Deprecation.parse(**deprecation_args)
self.deprecation = ::Gitlab::Graphql::Deprecation.parse(**deprecation_args)
return unless deprecation
raise ArgumentError, "Bad deprecation. #{deprecation.errors.full_messages.to_sentence}" unless deprecation.valid?
kwargs[:deprecation_reason] = deprecation.deprecation_reason
kwargs[:description] = deprecation.edit_description(kwargs[:description])
deprecation
end
end

View File

@ -1706,7 +1706,11 @@ class Project < ApplicationRecord
end
def has_active_integrations?(hooks_scope = :push_hooks)
integrations.public_send(hooks_scope).any? # rubocop:disable GitlabSecurity/PublicSend
@has_active_integrations ||= {} # rubocop: disable Gitlab/PredicateMemoization
return @has_active_integrations[hooks_scope] if @has_active_integrations.key?(hooks_scope)
@has_active_integrations[hooks_scope] = integrations.public_send(hooks_scope).any? # rubocop:disable GitlabSecurity/PublicSend
end
def feature_usage

View File

@ -9,7 +9,7 @@
%tr
%td{ style: "#{default_font}vertical-align:middle;color:#ffffff;text-align:center;" }
%span
= _("Your %{host} account was signed in to from a new location") % { host: Gitlab.config.gitlab.host }
= _("Someone signed in to your %{host} account from a new location") % { host: Gitlab.config.gitlab.host }
%tr.spacer
%td{ style: spacer_style }
&nbsp;

View File

@ -32,3 +32,5 @@ metadata:
description: Operations related to deploy freeze periods
- name: release_links
description: Operations related to release assets (links)
- name: cluster_agents
description: Operations related to the GitLab agent for Kubernetes

View File

@ -102,6 +102,8 @@ Items are marked as deprecated in:
NOTE:
If you use the GraphQL API, we recommend you remove the deprecated schema from your GraphQL
API calls as soon as possible to avoid experiencing breaking changes.
To verify your API calls against the schema without the deprecated schema items, you can add a
`?remove_deprecated=true` query parameter. You should only use this parameter for verification purposes.
The deprecation message provides an alternative for the deprecated schema item,
if applicable.

View File

@ -198,18 +198,11 @@ The response is `404 Not Found` if the vulnerability export is not finished yet
Example response:
```csv
Group Name,Project Name,Tool,Scanner Name,Status,Vulnerability,Details,Additional Info,Severity,CVE,CWE,Other Identifiers
Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2017-16997 in glibc,,CVE-2017-16997 in glibc,critical,CVE-2017-16997
Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2017-18269 in glibc,,CVE-2017-18269 in glibc,critical,CVE-2017-18269
Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2018-1000001 in glibc,,CVE-2018-1000001 in glibc,high,CVE-2018-1000001
Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2016-10228 in glibc,,CVE-2016-10228 in glibc,medium,CVE-2016-10228
Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2010-4052 in glibc,,CVE-2010-4052 in glibc,low,CVE-2010-4052
Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2018-18520 in elfutils,,CVE-2018-18520 in elfutils,low,CVE-2018-18520
Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2018-16869 in nettle,,CVE-2018-16869 in nettle,unknown,CVE-2018-16869,CWE-1
Gitlab.org,Defend,dependency_scanning,Gemnasium,detected,Regular Expression Denial of Service in debug,,Regular Expression Denial of Service in debug,unknown,CVE-2021-1234,CWE-2,"""yarn.lock:debug:gemnasium:37283ed4-0380-40d7-ada7-2d994afcc62a"""
Gitlab.org,Defend,dependency_scanning,Gemnasium,detected,Authentication bypass via incorrect DOM traversal and canonicalization in saml2-js,,Authentication bypass via incorrect DOM traversal and canonicalization in saml2-js,unknown,,,"""yarn.lock:saml2-js:gemnasium:9952e574-7b5b-46fa-a270-aeb694198a98"""
Gitlab.org,Defend,sast,Find Security Bugs,detected,Predictable pseudorandom number generator,,Predictable pseudorandom number generator,medium,,,"""818bf5dacb291e15d9e6dc3c5ac32178:PREDICTABLE_RANDOM:src/main/java/com/gitlab/security_products/tests/App.java:47"""
Gitlab.org,Defend,sast,Find Security Bugs,detected,Cipher with no integrity,,Cipher with no integrity,medium,,,"""e6449b89335daf53c0db4c0219bc1634:CIPHER_INTEGRITY:src/main/java/com/gitlab/security_products/tests/App.java:29"""
Gitlab.org,Defend,sast,Find Security Bugs,detected,Predictable pseudorandom number generator,,Predictable pseudorandom number generator,medium,,,"""e8ff1d01f74cd372f78da8f5247d3e73:PREDICTABLE_RANDOM:src/main/java/com/gitlab/security_products/tests/App.java:41"""
Gitlab.org,Defend,sast,Find Security Bugs,detected,ECB mode is insecure,,ECB mode is insecure,medium,,,"""ea0f905fc76f2739d5f10a1fd1e37a10:ECB_MODE:src/main/java/com/gitlab/security_products/tests/App.java:29"""
Group Name,Project Name,Tool,Scanner Name,Status,Vulnerability,Details,Additional Info,Severity,CVE,CWE,Other Identifiers,Detected At,Location,Activity,
Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2019-14697 in musl-utils-1.1.20-r4,"musl libc through 1.1.23 has an x87 floating-point stack adjustment imbalance, related to the math/i386/ directory. In some cases, use of this library could introduce out-of-bounds writes that are not present in an application's source code.",CVE-2019-14697 in musl-utils-1.1.20-r4,critical,CVE-2019-14697,,"",2022-10-07 13:34:41 UTC,"{""image""=>""python:3.4-alpine"", ""dependency""=>{""package""=>{""name""=>""musl-utils""}, ""version""=>""1.1.20-r4""}, ""operating_system""=>""alpine 3.9.2""}",true,
Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2019-19242 in sqlite-libs-3.26.0-r3,"SQLite 3.30.1 mishandles pExpr->y.pTab, as demonstrated by the TK_COLUMN case in sqlite3ExprCodeTarget in expr.c.",CVE-2019-19242 in sqlite-libs-3.26.0-r3,medium,CVE-2019-19242,,"",2022-10-07 13:34:41 UTC,"{""image""=>""python:3.4-alpine"", ""dependency""=>{""package""=>{""name""=>""sqlite-libs""}, ""version""=>""3.26.0-r3""}, ""operating_system""=>""alpine 3.9.2""}",true,
Gitlab.org,Defend,container_scanning,Trivy,detected,CVE-2020-28928 in musl-1.1.20-r4,"In musl libc through 1.2.1, wcsnrtombs mishandles particular combinations of destination buffer size and source character limit, as demonstrated by an invalid write access (buffer overflow).",CVE-2020-28928 in musl-1.1.20-r4,medium,CVE-2020-28928,,"",2022-10-07 13:34:41 UTC,"{""image""=>""python:3.4-alpine"", ""dependency""=>{""package""=>{""name""=>""musl""}, ""version""=>""1.1.20-r4""}, ""operating_system""=>""alpine 3.9.2""}",true,
Gitlab.org,Defend,dependency_scanning,Gemnasium,detected,Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') in rack,Carefully crafted requests can cause shell escape sequences to be written to the terminal via Rack's Lint middleware and CommonLogger middleware. These escape sequences can be leveraged to possibly execute commands in the victim's terminal.,Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') in rack,unknown,Gemfile.lock:rack:gemnasium:60b5a27f-4e4d-4ab4-8ae7-74b4b212e177,,Gemnasium-60b5a27f-4e4d-4ab4-8ae7-74b4b212e177; GHSA-wq4h-7r42-5hrr,2022-10-14 13:16:00 UTC,"{""file""=>""Gemfile.lock"", ""dependency""=>{""package""=>{""name""=>""rack""}, ""version""=>""2.2.3""}}",false,
Gitlab.org,Defend,dependency_scanning,Gemnasium,detected,Denial of Service Vulnerability in Rack Multipart Parsing in rack,"Carefully crafted multipart POST requests can cause Rack's multipart parser to take much longer than expected, leading to a possible denial of service vulnerability. Impacted code will use Rack's multipart parser to parse multipart posts.",Denial of Service Vulnerability in Rack Multipart Parsing in rack,unknown,Gemfile.lock:rack:gemnasium:20daa17a-47b5-4f79-80c2-cd8f2db9805c,,Gemnasium-20daa17a-47b5-4f79-80c2-cd8f2db9805c; GHSA-hxqx-xwvh-44m2,2022-10-14 13:16:00 UTC,"{""file""=>""Gemfile.lock"", ""dependency""=>{""package""=>{""name""=>""rack""}, ""version""=>""2.2.3""}}",false,
Gitlab.org,Defend,sast,Brakeman,detected,Possible SQL injection,,Possible SQL injection,medium,e52f23a259cd489168b4313317ac94a3f13bffde57b9635171c1a44a9f329e9a,,"""Brakeman Warning Code 0""",2022-10-13 15:16:36 UTC,"{""file""=>""main.rb"", ""class""=>""User"", ""method""=>""index"", ""start_line""=>3}",false
```

View File

@ -3255,7 +3255,8 @@ Use `rules:if` clauses to specify when to add a job to a pipeline:
- If no `if` statements are true, do not add the job to the pipeline.
`if` clauses are evaluated based on the values of [predefined CI/CD variables](../variables/predefined_variables.md)
or [custom CI/CD variables](../variables/index.md#custom-cicd-variables).
or [custom CI/CD variables](../variables/index.md#custom-cicd-variables), with
[some exceptions](../variables/where_variables_can_be_used.md#gitlab-ciyml-file).
**Keyword type**: Job-specific and pipeline-specific. You can use it as part of a job
to configure the job behavior, or with [`workflow`](#workflow) to configure the pipeline behavior.

View File

@ -20,11 +20,10 @@ The acronym refers to the first letter of each topic type.
In general, each page in the GitLab documentation contains multiple topics.
Each topic on a page should be recognizable as a specific topic type.
## Other topic types
In addition to the four primary topic types, we also have a page type for
[Tutorials](tutorial.md) and [Get started](#get-started).
In addition to the four primary topic types, we have a few other types.
### Related topics
## Related topics
If inline links are not sufficient, you can create a topic called **Related topics**
and include an unordered list of related topics. This topic should be above the Troubleshooting section.
@ -36,57 +35,7 @@ and include an unordered list of related topics. This topic should be above the
- [Trigger a pipeline manually](link-to-topic).
```
### Tutorials
A tutorial is page that contains an end-to-end walkthrough of a complex workflow or scenario.
In general, you might consider using a tutorial when:
- The workflow requires a number of sequential steps where each step consists
of sub-steps.
- The steps cover a variety of GitLab features or third-party tools.
Tutorials are learning aids that complement our core documentation.
They do not introduce new features.
Always use the primary [topic types](#documentation-topic-types-ctrt) to document new features.
Tutorials should be in this format:
```markdown
# Title (starts with "Tutorial:" followed by an active verb, like "Tutorial: Create a website")
A paragraph that explains what the tutorial does, and the expected outcome.
To create a website:
1. [Do the first task](#do-the-first-task)
1. [Do the second task](#do-the-second-task)
Prerequisites (optional):
- Thing 1
- Thing 2
- Thing 3
## Do the first task
To do step 1:
1. First step.
1. Another step.
1. Another step.
## Do the second task
Before you begin, make sure you have [done the first task](#do-the-first-task).
To do step 2:
1. First step.
1. Another step.
1. Another step.
```
### Get started
## Get started
A get started page is a set of steps to help a user get set up
quickly to use a single GitLab feature or tool.
@ -110,7 +59,7 @@ consider using subsections for each distinct task.
In the left nav, use `Get started` as the text. On the page itself, spell out
the full name. For example, `Get started with application security`.
### Topics and resources
## Topics and resources
Some pages are solely a list of links to other documentation.

View File

@ -0,0 +1,79 @@
---
stage: none
group: Style Guide
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Tutorial topic type
A tutorial is page that contains an end-to-end walkthrough of a complex workflow or scenario.
In general, you might consider using a tutorial when:
- The workflow requires a number of sequential steps where each step consists
of sub-steps.
- The steps cover a variety of GitLab features or third-party tools.
Tutorials are learning aids that complement our core documentation.
They do not introduce new features.
Always use the primary [topic types](index.md) to document new features.
Tutorials should be in this format:
```markdown
# Title (starts with "Tutorial:" followed by an active verb, like "Tutorial: Create a website")
A paragraph that explains what the tutorial does, and the expected outcome.
To create a website:
1. [Do the first task](#do-the-first-task)
1. [Do the second task](#do-the-second-task)
Prerequisites (optional):
- Thing 1
- Thing 2
- Thing 3
## Do the first task
To do step 1:
1. First step.
1. Another step.
1. Another step.
## Do the second task
Before you begin, make sure you have [done the first task](#do-the-first-task).
To do step 2:
1. First step.
1. Another step.
1. Another step.
```
## Tutorial headings
Start with `Tutorial:` followed by an active verb, like `Tutorial: Create a website`.
## Screenshots
You can include screenshots in a tutorial to illustrate important steps in the process.
In the core product documentation, you should [use screenshots sparingly](../styleguide/index.md#images).
However, in tutorials, screenshots can help users understand where they are in a complex process.
Try to balance the number of screenshots in the tutorial so they don't disrupt
the narrative flow. For example, do not put one large screenshot in the middle of the tutorial.
Instead, put multiple, smaller screenshots throughout.
## Tutorial voice
Use a friendlier tone than you would for other topic types. For example,
you can:
- Add encouraging or congratulatory phrases after tasks.
- Use future tense from time to time, especially when you're introducing
steps. For example, `Next, you will associate your issues with your epics`.
- Be more conversational. For example, `This task might take a while to complete`.

View File

@ -216,6 +216,9 @@ Fields included are:
- [CVE](https://cve.mitre.org/) (Common Vulnerabilities and Exposures)
- [CWE](https://cwe.mitre.org/) (Common Weakness Enumeration)
- Other identifiers
- Detected At
- Location
- Activity
NOTE:
Full details are available through our

View File

@ -115,6 +115,14 @@ a test request to re-enable a [disabled webhook](#re-enable-disabled-webhooks).
For example, to test `push events`, your project should have at least one commit. The webhook uses this commit in the webhook.
NOTE:
Testing is not supported for some types of events for project and groups webhooks.
Read more in [issue 379201](https://gitlab.com/gitlab-org/gitlab/-/issues/379201).
Prerequisite:
- To test group webhooks, you must have administrator access for your instance.
To test a webhook:
1. In your project or group, on the left sidebar, select **Settings > Webhooks**.
@ -237,6 +245,10 @@ Webhook requests to your endpoint include the following headers:
GitLab records the history of each webhook request.
You can view requests made in the last 2 days in the **Recent events** table.
Prerequisite:
- To troubleshoot group webhooks, you must have administrator access for your instance.
To view the table:
1. In your project or group, on the left sidebar, select **Settings > Webhooks**.

View File

@ -171,6 +171,8 @@ module API
namespace do
mount ::API::AccessRequests
mount ::API::Appearance
mount ::API::Clusters::Agents
mount ::API::Clusters::AgentTokens
mount ::API::DeployKeys
mount ::API::DeployTokens
mount ::API::Deployments
@ -212,8 +214,6 @@ module API
mount ::API::Ci::SecureFiles
mount ::API::Ci::Triggers
mount ::API::Ci::Variables
mount ::API::Clusters::Agents
mount ::API::Clusters::AgentTokens
mount ::API::CommitStatuses
mount ::API::Commits
mount ::API::ComposerPackages

View File

@ -18,9 +18,10 @@ module API
end
resource ':id/cluster_agents/:agent_id' do
resource :tokens do
desc 'List agent tokens' do
detail 'This feature was introduced in GitLab 15.0.'
desc 'List tokens for an agent' do
detail 'This feature was introduced in GitLab 15.0. Returns a list of tokens for an agent.'
success Entities::Clusters::AgentTokenBasic
tags %w[cluster_agents]
end
params do
use :pagination
@ -32,8 +33,9 @@ module API
end
desc 'Get a single agent token' do
detail 'This feature was introduced in GitLab 15.0.'
detail 'This feature was introduced in GitLab 15.0. Gets a single agent token.'
success Entities::Clusters::AgentToken
tags %w[cluster_agents]
end
params do
requires :token_id, type: Integer, desc: 'The ID of the agent token'
@ -47,8 +49,9 @@ module API
end
desc 'Create an agent token' do
detail 'This feature was introduced in GitLab 15.0.'
detail 'This feature was introduced in GitLab 15.0. Creates a new token for an agent.'
success Entities::Clusters::AgentTokenWithToken
tags %w[cluster_agents]
end
params do
requires :name, type: String, desc: 'The name for the token'
@ -71,7 +74,8 @@ module API
end
desc 'Revoke an agent token' do
detail 'This feature was introduced in GitLab 15.0.'
detail 'This feature was introduced in GitLab 15.0. Revokes an agent token.'
tags %w[cluster_agents]
end
params do
requires :token_id, type: Integer, desc: 'The ID of the agent token'

View File

@ -14,9 +14,10 @@ module API
requires :id, type: String, desc: 'The ID of a project'
end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'List agents' do
detail 'This feature was introduced in GitLab 14.10.'
desc 'List the agents for a project' do
detail 'This feature was introduced in GitLab 14.10. Returns the list of agents registered for the project.'
success Entities::Clusters::Agent
tags %w[cluster_agents]
end
params do
use :pagination
@ -29,9 +30,10 @@ module API
present paginate(agents), with: Entities::Clusters::Agent
end
desc 'Get single agent' do
detail 'This feature was introduced in GitLab 14.10.'
desc 'Get details about an agent' do
detail 'This feature was introduced in GitLab 14.10. Gets a single agent details.'
success Entities::Clusters::Agent
tags %w[cluster_agents]
end
params do
requires :agent_id, type: Integer, desc: 'The ID of an agent'
@ -42,9 +44,10 @@ module API
present agent, with: Entities::Clusters::Agent
end
desc 'Add an agent to a project' do
detail 'This feature was introduced in GitLab 14.10.'
desc 'Register an agent with a project' do
detail 'This feature was introduced in GitLab 14.10. Registers an agent to the project.'
success Entities::Clusters::Agent
tags %w[cluster_agents]
end
params do
requires :name, type: String, desc: 'The name of the agent'
@ -61,8 +64,9 @@ module API
present result[:cluster_agent], with: Entities::Clusters::Agent
end
desc 'Delete an agent' do
detail 'This feature was introduced in GitLab 14.10.'
desc 'Delete a registered agent' do
detail 'This feature was introduced in GitLab 14.10. Deletes an existing agent registration.'
tags %w[cluster_agents]
end
params do
requires :agent_id, type: Integer, desc: 'The ID of an agent'

View File

@ -11,8 +11,8 @@ module API
->(obj, opts) { Ability.allowed?(opts[:user], "destroy_#{attr}".to_sym, yield(obj)) }
end
def expose_restricted(attr, &block)
expose attr, if: can_read(attr, &block)
def expose_restricted(attr, documentation: {}, &block)
expose attr, documentation: documentation, if: can_read(attr, &block)
end
end
end

View File

@ -38095,6 +38095,9 @@ msgstr ""
msgid "Someone edited this test case at the same time you did. The description has been updated and you will need to make your changes again."
msgstr ""
msgid "Someone signed in to your %{host} account from a new location"
msgstr ""
msgid "Someone, hopefully you, has requested to reset the password for your GitLab account on %{link_to_gitlab}."
msgstr ""
@ -46227,6 +46230,9 @@ msgstr ""
msgid "You are not allowed to create this tag as it is protected."
msgstr ""
msgid "You are not allowed to download code from this project."
msgstr ""
msgid "You are not allowed to log in using password"
msgstr ""
@ -46849,9 +46855,6 @@ msgstr ""
msgid "Your %{group} membership will now expire in %{days}."
msgstr ""
msgid "Your %{host} account was signed in to from a new location"
msgstr ""
msgid "Your %{spammable_entity_type} has been recognized as spam and has been discarded."
msgstr ""

View File

@ -2,7 +2,7 @@
source 'https://rubygems.org'
gem 'gitlab-qa', '~> 8', '>= 8.10.0', require: 'gitlab/qa'
gem 'gitlab-qa', '~> 8', '>= 8.10.1', require: 'gitlab/qa'
gem 'activesupport', '~> 6.1.4.7' # This should stay in sync with the root's Gemfile
gem 'allure-rspec', '~> 2.18.0'
gem 'capybara', '~> 3.37.1'

View File

@ -100,7 +100,7 @@ GEM
gitlab (4.18.0)
httparty (~> 0.18)
terminal-table (>= 1.5.1)
gitlab-qa (8.10.0)
gitlab-qa (8.10.1)
activesupport (~> 6.1)
gitlab (~> 4.18.0)
http (~> 5.0)
@ -312,7 +312,7 @@ DEPENDENCIES
faraday-retry (~> 2.0)
fog-core (= 2.1.0)
fog-google (~> 1.19)
gitlab-qa (~> 8, >= 8.10.0)
gitlab-qa (~> 8, >= 8.10.1)
influxdb-client (~> 2.8)
knapsack (~> 4.0)
nokogiri (~> 1.13, >= 1.13.9)

View File

@ -414,4 +414,114 @@ RSpec.describe GraphqlController do
expect(log_payload.dig(:exception_object)).to eq(exception)
end
end
describe 'removal of deprecated items' do
let(:mock_schema) do
Class.new(GraphQL::Schema) do
lazy_resolve ::Gitlab::Graphql::Lazy, :force
query(Class.new(::Types::BaseObject) do
graphql_name 'Query'
field :foo, GraphQL::Types::Boolean,
deprecated: { milestone: '0.1', reason: :renamed }
field :bar, (Class.new(::Types::BaseEnum) do
graphql_name 'BarEnum'
value 'FOOBAR', value: 'foobar', deprecated: { milestone: '0.1', reason: :renamed }
end)
field :baz, GraphQL::Types::Boolean do
argument :arg, String, required: false, deprecated: { milestone: '0.1', reason: :renamed }
end
def foo
false
end
def bar
'foobar'
end
def baz(arg:)
false
end
end)
end
end
before do
allow(GitlabSchema).to receive(:execute).and_wrap_original do |method, *args|
mock_schema.execute(*args)
end
end
context 'without `remove_deprecated` param' do
let(:params) { { query: '{ foo bar baz(arg: "test") }' } }
subject { post :execute, params: params }
it "sets context's `remove_deprecated` value to false" do
subject
expect(assigns(:context)[:remove_deprecated]).to be false
end
it 'returns deprecated items in response' do
subject
expect(json_response).to include('data' => { 'foo' => false, 'bar' => 'FOOBAR', 'baz' => false })
end
end
context 'with `remove_deprecated` param' do
let(:params) { { remove_deprecated: 'true' } }
subject { post :execute, params: params }
it "sets context's `remove_deprecated` value to true" do
subject
expect(assigns(:context)[:remove_deprecated]).to be true
end
it 'does not allow deprecated field' do
params[:query] = '{ foo }'
subject
expect(json_response).not_to include('data' => { 'foo' => false })
expect(json_response).to include(
'errors' => include(a_hash_including('message' => /Field 'foo' doesn't exist on type 'Query'/))
)
end
it 'does not allow deprecated enum value' do
params[:query] = '{ bar }'
subject
expect(json_response).not_to include('data' => { 'bar' => 'FOOBAR' })
expect(json_response).to include(
'errors' => include(
a_hash_including(
'message' => /`Query.bar` returned `"foobar"` at `bar`, but this isn't a valid value for `BarEnum`/
)
)
)
end
it 'does not allow deprecated argument' do
params[:query] = '{ baz(arg: "test") }'
subject
expect(json_response).not_to include('data' => { 'bar' => 'FOOBAR' })
expect(json_response).to include(
'errors' => include(a_hash_including('message' => /Field 'baz' doesn't accept argument 'arg'/))
)
end
end
end
end

View File

@ -400,9 +400,7 @@ RSpec.describe 'Merge request > User sees merge widget', :js do
it 'updates the MR widget', :sidekiq_might_not_need_inline do
click_button 'Merge'
page.within('.mr-widget-body') do
expect(page).to have_content('An error occurred while merging')
end
expect(page).to have_content('An error occurred while merging')
end
end

View File

@ -9,7 +9,7 @@ RSpec.describe Mutations::ResolvesGroup do
end
end
let(:context) { double }
let(:context) { {} }
subject(:mutation) { mutation_class.new(object: nil, context: context, field: nil) }

View File

@ -5799,7 +5799,7 @@ RSpec.describe Project, factory_default: :keep do
end
describe '#has_active_integrations?' do
let_it_be(:project) { create(:project) }
let_it_be_with_refind(:project) { create(:project) }
it { expect(project.has_active_integrations?).to eq(false) }
@ -5809,6 +5809,20 @@ RSpec.describe Project, factory_default: :keep do
expect(project.has_active_integrations?(:merge_request_hooks)).to eq(false)
expect(project.has_active_integrations?).to eq(true)
end
it 'caches matching integrations' do
create(:custom_issue_tracker_integration, push_events: true, merge_requests_events: false, project: project)
expect(project.has_active_integrations?(:merge_request_hooks)).to eq(false)
expect(project.has_active_integrations?).to eq(true)
count = ActiveRecord::QueryRecorder.new do
expect(project.has_active_integrations?(:merge_request_hooks)).to eq(false)
expect(project.has_active_integrations?).to eq(true)
end.count
expect(count).to eq(0)
end
end
describe '#badges' do

View File

@ -7,7 +7,7 @@ RSpec.describe API::Boards do
let_it_be(:non_member) { create(:user) }
let_it_be(:guest) { create(:user) }
let_it_be(:admin) { create(:user, :admin) }
let_it_be(:board_parent, reload: true) { create(:project, :public, creator_id: user.id, namespace: user.namespace ) }
let_it_be(:board_parent, reload: true) { create(:project, :public, creator_id: user.id, namespace: user.namespace) }
let_it_be(:dev_label) do
create(:label, title: 'Development', color: '#FFAABB', project: board_parent)
@ -97,7 +97,7 @@ RSpec.describe API::Boards do
describe "POST /groups/:id/boards/:board_id/lists" do
let_it_be(:group) { create(:group) }
let_it_be(:board_parent) { create(:group, parent: group ) }
let_it_be(:board_parent) { create(:group, parent: group) }
let(:url) { "/groups/#{board_parent.id}/boards/#{board.id}/lists" }
let_it_be(:board) { create(:board, group: board_parent) }

View File

@ -238,7 +238,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
context 'authorization token is invalid' do
it 'responds with forbidden' do
authorize_artifacts(token: 'invalid', filesize: 100 )
authorize_artifacts(token: 'invalid', filesize: 100)
expect(response).to have_gitlab_http_status(:forbidden)
end

View File

@ -462,7 +462,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
request_job info: { 'config' => { 'gpus' => 'all', 'ignored' => 'hello' } }
expect(response).to have_gitlab_http_status(:created)
expect(runner.reload.config).to eq( { 'gpus' => 'all' } )
expect(runner.reload.config).to eq({ 'gpus' => 'all' })
end
it "sets the runner's ip_address" do

View File

@ -118,7 +118,7 @@ RSpec.describe API::Ci::Runners do
end
include_context 'when authorized', 'group' do
let_it_be(:user) { create_default(:group_member, :owner, user: create(:user), group: group ).user }
let_it_be(:user) { create_default(:group_member, :owner, user: create(:user), group: group).user }
def get_token
group.reload.runners_token

View File

@ -399,7 +399,7 @@ RSpec.describe API::Ci::Runners do
it 'unrelated runner attribute on an existing runner with too many tags' do
# This test ensures that it is possible to update any attribute on a runner that currently fails the
# validation that ensures that there aren't too many tags associated with a runner
existing_invalid_shared_runner = build(:ci_runner, :instance, tag_list: (1..::Ci::Runner::TAG_LIST_MAX_LENGTH + 1).map { |i| "tag#{i}" } )
existing_invalid_shared_runner = build(:ci_runner, :instance, tag_list: (1..::Ci::Runner::TAG_LIST_MAX_LENGTH + 1).map { |i| "tag#{i}" })
existing_invalid_shared_runner.save!(validate: false)
active = existing_invalid_shared_runner.active

View File

@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe API::DependencyProxy, api: true do
let_it_be(:user) { create(:user) }
let_it_be(:blob) { create(:dependency_proxy_blob ) }
let_it_be(:blob) { create(:dependency_proxy_blob) }
let_it_be(:group, reload: true) { blob.group }
before do

View File

@ -325,7 +325,7 @@ RSpec.describe API::Deployments do
context 'as non member' do
it 'returns a 404 status code' do
post(
api( "/projects/#{project.id}/deployments", non_member),
api("/projects/#{project.id}/deployments", non_member),
params: {
environment: 'production',
sha: '123',

View File

@ -11,7 +11,7 @@ RSpec.describe API::Files do
let_it_be(:inherited_reporter) { create(:user) }
let_it_be(:inherited_developer) { create(:user) }
let!(:project) { create(:project, :repository, namespace: user.namespace ) }
let!(:project) { create(:project, :repository, namespace: user.namespace) }
let(:guest) { create(:user) { |u| project.add_guest(u) } }
let(:file_path) { 'files%2Fruby%2Fpopen%2Erb' }
let(:file_name) { 'popen.rb' }
@ -935,7 +935,7 @@ RSpec.describe API::Files do
end
context 'and the repo is empty' do
let!(:project) { create(:project_empty_repo, namespace: user.namespace ) }
let!(:project) { create(:project_empty_repo, namespace: user.namespace) }
it_behaves_like 'creates a new file in the project repo' do
let(:current_user) { user }

View File

@ -16,12 +16,12 @@ RSpec.describe API::GoProxy do
let_it_be(:modules) do
commits = [
create(:go_module_commit, :files, project: project, tag: 'v1.0.0', files: { 'README.md' => 'Hi' } ),
create(:go_module_commit, :module, project: project, tag: 'v1.0.1' ),
create(:go_module_commit, :package, project: project, tag: 'v1.0.2', path: 'pkg' ),
create(:go_module_commit, :module, project: project, tag: 'v1.0.3', name: 'mod' ),
create(:go_module_commit, :files, project: project, files: { 'y.go' => "package a\n" } ),
create(:go_module_commit, :module, project: project, name: 'v2' ),
create(:go_module_commit, :files, project: project, tag: 'v1.0.0', files: { 'README.md' => 'Hi' }),
create(:go_module_commit, :module, project: project, tag: 'v1.0.1'),
create(:go_module_commit, :package, project: project, tag: 'v1.0.2', path: 'pkg'),
create(:go_module_commit, :module, project: project, tag: 'v1.0.3', name: 'mod'),
create(:go_module_commit, :files, project: project, files: { 'y.go' => "package a\n" }),
create(:go_module_commit, :module, project: project, name: 'v2'),
create(:go_module_commit, :files, project: project, tag: 'v2.0.0', files: { 'v2/x.go' => "package a\n" })
]
@ -288,10 +288,10 @@ RSpec.describe API::GoProxy do
let_it_be(:base) { "#{Settings.build_gitlab_go_url}/#{project.full_path}" }
let_it_be(:modules) do
create(:go_module_commit, :files, project: project, files: { 'a.go' => "package\a" } )
create(:go_module_commit, :files, project: project, files: { 'a.go' => "package\a" })
create(:go_module_commit, :files, project: project, tag: 'v1.0.0', files: { 'go.mod' => "module not/a/real/module\n" })
create(:go_module_commit, :files, project: project, files: { 'v2/a.go' => "package a\n" } )
create(:go_module_commit, :files, project: project, tag: 'v2.0.0', files: { 'v2/go.mod' => "module #{base}\n" } )
create(:go_module_commit, :files, project: project, files: { 'v2/a.go' => "package a\n" })
create(:go_module_commit, :files, project: project, tag: 'v2.0.0', files: { 'v2/go.mod' => "module #{base}\n" })
end
describe 'GET /projects/:id/packages/go/*module_name/@v/list' do

View File

@ -7,7 +7,7 @@ RSpec.describe 'get board lists' do
let_it_be(:user) { create(:user) }
let_it_be(:unauth_user) { create(:user) }
let_it_be(:project) { create(:project, creator_id: user.id, namespace: user.namespace ) }
let_it_be(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
let_it_be(:group) { create(:group, :private) }
let_it_be(:project_label) { create(:label, project: project, name: 'Development') }
let_it_be(:project_label2) { create(:label, project: project, name: 'Testing') }

View File

@ -109,7 +109,7 @@ RSpec.describe 'Query.project.pipeline' do
'name' => 'docker 1 2',
'needs' => { 'nodes' => [] },
'previousStageJobsOrNeeds' => { 'nodes' => [
a_hash_including( 'name' => 'my test job' )
a_hash_including('name' => 'my test job')
] }
),
a_hash_including(
@ -129,7 +129,7 @@ RSpec.describe 'Query.project.pipeline' do
'name' => 'rspec 2 2',
'needs' => { 'nodes' => [a_hash_including('name' => 'my test job')] },
'previousStageJobsOrNeeds' => { 'nodes' => [
a_hash_including('name' => 'my test job' )
a_hash_including('name' => 'my test job')
] }
)
)

View File

@ -419,7 +419,7 @@ RSpec.describe 'Query.project(fullPath).pipelines' do
end
before do
create(:ci_sources_pipeline, source_pipeline: upstream_pipeline, pipeline: pipeline )
create(:ci_sources_pipeline, source_pipeline: upstream_pipeline, pipeline: pipeline)
post_graphql(query, current_user: user)
end
@ -441,10 +441,10 @@ RSpec.describe 'Query.project(fullPath).pipelines' do
pipeline_2 = create(:ci_pipeline, project: project, user: user)
upstream_pipeline_2 = create(:ci_pipeline, project: upstream_project, user: user)
create(:ci_sources_pipeline, source_pipeline: upstream_pipeline_2, pipeline: pipeline_2 )
create(:ci_sources_pipeline, source_pipeline: upstream_pipeline_2, pipeline: pipeline_2)
pipeline_3 = create(:ci_pipeline, project: project, user: user)
upstream_pipeline_3 = create(:ci_pipeline, project: upstream_project, user: user)
create(:ci_sources_pipeline, source_pipeline: upstream_pipeline_3, pipeline: pipeline_3 )
create(:ci_sources_pipeline, source_pipeline: upstream_pipeline_3, pipeline: pipeline_3)
expect do
post_graphql(query, current_user: second_user)

View File

@ -20,7 +20,7 @@ RSpec.describe 'Removing an AwardEmoji' do
end
def create_award_emoji(user)
create(:award_emoji, name: emoji_name, awardable: awardable, user: user )
create(:award_emoji, name: emoji_name, awardable: awardable, user: user)
end
shared_examples 'a mutation that does not destroy an AwardEmoji' do

View File

@ -32,7 +32,7 @@ RSpec.describe 'Toggling an AwardEmoji' do
end
def create_award_emoji(user)
create(:award_emoji, name: emoji_name, awardable: awardable, user: user )
create(:award_emoji, name: emoji_name, awardable: awardable, user: user)
end
context 'when the user has permission' do

View File

@ -87,7 +87,7 @@ RSpec.describe 'RunnersRegistrationTokenReset' do
include_context('when unauthorized', 'group')
include_context 'when authorized', 'group' do
let_it_be(:user) { create_default(:group_member, :owner, user: create(:user), group: group ).user }
let_it_be(:user) { create_default(:group_member, :owner, user: create(:user), group: group).user }
def get_token
group.reload.runners_token

View File

@ -13,7 +13,7 @@ RSpec.describe API::GroupBoards do
board_parent.add_owner(user)
end
let_it_be(:project) { create(:project, :public, namespace: board_parent ) }
let_it_be(:project) { create(:project, :public, namespace: board_parent) }
let_it_be(:dev_label) do
create(:group_label, title: 'Development', color: '#FFAABB', group: board_parent)

View File

@ -92,7 +92,7 @@ RSpec.describe API::Issues do
describe 'GET /issues/:id' do
context 'when unauthorized' do
it 'returns unauthorized' do
get api("/issues/#{issue.id}" )
get api("/issues/#{issue.id}")
expect(response).to have_gitlab_http_status(:unauthorized)
end
@ -101,7 +101,7 @@ RSpec.describe API::Issues do
context 'when authorized' do
context 'as a normal user' do
it 'returns forbidden' do
get api("/issues/#{issue.id}", user )
get api("/issues/#{issue.id}", user)
expect(response).to have_gitlab_http_status(:forbidden)
end

View File

@ -473,8 +473,8 @@ RSpec.describe API::Issues do
end
describe '/projects/:id/issues/:issue_iid/move' do
let!(:target_project) { create(:project, creator_id: user.id, namespace: user.namespace ) }
let!(:target_project2) { create(:project, creator_id: non_member.id, namespace: non_member.namespace ) }
let!(:target_project) { create(:project, creator_id: user.id, namespace: user.namespace) }
let!(:target_project2) { create(:project, creator_id: non_member.id, namespace: non_member.namespace) }
it 'moves an issue' do
post api("/projects/#{project.id}/issues/#{issue.iid}/move", user),

View File

@ -234,7 +234,7 @@ RSpec.describe API::Labels do
before do
create(:labeled_issue, project: project, labels: [group_label], author: user)
create(:labeled_issue, project: project, labels: [label1], author: user, state: :closed)
create(:labeled_merge_request, labels: [priority_label], author: user, source_project: project )
create(:labeled_merge_request, labels: [priority_label], author: user, source_project: project)
end
it 'includes counts in the response' do

View File

@ -3022,7 +3022,7 @@ RSpec.describe API::MergeRequests do
describe "PUT /projects/:id/merge_requests/:merge_request_iid" do
context 'updates force_remove_source_branch properly' do
it 'sets to false' do
merge_request.update!(merge_params: { 'force_remove_source_branch' => true } )
merge_request.update!(merge_params: { 'force_remove_source_branch' => true })
expect(merge_request.force_remove_source_branch?).to be_truthy
@ -3034,7 +3034,7 @@ RSpec.describe API::MergeRequests do
end
it 'sets to true' do
merge_request.update!(merge_params: { 'force_remove_source_branch' => false } )
merge_request.update!(merge_params: { 'force_remove_source_branch' => false })
expect(merge_request.force_remove_source_branch?).to be false

View File

@ -253,7 +253,7 @@ RSpec.describe API::Ml::Mlflow do
it 'creates the experiment', :aggregate_failures do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to include('experiment_id' )
expect(json_response).to include('experiment_id')
end
describe 'Error States' do

View File

@ -36,7 +36,7 @@ RSpec.describe API::Pages do
end
it 'removes the pages' do
delete api("/projects/#{project.id}/pages", admin )
delete api("/projects/#{project.id}/pages", admin)
expect(project.reload.pages_metadatum.deployed?).to be(false)
end

View File

@ -87,7 +87,7 @@ RSpec.describe API::PersonalAccessTokens do
end
context 'filter with created parameter' do
let_it_be(:token1) { create(:personal_access_token, created_at: DateTime.new(2022, 01, 01, 12, 30, 25) ) }
let_it_be(:token1) { create(:personal_access_token, created_at: DateTime.new(2022, 01, 01, 12, 30, 25)) }
context 'test created_before' do
where(:created_at, :status, :result_count, :result) do
@ -121,7 +121,7 @@ RSpec.describe API::PersonalAccessTokens do
end
context 'filter with last_used parameter' do
let_it_be(:token1) { create(:personal_access_token, last_used_at: DateTime.new(2022, 01, 01, 12, 30, 25) ) }
let_it_be(:token1) { create(:personal_access_token, last_used_at: DateTime.new(2022, 01, 01, 12, 30, 25)) }
let_it_be(:never_used_token) { create(:personal_access_token) }
context 'test last_used_before' do
@ -209,13 +209,13 @@ RSpec.describe API::PersonalAccessTokens do
expect(response).to have_gitlab_http_status(status)
expect(json_response.map { |pat| pat['id'] } ).to include(*result) if status == :ok
expect(json_response.map { |pat| pat['id'] }).to include(*result) if status == :ok
end
end
end
context 'filter last_used_before and last_used_after combined is valid' do
let_it_be(:token1) { create(:personal_access_token, last_used_at: DateTime.new(2022, 01, 02) ) }
let_it_be(:token1) { create(:personal_access_token, last_used_at: DateTime.new(2022, 01, 02)) }
where(:last_used_before, :last_used_after, :status, :result) do
'2022-01-02' | '2022-01-02' | :ok | lazy { [token1.id] }
@ -232,7 +232,7 @@ RSpec.describe API::PersonalAccessTokens do
expect(response).to have_gitlab_http_status(status)
expect(json_response.map { |pat| pat['id'] } ).to include(*result) if status == :ok
expect(json_response.map { |pat| pat['id'] }).to include(*result) if status == :ok
end
end
end
@ -304,7 +304,7 @@ RSpec.describe API::PersonalAccessTokens do
# Here it is only tested whether PATs to which the user has no access right are excluded from the filter function.
context 'filter with created parameter' do
let_it_be(:token1) do
create(:personal_access_token, created_at: DateTime.new(2022, 01, 02, 12, 30, 25), user: current_user )
create(:personal_access_token, created_at: DateTime.new(2022, 01, 02, 12, 30, 25), user: current_user)
end
let_it_be(:token2) { create(:personal_access_token, created_at: DateTime.new(2022, 01, 02, 12, 30, 25)) }
@ -332,7 +332,7 @@ RSpec.describe API::PersonalAccessTokens do
create(:personal_access_token, last_used_at: DateTime.new(2022, 01, 01, 12, 30, 25), user: current_user)
end
let_it_be(:token2) { create(:personal_access_token, last_used_at: DateTime.new(2022, 01, 01, 12, 30, 25) ) }
let_it_be(:token2) { create(:personal_access_token, last_used_at: DateTime.new(2022, 01, 01, 12, 30, 25)) }
let_it_be(:never_used_token) { create(:personal_access_token) }
let_it_be(:status) { :ok }

View File

@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe API::ProjectMilestones do
let_it_be(:user) { create(:user) }
let_it_be_with_reload(:project) { create(:project, namespace: user.namespace ) }
let_it_be_with_reload(:project) { create(:project, namespace: user.namespace) }
let_it_be(:closed_milestone) { create(:closed_milestone, project: project, title: 'version1', description: 'closed milestone') }
let_it_be(:milestone) { create(:milestone, project: project, title: 'version2', description: 'open milestone') }
let_it_be(:route) { "/projects/#{project.id}/milestones" }

View File

@ -89,7 +89,7 @@ RSpec.describe API::ProjectSnippets do
expect(json_response['title']).to eq(snippet.title)
expect(json_response['description']).to eq(snippet.description)
expect(json_response['file_name']).to eq(snippet.file_name_on_repo)
expect(json_response['files']).to eq(snippet.blobs.map { |blob| snippet_blob_file(blob) } )
expect(json_response['files']).to eq(snippet.blobs.map { |blob| snippet_blob_file(blob) })
expect(json_response['ssh_url_to_repo']).to eq(snippet.ssh_url_to_repo)
expect(json_response['http_url_to_repo']).to eq(snippet.http_url_to_repo)
end

View File

@ -28,7 +28,7 @@ RSpec.describe API::Snippets, factory_default: :keep do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.map { |snippet| snippet['id'] } ).to contain_exactly(
expect(json_response.map { |snippet| snippet['id'] }).to contain_exactly(
public_snippet.id,
internal_snippet.id,
private_snippet.id)
@ -75,7 +75,7 @@ RSpec.describe API::Snippets, factory_default: :keep do
it 'returns snippets available for user in given time range' do
get api(path, personal_access_token: user_token)
expect(json_response.map { |snippet| snippet['id'] } ).to contain_exactly(
expect(json_response.map { |snippet| snippet['id'] }).to contain_exactly(
private_snippet_in_time_range1.id,
private_snippet_in_time_range2.id)
end
@ -99,10 +99,10 @@ RSpec.describe API::Snippets, factory_default: :keep do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.map { |snippet| snippet['id'] } ).to contain_exactly(
expect(json_response.map { |snippet| snippet['id'] }).to contain_exactly(
public_snippet.id,
public_snippet_other.id)
expect(json_response.map { |snippet| snippet['web_url'] } ).to contain_exactly(
expect(json_response.map { |snippet| snippet['web_url'] }).to contain_exactly(
"http://localhost/-/snippets/#{public_snippet.id}",
"http://localhost/-/snippets/#{public_snippet_other.id}")
expect(json_response[0]['files'].first).to eq snippet_blob_file(public_snippet_other.blobs.first)
@ -126,7 +126,7 @@ RSpec.describe API::Snippets, factory_default: :keep do
it 'returns public snippets available to user in given time range' do
get api(path, personal_access_token: user_token)
expect(json_response.map { |snippet| snippet['id'] } ).to contain_exactly(
expect(json_response.map { |snippet| snippet['id'] }).to contain_exactly(
public_snippet_in_time_range.id)
end
end

View File

@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe API::Submodules do
let(:user) { create(:user) }
let!(:project) { create(:project, :repository, namespace: user.namespace ) }
let!(:project) { create(:project, :repository, namespace: user.namespace) }
let(:guest) { create(:user) { |u| project.add_guest(u) } }
let(:submodule) { 'six' }
let(:commit_sha) { 'e25eda1fece24ac7a03624ed1320f82396f35bd8' }

View File

@ -86,4 +86,25 @@ RSpec.shared_examples 'Gitlab-style deprecations' do
eq("`alpha` and `deprecated` arguments cannot be passed at the same time")
)
end
describe 'visible?' do
let(:ctx) { {} }
it 'defaults to true' do
expect(subject).to be_visible(ctx)
end
context 'when subject is deprecated' do
let(:arguments) { { deprecated: { milestone: '1.10', reason: :renamed } } }
it 'defaults to true' do
expect(subject(arguments)).to be_visible(ctx)
end
it 'returns false if `remove_deprecated` is true in context' do
ctx = { remove_deprecated: true }
expect(subject(arguments)).not_to be_visible(ctx)
end
end
end
end