Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-06-24 06:09:01 +00:00
parent 4870899d6c
commit fa7ac2663b
749 changed files with 975 additions and 861 deletions

View File

@ -450,6 +450,11 @@ Rails/TimeZone:
- 'spec/models/**/*'
- 'ee/app/models/**/*'
- 'ee/spec/models/**/*'
- 'app/workers/**/*'
- 'spec/workers/**/*'
- 'ee/app/workers/**/*'
- 'ee/spec/workers/**/*'
# WIP: See https://gitlab.com/gitlab-org/gitlab/-/issues/220040
Rails/SaveBang:

View File

@ -3,8 +3,10 @@
* This is tightly coupled to projects/issues/_issue.html.haml,
* any changes done to the haml need to be reflected here.
*/
// TODO: need to move this component to graphql - https://gitlab.com/gitlab-org/gitlab/-/issues/221246
import { escape, isNumber } from 'lodash';
import { GlLink, GlTooltipDirective as GlTooltip } from '@gitlab/ui';
import { GlLink, GlTooltipDirective as GlTooltip, GlLabel } from '@gitlab/ui';
import {
dateInWords,
formatDate,
@ -18,16 +20,21 @@ import initUserPopovers from '~/user_popovers';
import { mergeUrlParams } from '~/lib/utils/url_utility';
import Icon from '~/vue_shared/components/icon.vue';
import IssueAssignees from '~/vue_shared/components/issue/issue_assignees.vue';
import { isScopedLabel } from '~/lib/utils/common_utils';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
export default {
isScopedLabel,
components: {
Icon,
IssueAssignees,
GlLink,
GlLabel,
},
directives: {
GlTooltip,
},
mixins: [glFeatureFlagsMixin()],
props: {
issuable: {
type: Object,
@ -57,8 +64,8 @@ export default {
return this.issuableLink({ milestone_title: title });
},
hasLabels() {
return Boolean(this.issuable.labels && this.issuable.labels.length);
scopedLabelsAvailable() {
return this.glFeatures.scopedLabels;
},
hasWeight() {
return isNumber(this.issuable.weight);
@ -163,15 +170,12 @@ export default {
initUserPopovers([this.$refs.openedAgoByContainer.querySelector('a')]);
},
methods: {
labelStyle(label) {
return {
backgroundColor: label.color,
color: label.text_color,
};
},
issuableLink(params) {
return mergeUrlParams(params, this.baseUrl);
},
isScoped({ name }) {
return isScopedLabel({ title: name }) && this.scopedLabelsAvailable;
},
labelHref({ name }) {
return this.issuableLink({ 'label_name[]': name });
},
@ -221,9 +225,9 @@ export default {
></i>
<gl-link :href="issuable.web_url">{{ issuable.title }}</gl-link>
</span>
<span v-if="issuable.has_tasks" class="ml-1 task-status d-none d-sm-inline-block">{{
issuable.task_status
}}</span>
<span v-if="issuable.has_tasks" class="ml-1 task-status d-none d-sm-inline-block">
{{ issuable.task_status }}
</span>
</div>
<div class="issuable-info">
@ -256,22 +260,19 @@ export default {
{{ dueDateWords }}
</span>
<span v-if="hasLabels" class="js-labels">
<gl-link
v-for="label in issuable.labels"
:key="label.id"
class="label-link mr-1"
:href="labelHref(label)"
>
<span
v-gl-tooltip
class="badge color-label"
:style="labelStyle(label)"
:title="label.description"
>{{ label.name }}</span
>
</gl-link>
</span>
<gl-label
v-for="label in issuable.labels"
:key="label.id"
:target="labelHref(label)"
:background-color="label.color"
:description="label.description"
:color="label.text_color"
:title="label.name"
:scoped="isScoped(label)"
size="sm"
class="mr-1"
>{{ label.name }}</gl-label
>
<span
v-if="hasWeight"

View File

@ -8,7 +8,7 @@ module Resolvers
argument :search, GraphQL::STRING_TYPE,
required: false,
description: 'Search query'
description: 'Search query for environment name'
argument :states, [GraphQL::STRING_TYPE],
required: false,

View File

@ -44,7 +44,7 @@ module Resolvers
description: 'Issues closed after this date'
argument :search, GraphQL::STRING_TYPE,
required: false,
description: 'Search query for finding issues by title or description'
description: 'Search query for issue title or description'
argument :sort, Types::IssueSortEnum,
description: 'Sort issues by this criteria',
required: false,

View File

@ -10,7 +10,7 @@ module Resolvers
argument :search, GraphQL::STRING_TYPE,
required: false,
description: 'Search criteria'
description: 'Search query for project name, path, or description'
def resolve(**args)
ProjectsFinder

View File

@ -17,7 +17,7 @@ module Types
resolver: Resolvers::ErrorTracking::SentryErrorsResolver do
argument :search_term,
String,
description: 'Search term for the Sentry error.',
description: 'Search query for the Sentry error details',
required: false
argument :sort,
String,

View File

@ -73,7 +73,7 @@ module Reenqueuer
# end
#
def ensure_minimum_duration(minimum_duration)
start_time = Time.now
start_time = Time.current
result = yield
@ -95,7 +95,7 @@ module Reenqueuer
end
def elapsed_time(start_time)
Time.now - start_time
Time.current - start_time
end
end
end

View File

@ -62,7 +62,7 @@ module Gitlab
end
def build_label_attrs(issue_id, label_id)
time = Time.now
time = Time.current
{
label_id: label_id,
target_id: issue_id,

View File

@ -80,7 +80,7 @@ class ProcessCommitWorker
# manually parse these values.
hash.each do |key, value|
if key.to_s.end_with?(date_suffix) && value.is_a?(String)
hash[key] = Time.parse(value)
hash[key] = Time.zone.parse(value)
end
end

View File

@ -34,7 +34,7 @@ module RepositoryCheck
end
def perform_repository_checks
start = Time.now
start = Time.current
# This loop will break after a little more than one hour ('a little
# more' because `git fsck` may take a few minutes), or if it runs out of
@ -42,7 +42,7 @@ module RepositoryCheck
# RepositoryCheckWorker each hour so that as long as there are repositories to
# check, only one (or two) will be checked at a time.
project_ids.each do |project_id|
break if Time.now - start >= RUN_TIME
break if Time.current - start >= RUN_TIME
next unless try_obtain_lease_for_project(project_id)

View File

@ -17,7 +17,7 @@ module RepositoryCheck
def update_repository_check_status(project, healthy)
project.update_columns(
last_repository_check_failed: !healthy,
last_repository_check_at: Time.now
last_repository_check_at: Time.current
)
end

View File

@ -3,7 +3,7 @@
#
# Checks for unexpanded acronyms.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: conditional
message: '"%s" has no definition.'
link: https://about.gitlab.com/handbook/marketing/growth-marketing/content/editorial-team/#acronyms

View File

@ -3,7 +3,7 @@
#
# Verifies that badges are not mixed case, which won't render properly.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: existence
message: 'Badge "%s" must be capitalized.'
link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#product-badges

View File

@ -3,7 +3,7 @@
#
# Checks that US spelling is used over British spelling.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: substitution
message: 'Use the US spelling "%s" instead of the British "%s".'
link: https://about.gitlab.com/handbook/communication/#top-misused-terms

View File

@ -3,7 +3,7 @@
#
# Ensures all codeblock language tags use the full name, not aliases.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: existence
message: 'Syntax highlighting hint "%s" must be one of: yaml, ruby, plaintext, markdown, javascript, shell, golang, python, dockerfile, or typescript.'
link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#code-blocks

View File

@ -3,7 +3,7 @@
#
# Checks for use of common and uncommon contractions.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: substitution
message: 'Use "%s" instead of "%s", for a friendly, informal tone.'
link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#language

View File

@ -3,7 +3,7 @@
#
# Ensures all codeblocks using curl quote any URL strings.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: existence
message: 'Curl commands must wrap URLs in double quotes ("): %s'
link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#curl-commands

View File

@ -2,7 +2,7 @@
# Suggestion: gitlab.CurrentStatus
# Checks for words that indicate a product or feature may change in the future.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: existence
message: 'Avoid words like "%s" that promise future changes.'
level: suggestion

View File

@ -3,7 +3,7 @@
#
# Checks for use of first person pronouns.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: existence
message: '"%s" is a first-person pronoun. Use second- or third-person pronouns (like we, you, us, one) instead.'
level: warning

View File

@ -3,7 +3,7 @@
#
# Checks that internal links have .md extenstion and not .html extension.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: existence
message: 'Link "%s" must use the .md file extension.'
link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#links-to-internal-documentation

View File

@ -3,7 +3,7 @@
#
# Checks for use of latin terms.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: substitution
message: 'Use "%s" instead of "%s", but consider rewriting the sentence.'
link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#language

View File

@ -3,7 +3,7 @@
#
# Checks for the presence of semantically unhelpful words in link text.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: existence
message: 'Improve SEO and accessibility by rewriting "%s" in the link text.'
level: warning

View File

@ -3,7 +3,7 @@
#
# Checks for the presence of merge conflict markers.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: existence
message: 'Merge conflict marker "%s" found.'
link: https://docs.gitlab.com/ee/development/code_review.html#merging-a-merge-request

View File

@ -4,7 +4,7 @@
# Checks for the lack of an Oxford comma. In some cases, will catch overly
# complex sentence structures with lots of commas.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: existence
message: 'Use a comma before the last "and" or "or" in a list of four or more items.'
link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#punctuation

View File

@ -3,7 +3,7 @@
#
# Checks for the presence of reference-style links that must be inline.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: existence
message: 'Link "%s" must be inline.'
link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#basic-link-criteria

View File

@ -3,7 +3,7 @@
#
# Checks for the presence of absolute hyperlinks that should be relative.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: existence
message: 'Link "%s" must be relative.'
link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#links-to-internal-documentation

View File

@ -3,7 +3,7 @@
#
# Checks for duplicate words, like `the the` or `and and`.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: repetition
message: '"%s" is repeated.'
level: error

View File

@ -3,7 +3,7 @@
#
# Counts words in a sentence and alerts if a sentence exceeds 25 words.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: occurrence
message: 'Shorter sentences improve readability (max 25 words).'
scope: sentence

View File

@ -6,7 +6,7 @@
# - No spaces.
# - More than one space.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: existence
message: '"%s" must contain one and only one space.'
link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#punctuation

View File

@ -9,7 +9,7 @@
# Commands, like `git clone` must use backticks, and must not be added to the
# exceptions.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: spelling
message: 'Spelling check: "%s"?'
level: warning

View File

@ -4,7 +4,7 @@
# Warns against using common shorthand for terms.
# For substitutions flagged as errors, see Substitutions.yml
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: substitution
message: 'If possible, use "%s" instead of "%s".'
link: https://about.gitlab.com/handbook/communication/#top-misused-terms

View File

@ -4,7 +4,7 @@
# Checks for use of some of the top misused terms at GitLab.
# For substitutions only flagged as warnings, see SubstitutionWarning.yml
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: substitution
message: 'Use "%s" instead of "%s".'
link: https://about.gitlab.com/handbook/communication/#top-misused-terms

View File

@ -13,7 +13,7 @@
# immediately on the next line is ok. However, this will often highlight where multi-line version
# text is attempted without `-` characters.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: existence
message: '"%s" is not formatted correctly.'
link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#text-for-documentation-requiring-version-text

View File

@ -3424,7 +3424,7 @@ type Epic implements Noteable {
last: Int
"""
Filter epics by title and description
Search query for epic title or description
"""
search: String
@ -4701,7 +4701,7 @@ type Group {
labelName: [String!]
"""
Filter epics by title and description
Search query for epic title or description
"""
search: String
@ -4778,7 +4778,7 @@ type Group {
last: Int
"""
Filter epics by title and description
Search query for epic title or description
"""
search: String
@ -4899,7 +4899,7 @@ type Group {
milestoneTitle: [String]
"""
Search query for finding issues by title or description
Search query for issue title or description
"""
search: String
@ -8730,7 +8730,7 @@ type Project {
name: String
"""
Search query
Search query for environment name
"""
search: String
@ -8830,7 +8830,7 @@ type Project {
milestoneTitle: [String]
"""
Search query for finding issues by title or description
Search query for issue title or description
"""
search: String
@ -8930,7 +8930,7 @@ type Project {
milestoneTitle: [String]
"""
Search query for finding issues by title or description
Search query for issue title or description
"""
search: String
@ -9338,7 +9338,7 @@ type Project {
iids: [ID!]
"""
Filter requirements by title search
Search query for requirement title
"""
search: String
@ -9398,7 +9398,7 @@ type Project {
last: Int
"""
Filter requirements by title search
Search query for requirement title
"""
search: String
@ -10089,7 +10089,7 @@ type Query {
membership: Boolean
"""
Search criteria
Search query for project name, path, or description
"""
search: String
): ProjectConnection
@ -11440,7 +11440,7 @@ type SentryErrorCollection {
last: Int
"""
Search term for the Sentry error.
Search query for the Sentry error details
"""
searchTerm: String

View File

@ -9497,7 +9497,7 @@
},
{
"name": "search",
"description": "Filter epics by title and description",
"description": "Search query for epic title or description",
"type": {
"kind": "SCALAR",
"name": "String",
@ -13076,7 +13076,7 @@
},
{
"name": "search",
"description": "Filter epics by title and description",
"description": "Search query for epic title or description",
"type": {
"kind": "SCALAR",
"name": "String",
@ -13205,7 +13205,7 @@
},
{
"name": "search",
"description": "Filter epics by title and description",
"description": "Search query for epic title or description",
"type": {
"kind": "SCALAR",
"name": "String",
@ -13544,7 +13544,7 @@
},
{
"name": "search",
"description": "Search query for finding issues by title or description",
"description": "Search query for issue title or description",
"type": {
"kind": "SCALAR",
"name": "String",
@ -25957,7 +25957,7 @@
},
{
"name": "search",
"description": "Search query",
"description": "Search query for environment name",
"type": {
"kind": "SCALAR",
"name": "String",
@ -26294,7 +26294,7 @@
},
{
"name": "search",
"description": "Search query for finding issues by title or description",
"description": "Search query for issue title or description",
"type": {
"kind": "SCALAR",
"name": "String",
@ -26473,7 +26473,7 @@
},
{
"name": "search",
"description": "Search query for finding issues by title or description",
"description": "Search query for issue title or description",
"type": {
"kind": "SCALAR",
"name": "String",
@ -27483,7 +27483,7 @@
},
{
"name": "search",
"description": "Filter requirements by title search",
"description": "Search query for requirement title",
"type": {
"kind": "SCALAR",
"name": "String",
@ -27586,7 +27586,7 @@
},
{
"name": "search",
"description": "Filter requirements by title search",
"description": "Search query for requirement title",
"type": {
"kind": "SCALAR",
"name": "String",
@ -29710,7 +29710,7 @@
},
{
"name": "search",
"description": "Search criteria",
"description": "Search query for project name, path, or description",
"type": {
"kind": "SCALAR",
"name": "String",
@ -33629,7 +33629,7 @@
},
{
"name": "searchTerm",
"description": "Search term for the Sentry error.",
"description": "Search query for the Sentry error details",
"type": {
"kind": "SCALAR",
"name": "String",

View File

@ -173,8 +173,8 @@ If you want to use the environment URL in GitLab, you would have to update it ma
To address this problem, you can configure a deployment job to report back a set of
variables, including the URL that was dynamically-generated by the external service.
GitLab supports [dotenv](https://github.com/bkeepers/dotenv) file as the format,
and expands the `environment:url` value with variables defined in the dotenv file.
GitLab supports the [dotenv (`.env`)](https://github.com/bkeepers/dotenv) file format,
and expands the `environment:url` value with variables defined in the `.env` file.
To use this feature, specify the
[`artifacts:reports:dotenv`](../pipelines/job_artifacts.md#artifactsreportsdotenv) keyword in `.gitlab-ci.yml`.
@ -213,14 +213,13 @@ stop_review:
As soon as the `review` job finishes, GitLab updates the `review/your-branch-name`
environment's URL.
It parses the report artifact `deploy.env`, registers a list of variables as runtime-created,
It parses the `deploy.env` report artifact, registers a list of variables as runtime-created,
uses it for expanding `environment:url: $DYNAMIC_ENVIRONMENT_URL` and sets it to the environment URL.
You can also specify a static part of the URL at `environment:url:`, such as
`https://$DYNAMIC_ENVIRONMENT_URL`. If the value of `DYNAMIC_ENVIRONMENT_URL` is
`123.awesome.com`, the final result will be `https://123.awesome.com`.
`example.com`, the final result will be `https://example.com`.
The assigned URL for the `review/your-branch-name` environment is visible in the UI.
[See where the environment URL is displayed](#using-the-environment-url).
The assigned URL for the `review/your-branch-name` environment is [visible in the UI](#using-the-environment-url).
> **Notes:**
>

View File

@ -114,14 +114,15 @@ The `dotenv` report collects a set of environment variables as artifacts.
The collected variables are registered as runtime-created variables of the job,
which is useful to [set dynamic environment URLs after a job finishes](../environments/index.md#set-dynamic-environment-urls-after-a-job-finishes).
There are a couple of limitations on top of the [original dotenv rules](https://github.com/motdotla/dotenv#rules).
There are a couple of exceptions to the [original dotenv rules](https://github.com/motdotla/dotenv#rules):
- The variable key can contain only letters, digits and underscore ('_').
- The size of the dotenv file must be smaller than 5 kilobytes.
- The number of variables must be less than 10.
- It does not support variable substitution in the dotenv file itself.
- It does not support empty lines and comments (`#`) in dotenv file.
- It does not support quote escape, spaces in a quote, a new line expansion in a quote, in dotenv file.
- The variable key can contain only letters, digits, and underscores (`_`).
- The maximum size of the `.env` file is 5 KB.
- The maximum number of variables is 10.
- Variable substitution in the `.env` file is not supported.
- The `.env` file can't have empty lines or comments (starting with `#`).
- Key values in the `env` file cannot have spaces or newline characters (`\n`), including when using single or double quotes.
- Quote escaping during parsing (`key = 'value'` -> `{key: "value"}`) is not supported.
#### `artifacts:reports:cobertura`

View File

@ -1012,6 +1012,34 @@ to make sure the error information we are passing back is useful.
See also the [frontend GraphQL guide](../development/fe_guide/graphql.md#handling-errors).
### Aliasing and deprecating mutations
The `#mount_aliased_mutation` helper allows us to alias a mutation as
another name within `MutationType`.
For example, to alias a mutation called `FooMutation` as `BarMutation`:
```ruby
mount_aliased_mutation 'BarMutation', Mutations::FooMutation
```
This allows us to rename a mutation and continue to support the old name,
when coupled with the [`deprecated`](#deprecating-fields) argument.
Example:
```ruby
mount_aliased_mutation 'UpdateFoo',
Mutations::Foo::Update,
deprecated: { reason: 'Use fooUpdate', milestone: '13.2' }
```
Deprecated mutations should be added to `Types::DeprecatedMutations` and
tested for within the unit test of `Types::MutationType`. The merge request
[!34798](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34798)
can be referred to as an example of this, including the method of testing
deprecated aliased mutations.
## Validating arguments
For validations of single arguments, use the

View File

@ -210,11 +210,20 @@ actors.
Feature.enabled?(:some_feature, group)
```
NOTE:
NOTE: **Note:**
**Percentage of time** rollout is not a good idea if what you want is to make sure a feature
is always on or off to the users. In that case, **Percentage of actors** rollout is a better method.
Lastly, to verify that the feature is deemed stable in as many cases as possible,
you should fully roll out the feature by enabling the flag **globally** by running:
```shell
/chatops run feature set some_feature true
```
This changes the feature flag state to be **enabled** always, which overrides the
existing gates (e.g. `--group=gitlab-org`) in the above processes.
### Feature flag change logging
Any feature flag change that affects GitLab.com (production) will

View File

@ -71,7 +71,9 @@ absolutely no way to use the feature until it is enabled.
In order to build a final release and present the feature for self-managed
users, the feature flag should be at least defaulted to **on**. If the feature
is deemed stable and there is confidence that removing the feature flag is safe,
consider removing the feature flag altogether.
consider removing the feature flag altogether. It's _strongly_ recommended that
the feature flag is [enabled **globally** on **production**](./controls.md#enabling-a-feature-for-gitlabcom) for **at least one day**
before making this decision. Unexpected bugs are sometimes discovered during this period.
The process for enabling features that are disabled by default can take 5-6 days
from when the merge request is first reviewed to when the change is deployed to

View File

@ -22,6 +22,19 @@ configured to run when changes to Ruby files are detected. By default, it runs i
the [`.pre` stage](../../../ci/yaml/README.md#pre-and-post) of a GitLab CI/CD pipeline,
before all other stages.
## Example use case
Fail fast testing is useful when adding new functionality to a project and adding
new automated tests.
Your project could have hundreds of thousands of tests that take a long time to complete.
You may be confident that a new test will pass, but you have to wait for all the tests
to complete to verify it. This could take an hour or more, even when using parallelization.
Fail fast testing gives you a faster feedback loop from the pipeline. It lets you
know quickly that the new tests are passing and the new functionality did not break
other tests.
## Requirements
This template requires:

View File

@ -1,5 +1,5 @@
import { shallowMount } from '@vue/test-utils';
import { GlLink } from '@gitlab/ui';
import { GlLabel } from '@gitlab/ui';
import { TEST_HOST } from 'helpers/test_constants';
import { trimText } from 'helpers/text_helper';
import initUserPopovers from '~/user_popovers';
@ -8,6 +8,7 @@ import { mergeUrlParams } from '~/lib/utils/url_utility';
import Issuable from '~/issuables_list/components/issuable.vue';
import IssueAssignees from '~/vue_shared/components/issue/issue_assignees.vue';
import { simpleIssue, testAssignees, testLabels } from '../issuable_list_test_data';
import { isScopedLabel } from '~/lib/utils/common_utils';
jest.mock('~/user_popovers');
@ -37,13 +38,18 @@ describe('Issuable component', () => {
let DateOrig;
let wrapper;
const factory = (props = {}) => {
const factory = (props = {}, scopedLabels = false) => {
wrapper = shallowMount(Issuable, {
propsData: {
issuable: simpleIssue,
baseUrl: TEST_BASE_URL,
...props,
},
provide: {
glFeatures: {
scopedLabels,
},
},
});
};
@ -53,6 +59,7 @@ describe('Issuable component', () => {
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
beforeAll(() => {
@ -70,8 +77,7 @@ describe('Issuable component', () => {
const findMilestone = () => wrapper.find('.js-milestone');
const findMilestoneTooltip = () => findMilestone().attributes('title');
const findDueDate = () => wrapper.find('.js-due-date');
const findLabelContainer = () => wrapper.find('.js-labels');
const findLabelLinks = () => findLabelContainer().findAll(GlLink);
const findLabels = () => wrapper.findAll(GlLabel);
const findWeight = () => wrapper.find('.js-weight');
const findAssignees = () => wrapper.find(IssueAssignees);
const findMergeRequestsCount = () => wrapper.find('.js-merge-requests');
@ -79,6 +85,8 @@ describe('Issuable component', () => {
const findDownvotes = () => wrapper.find('.js-downvotes');
const findNotes = () => wrapper.find('.js-notes');
const findBulkCheckbox = () => wrapper.find('input.selected-issuable');
const findScopedLabels = () => findLabels().filter(w => isScopedLabel({ title: w.text() }));
const findUnscopedLabels = () => findLabels().filter(w => !isScopedLabel({ title: w.text() }));
describe('when mounted', () => {
it('initializes user popovers', () => {
@ -90,6 +98,54 @@ describe('Issuable component', () => {
});
});
describe('when scopedLabels feature is available', () => {
beforeEach(() => {
issuable.labels = [...testLabels];
factory({ issuable }, true);
});
describe('when label is scoped', () => {
it('returns label with correct props', () => {
const scopedLabel = findScopedLabels().at(0);
expect(scopedLabel.props('scoped')).toBe(true);
});
});
describe('when label is not scoped', () => {
it('returns label with correct props', () => {
const notScopedLabel = findUnscopedLabels().at(0);
expect(notScopedLabel.props('scoped')).toBe(false);
});
});
});
describe('when scopedLabels feature is not available', () => {
beforeEach(() => {
issuable.labels = [...testLabels];
factory({ issuable });
});
describe('when label is scoped', () => {
it('label scoped props is false', () => {
const scopedLabel = findScopedLabels().at(0);
expect(scopedLabel.props('scoped')).toBe(false);
});
});
describe('when label is not scoped', () => {
it('label scoped props is false', () => {
const notScopedLabel = findUnscopedLabels().at(0);
expect(notScopedLabel.props('scoped')).toBe(false);
});
});
});
describe('with simple issuable', () => {
beforeEach(() => {
Object.assign(issuable, {
@ -113,7 +169,7 @@ describe('Issuable component', () => {
${'task status'} | ${findTaskStatus}
${'milestone'} | ${findMilestone}
${'due date'} | ${findDueDate}
${'labels'} | ${findLabelContainer}
${'labels'} | ${findLabels}
${'weight'} | ${findWeight}
${'merge request count'} | ${findMergeRequestsCount}
${'upvotes'} | ${findUpvotes}
@ -239,10 +295,10 @@ describe('Issuable component', () => {
it('renders labels', () => {
factory({ issuable });
const labels = findLabelLinks().wrappers.map(label => ({
href: label.attributes('href'),
const labels = findLabels().wrappers.map(label => ({
href: label.props('target'),
text: label.text(),
tooltip: label.find('span').attributes('title'),
tooltip: label.attributes('description'),
}));
const expected = testLabels.map(label => ({

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe ProtectableDropdown do
RSpec.describe ProtectableDropdown do
let(:project) { create(:project, :repository) }
let(:subject) { described_class.new(project, :branches) }

View File

@ -2,6 +2,6 @@
require 'spec_helper'
describe ProtectedBranch::MergeAccessLevel do
RSpec.describe ProtectedBranch::MergeAccessLevel do
it { is_expected.to validate_inclusion_of(:access_level).in_array([Gitlab::Access::MAINTAINER, Gitlab::Access::DEVELOPER, Gitlab::Access::NO_ACCESS]) }
end

View File

@ -2,6 +2,6 @@
require 'spec_helper'
describe ProtectedBranch::PushAccessLevel do
RSpec.describe ProtectedBranch::PushAccessLevel do
it { is_expected.to validate_inclusion_of(:access_level).in_array([Gitlab::Access::MAINTAINER, Gitlab::Access::DEVELOPER, Gitlab::Access::NO_ACCESS]) }
end

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe ProtectedBranch do
RSpec.describe ProtectedBranch do
subject { build_stubbed(:protected_branch) }
describe 'Associations' do

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe ProtectedTag do
RSpec.describe ProtectedTag do
describe 'Associations' do
it { is_expected.to belong_to(:project) }
end

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe PushEventPayload do
RSpec.describe PushEventPayload do
it_behaves_like 'having unique enum values'
describe 'saving payloads' do

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe PushEvent do
RSpec.describe PushEvent do
let(:payload) { PushEventPayload.new }
let(:event) do

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe ReadmeBlob do
RSpec.describe ReadmeBlob do
include FakeBlobHelpers
describe 'policy' do

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe RedirectRoute do
RSpec.describe RedirectRoute do
let(:group) { create(:group) }
let!(:redirect_route) { group.redirect_routes.create(path: 'gitlabb') }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe Releases::Evidence do
RSpec.describe Releases::Evidence do
let_it_be(:project) { create(:project) }
let(:release) { create(:release, project: project) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe Releases::Link do
RSpec.describe Releases::Link do
let(:release) { create(:release, project: project) }
let(:project) { create(:project) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe Releases::Source do
RSpec.describe Releases::Source do
let_it_be(:project) { create(:project, :repository, name: 'finance-cal') }
let(:tag_name) { 'v1.0' }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe RemoteMirror, :mailer do
RSpec.describe RemoteMirror, :mailer do
include GitHelpers
describe 'URL validation' do

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe RepositoryLanguage do
RSpec.describe RepositoryLanguage do
let(:repository_language) { build(:repository_language) }
describe 'associations' do

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe Repository do
RSpec.describe Repository do
include RepoHelpers
include GitHelpers

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe ResourceMilestoneEvent, type: :model do
RSpec.describe ResourceMilestoneEvent, type: :model do
it_behaves_like 'a resource event'
it_behaves_like 'a resource event for issues'
it_behaves_like 'a resource event for merge requests'

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe ResourceStateEvent, type: :model do
RSpec.describe ResourceStateEvent, type: :model do
subject { build(:resource_state_event, issue: issue) }
let(:issue) { create(:issue) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe Review do
RSpec.describe Review do
describe 'associations' do
it { is_expected.to belong_to(:author).class_name('User').with_foreign_key(:author_id).inverse_of(:reviews) }
it { is_expected.to belong_to(:merge_request).inverse_of(:reviews).touch(false) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe Route do
RSpec.describe Route do
let(:group) { create(:group, path: 'git_lab', name: 'git_lab') }
let(:route) { group.route }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe SentNotification do
RSpec.describe SentNotification do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe SentryIssue do
RSpec.describe SentryIssue do
describe 'associations' do
it { is_expected.to belong_to(:issue) }
end

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe ::Serverless::DomainCluster do
RSpec.describe ::Serverless::DomainCluster do
subject { create(:serverless_domain_cluster) }
describe 'validations' do

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe ::Serverless::Domain do
RSpec.describe ::Serverless::Domain do
let(:function_name) { 'test-function' }
let(:pages_domain_name) { 'serverless.gitlab.io' }
let(:pages_domain) { create(:pages_domain, :instance_serverless, domain: pages_domain_name) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe ::Serverless::Function do
RSpec.describe ::Serverless::Function do
let(:project) { create(:project) }
let(:func) { described_class.new(project, 'test', 'test-ns') }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe Shard do
RSpec.describe Shard do
describe '.populate!' do
it 'creates shards based on the config file' do
expect(described_class.all).to be_empty

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe SnippetBlob do
RSpec.describe SnippetBlob do
let(:snippet) { create(:snippet) }
subject { described_class.new(snippet) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe SnippetInputActionCollection do
RSpec.describe SnippetInputActionCollection do
let(:action_name) { 'create' }
let(:action) { { action: action_name, file_path: 'foo', content: 'bar', previous_path: 'foobar' } }
let(:data) { [action, action] }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe SnippetInputAction do
RSpec.describe SnippetInputAction do
describe 'validations' do
using RSpec::Parameterized::TableSyntax

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe SnippetRepository do
RSpec.describe SnippetRepository do
let_it_be(:user) { create(:user) }
let(:snippet) { create(:personal_snippet, :repository, author: user) }
let(:snippet_repository) { snippet.snippet_repository }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe Snippet do
RSpec.describe Snippet do
describe 'modules' do
subject { described_class }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe SpamLog do
RSpec.describe SpamLog do
let_it_be(:admin) { create(:admin) }
describe 'associations' do

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe SshHostKey do
RSpec.describe SshHostKey do
using RSpec::Parameterized::TableSyntax
include ReactiveCachingHelpers

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe StateNote do
RSpec.describe StateNote do
describe '.from_event' do
let_it_be(:author) { create(:user) }
let_it_be(:project) { create(:project, :repository) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe Subscription do
RSpec.describe Subscription do
describe 'relationships' do
it { is_expected.to belong_to(:project) }
it { is_expected.to belong_to(:subscribable) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe Suggestion do
RSpec.describe Suggestion do
let(:suggestion) { create(:suggestion) }
describe 'associations' do

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe SystemNoteMetadata do
RSpec.describe SystemNoteMetadata do
describe 'associations' do
it { is_expected.to belong_to(:note) }
it { is_expected.to belong_to(:description_version) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe TermAgreement do
RSpec.describe TermAgreement do
describe 'validations' do
it { is_expected.to validate_presence_of(:term) }
it { is_expected.to validate_presence_of(:user) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe Terraform::State do
RSpec.describe Terraform::State do
subject { create(:terraform_state, :with_file) }
let(:terraform_state_file) { fixture_file('terraform/terraform.tfstate') }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe Todo do
RSpec.describe Todo do
let(:issue) { create(:issue) }
describe 'relationships' do

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe Tree do
RSpec.describe Tree do
let(:repository) { create(:project, :repository).repository }
let(:sha) { repository.root_ref }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe TrendingProject do
RSpec.describe TrendingProject do
let(:user) { create(:user) }
let(:public_project1) { create(:project, :public, :repository) }
let(:public_project2) { create(:project, :public, :repository) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe Upload do
RSpec.describe Upload do
describe 'associations' do
it { is_expected.to belong_to(:model) }
end

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe Uploads::Fog do
RSpec.describe Uploads::Fog do
let(:data_store) { described_class.new }
before do

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe Uploads::Local do
RSpec.describe Uploads::Local do
let(:data_store) { described_class.new }
before do

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe UserAgentDetail do
RSpec.describe UserAgentDetail do
describe '.submittable?' do
it 'is submittable when not already submitted' do
detail = build(:user_agent_detail)

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe UserCallout do
RSpec.describe UserCallout do
let!(:callout) { create(:user_callout) }
it_behaves_like 'having unique enum values'

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe UserCanonicalEmail do
RSpec.describe UserCanonicalEmail do
it { is_expected.to belong_to(:user) }
describe 'validations' do

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe UserCustomAttribute do
RSpec.describe UserCustomAttribute do
describe 'assocations' do
it { is_expected.to belong_to(:user) }
end

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe UserDetail do
RSpec.describe UserDetail do
it { is_expected.to belong_to(:user) }
describe 'validations' do

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe UserHighestRole do
RSpec.describe UserHighestRole do
describe 'associations' do
it { is_expected.to belong_to(:user).required }
end

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe UserInteractedProject do
RSpec.describe UserInteractedProject do
describe '.track' do
subject { described_class.track(event) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe CommitUserMention do
RSpec.describe CommitUserMention do
describe 'associations' do
it { is_expected.to belong_to(:note) }
end

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe IssueUserMention do
RSpec.describe IssueUserMention do
describe 'associations' do
it { is_expected.to belong_to(:issue) }
it { is_expected.to belong_to(:note) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe MergeRequestUserMention do
RSpec.describe MergeRequestUserMention do
describe 'associations' do
it { is_expected.to belong_to(:merge_request) }
it { is_expected.to belong_to(:note) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe SnippetUserMention do
RSpec.describe SnippetUserMention do
describe 'associations' do
it { is_expected.to belong_to(:snippet) }
it { is_expected.to belong_to(:note) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe UserPreference do
RSpec.describe UserPreference do
let(:user_preference) { create(:user_preference) }
describe 'notes filters global keys' do

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe User do
RSpec.describe User do
include ProjectForksHelper
include TermsHelper
include ExclusiveLeaseHelpers

View File

@ -2,7 +2,7 @@
require 'spec_helper'
describe UserStatus do
RSpec.describe UserStatus do
it { is_expected.to validate_presence_of(:user) }
it { is_expected.to allow_value('smirk').for(:emoji) }

Some files were not shown because too many files have changed in this diff Show More