Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
5d41ea8c8e
commit
6b1cf9e9ce
|
@ -73,7 +73,6 @@ review-build-cng:
|
|||
extends:
|
||||
- .default-retry
|
||||
image: ${REVIEW_APPS_IMAGE}
|
||||
resource_group: "review/${CI_COMMIT_REF_NAME}"
|
||||
variables:
|
||||
HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}"
|
||||
DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}"
|
||||
|
@ -139,6 +138,7 @@ review-stop:
|
|||
extends:
|
||||
- .review-stop-base
|
||||
- .review:rules:review-stop
|
||||
resource_group: review/${CI_COMMIT_REF_SLUG}${SCHEDULE_TYPE} # CI_ENVIRONMENT_SLUG is not available here and we want this to be the same as the environment
|
||||
stage: deploy
|
||||
needs: []
|
||||
script:
|
||||
|
|
|
@ -6,6 +6,7 @@ review-cleanup:
|
|||
- .default-retry
|
||||
- .review:rules:review-cleanup
|
||||
image: ${REVIEW_APPS_IMAGE}
|
||||
resource_group: review/${CI_COMMIT_REF_SLUG}${SCHEDULE_TYPE} # CI_ENVIRONMENT_SLUG is not available here and we want this to be the same as the environment
|
||||
stage: prepare
|
||||
environment:
|
||||
name: review/${CI_COMMIT_REF_SLUG}${SCHEDULE_TYPE} # No separator for SCHEDULE_TYPE so it's compatible as before and looks nice without it
|
||||
|
@ -25,6 +26,7 @@ review-cleanup:
|
|||
start-review-app-pipeline:
|
||||
extends:
|
||||
- .review:rules:start-review-app-pipeline
|
||||
resource_group: review/${CI_COMMIT_REF_SLUG}${SCHEDULE_TYPE} # CI_ENVIRONMENT_SLUG is not available here and we want this to be the same as the environment
|
||||
stage: review
|
||||
needs:
|
||||
- job: build-assets-image
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 824 B |
|
@ -14,7 +14,10 @@ module GitlabStyleDeprecations
|
|||
'See https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#deprecating-schema-items'
|
||||
end
|
||||
|
||||
deprecation = ::Gitlab::Graphql::Deprecation.parse(kwargs.delete(:deprecated))
|
||||
# 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)
|
||||
return unless deprecation
|
||||
|
||||
raise ArgumentError, "Bad deprecation. #{deprecation.errors.full_messages.to_sentence}" unless deprecation.valid?
|
||||
|
|
|
@ -11,6 +11,6 @@ module Types
|
|||
|
||||
value 'TASK', value: 'task',
|
||||
description: 'Task issue type. Available only when feature flag `work_items` is enabled.',
|
||||
deprecated: { milestone: '15.2', reason: :alpha }
|
||||
alpha: { milestone: '15.2' }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -139,13 +139,13 @@ module Types
|
|||
mount_mutation Mutations::Packages::DestroyFiles
|
||||
mount_mutation Mutations::Packages::Cleanup::Policy::Update
|
||||
mount_mutation Mutations::Echo
|
||||
mount_mutation Mutations::WorkItems::Create, deprecated: { milestone: '15.1', reason: :alpha }
|
||||
mount_mutation Mutations::WorkItems::CreateFromTask, deprecated: { milestone: '15.1', reason: :alpha }
|
||||
mount_mutation Mutations::WorkItems::Delete, deprecated: { milestone: '15.1', reason: :alpha }
|
||||
mount_mutation Mutations::WorkItems::DeleteTask, deprecated: { milestone: '15.1', reason: :alpha }
|
||||
mount_mutation Mutations::WorkItems::Update, deprecated: { milestone: '15.1', reason: :alpha }
|
||||
mount_mutation Mutations::WorkItems::UpdateWidgets, deprecated: { milestone: '15.1', reason: :alpha }
|
||||
mount_mutation Mutations::WorkItems::UpdateTask, deprecated: { milestone: '15.1', reason: :alpha }
|
||||
mount_mutation Mutations::WorkItems::Create, alpha: { milestone: '15.1' }
|
||||
mount_mutation Mutations::WorkItems::CreateFromTask, alpha: { milestone: '15.1' }
|
||||
mount_mutation Mutations::WorkItems::Delete, alpha: { milestone: '15.1' }
|
||||
mount_mutation Mutations::WorkItems::DeleteTask, alpha: { milestone: '15.1' }
|
||||
mount_mutation Mutations::WorkItems::Update, alpha: { milestone: '15.1' }
|
||||
mount_mutation Mutations::WorkItems::UpdateWidgets, alpha: { milestone: '15.1' }
|
||||
mount_mutation Mutations::WorkItems::UpdateTask, alpha: { milestone: '15.1' }
|
||||
mount_mutation Mutations::SavedReplies::Create
|
||||
mount_mutation Mutations::SavedReplies::Update
|
||||
mount_mutation Mutations::Pages::MarkOnboardingComplete
|
||||
|
|
|
@ -147,7 +147,7 @@ module Types
|
|||
field :work_items,
|
||||
Types::WorkItemType.connection_type,
|
||||
null: true,
|
||||
deprecated: { milestone: '15.1', reason: :alpha },
|
||||
alpha: { milestone: '15.1' },
|
||||
description: 'Work items of the project.',
|
||||
extras: [:lookahead],
|
||||
resolver: Resolvers::WorkItemsResolver
|
||||
|
|
|
@ -91,7 +91,7 @@ module Types
|
|||
field :work_item, Types::WorkItemType,
|
||||
null: true,
|
||||
resolver: Resolvers::WorkItemResolver,
|
||||
deprecated: { milestone: '15.1', reason: :alpha },
|
||||
alpha: { milestone: '15.1' },
|
||||
description: 'Find a work item. Returns `null` if `work_items` feature flag is disabled.'
|
||||
|
||||
field :merge_request, Types::MergeRequestType,
|
||||
|
|
|
@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/331907
|
|||
milestone: '14.0'
|
||||
type: development
|
||||
group: group::workspace
|
||||
default_enabled: false
|
||||
default_enabled: true
|
||||
|
|
|
@ -121,7 +121,7 @@ the k6 test.
|
|||
NOTE:
|
||||
For Kubernetes setups a different template should be used: [`Jobs/Load-Performance-Testing.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/Load-Performance-Testing.gitlab-ci.yml).
|
||||
|
||||
k6 has [various options](https://k6.io/docs/using-k6/options) to configure how it will run tests, such as what throughput (RPS) to run with,
|
||||
k6 has [various options](https://k6.io/docs/using-k6/k6-options/reference/) to configure how it will run tests, such as what throughput (RPS) to run with,
|
||||
how long the test should run, and so on. Almost all options can be configured in the test itself, but as
|
||||
you can also pass command line options via the `K6_OPTIONS` variable.
|
||||
|
||||
|
|
|
@ -250,7 +250,7 @@ test:
|
|||
|
||||
This example uses [PHPUnit](https://phpunit.de/) with the `--log-junit` flag.
|
||||
You can also add this option using
|
||||
[XML](https://phpunit.readthedocs.io/en/stable/configuration.html#the-junit-element)
|
||||
[XML](https://phpunit.readthedocs.io/en/9.5/configuration.html#the-junit-element)
|
||||
in the `phpunit.xml` configuration file.
|
||||
|
||||
```yaml
|
||||
|
|
|
@ -60,7 +60,7 @@ NOTE:
|
|||
|
||||
Code shipped with GitLab needs to use a license approved by the Legal team. See the list of [existing approved licenses](https://about.gitlab.com/handbook/engineering/open-source/#using-open-source-libraries).
|
||||
|
||||
Notify the [Distribution team](https://about.gitlab.com/handbook/engineering/development/enablement/distribution/) when adding a new dependency that must be compiled. We must be able to compile the dependency on all supported platforms.
|
||||
Notify the [Distribution team](https://about.gitlab.com/handbook/engineering/development/enablement/systems/distribution/) when adding a new dependency that must be compiled. We must be able to compile the dependency on all supported platforms.
|
||||
|
||||
New services to be bundled with GitLab need to be available in the following environments.
|
||||
|
||||
|
@ -83,7 +83,7 @@ In order for a service to be bundled for end-users or GitLab.com, it needs to be
|
|||
Dependencies should be kept up to date and be tracked for security updates. For the Rails codebase, the JavaScript and Ruby dependencies are
|
||||
scanned for vulnerabilities using GitLab [dependency scanning](../user/application_security/dependency_scanning/index.md).
|
||||
|
||||
In addition, any system dependencies used in Omnibus packages or the Cloud Native images should be added to the [dependency update automation](https://about.gitlab.com/handbook/engineering/development/enablement/distribution/maintenance/dependencies.io.html#adding-new-dependencies).
|
||||
In addition, any system dependencies used in Omnibus packages or the Cloud Native images should be added to the [dependency update automation](https://about.gitlab.com/handbook/engineering/development/enablement/systems/distribution/maintenance/dependencies.io.html#adding-new-dependencies).
|
||||
|
||||
## Release management
|
||||
|
||||
|
|
|
@ -558,7 +558,7 @@ Example:
|
|||
```ruby
|
||||
field :foo, GraphQL::Types::String,
|
||||
null: true,
|
||||
deprecated: { reason: :alpha, milestone: '10.0' },
|
||||
alpha: { milestone: '10.0' },
|
||||
description: 'Some test field. Returns `null`' \
|
||||
'if `my_feature_flag` feature flag is disabled.'
|
||||
|
||||
|
@ -586,6 +586,7 @@ To deprecate a schema item in GraphQL:
|
|||
See also:
|
||||
|
||||
- [Aliasing and deprecating mutations](#aliasing-and-deprecating-mutations).
|
||||
- [Marking schema items as Alpha](#marking-schema-items-as-alpha).
|
||||
- [How to filter Kibana for queries that used deprecated fields](graphql_guide/monitoring.md#queries-that-used-a-deprecated-field).
|
||||
|
||||
### Create a deprecation issue
|
||||
|
@ -756,14 +757,14 @@ at any time without notice.
|
|||
This leverages GraphQL deprecations to cause the schema item to appear as deprecated,
|
||||
and will be described as being in "alpha" in our generated docs and its GraphQL description.
|
||||
|
||||
To mark a schema item as being in "alpha", use the `deprecated:` keyword with `reason: :alpha`.
|
||||
To mark a schema item as being in "alpha", use the `alpha:` keyword.
|
||||
You must provide the `milestone:` that introduced the alpha item.
|
||||
|
||||
For example:
|
||||
|
||||
```ruby
|
||||
field :token, GraphQL::Types::String, null: true,
|
||||
deprecated: { reason: :alpha, milestone: '10.0' },
|
||||
alpha: { milestone: '10.0' },
|
||||
description: 'Token for login.'
|
||||
```
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ new features and services must be written to consider Kubernetes compatibility *
|
|||
|
||||
The simplest way to ensure this, is to add support for your feature or service to
|
||||
[the official GitLab Helm chart](https://docs.gitlab.com/charts/) or reach out to
|
||||
[the Distribution team](https://about.gitlab.com/handbook/engineering/development/enablement/distribution/#how-to-work-with-distribution).
|
||||
[the Distribution team](https://about.gitlab.com/handbook/engineering/development/enablement/systems/distribution/#how-to-work-with-distribution).
|
||||
|
||||
Refer to the [process for adding new service components](adding_service_component.md) for more details.
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ of the [Create stage](https://about.gitlab.com/handbook/product/categories/#crea
|
|||
of the [DevOps lifecycle](https://about.gitlab.com/handbook/product/categories/#devops-stages).
|
||||
|
||||
We interface with the Gitaly and Code Review teams, and work closely with the
|
||||
[Create:Source Code Frontend team](https://about.gitlab.com/handbook/engineering/development/dev/create-source-code-fe). The features
|
||||
[Create:Source Code Frontend team](https://about.gitlab.com/handbook/engineering/development/dev/create/create-source-code-fe/). The features
|
||||
we work with are listed on the
|
||||
[Features by Group Page](https://about.gitlab.com/handbook/product/categories/features/#createsource-code-group).
|
||||
|
||||
|
|
|
@ -301,10 +301,10 @@ it's time to look at a custom solution:
|
|||
|
||||
In short: the oldest stuff is replaced with new stuff:
|
||||
|
||||
- A [useful article](https://redis.io/topics/lru-cache) about configuring Redis as an LRU cache.
|
||||
- A [useful article](https://redis.io/docs/manual/eviction/) about configuring Redis as an LRU cache.
|
||||
- Lots of options for different cache eviction strategies.
|
||||
- You probably want `allkeys-lru`, which is functionally similar to Memcached.
|
||||
- In Redis 4.0 and later, [allkeys-lfu is available](https://redis.io/topics/lru-cache#the-new-lfu-mode),
|
||||
- In Redis 4.0 and later, [allkeys-lfu is available](https://redis.io/docs/manual/eviction/#the-new-lfu-mode),
|
||||
which is similar but different.
|
||||
- We handle all explicit deletes using UNLINK instead of DEL now, which allows Redis to
|
||||
reclaim memory in its own time, rather than immediately.
|
||||
|
|
|
@ -135,7 +135,7 @@ with [domain expertise](#domain-experts).
|
|||
More information about license compatibility can be found in our
|
||||
[GitLab Licensing and Compatibility documentation](licensing.md).
|
||||
1. If your merge request includes a new dependency or a file system change, it must be
|
||||
**approved by a [Distribution team member](https://about.gitlab.com/company/team/)**. See how to work with the [Distribution team](https://about.gitlab.com/handbook/engineering/development/enablement/distribution/#how-to-work-with-distribution) for more details.
|
||||
**approved by a [Distribution team member](https://about.gitlab.com/company/team/)**. See how to work with the [Distribution team](https://about.gitlab.com/handbook/engineering/development/enablement/systems/distribution/#how-to-work-with-distribution) for more details.
|
||||
1. If your merge request includes documentation changes, it must be **approved
|
||||
by a [Technical writer](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments)**,
|
||||
based on assignments in the appropriate [DevOps stage group](https://about.gitlab.com/handbook/product/categories/#devops-stages).
|
||||
|
|
|
@ -68,9 +68,9 @@ Check states using your browser's _styles inspector_ to toggle CSS pseudo-classe
|
|||
like `:hover` and others ([Chrome](https://developer.chrome.com/docs/devtools/css/reference/#pseudo-class),
|
||||
[Firefox](https://firefox-source-docs.mozilla.org/devtools-user/page_inspector/how_to/examine_and_edit_css/index.html#viewing-common-pseudo-classes)).
|
||||
|
||||
- Account for all applicable states ([error](https://design.gitlab.com/content/error-messages),
|
||||
- Account for all applicable states ([error](https://design.gitlab.com/content/error-messages/),
|
||||
rest, loading, focus, hover, selected, disabled).
|
||||
- Account for states dependent on data size ([empty](https://design.gitlab.com/regions/empty-states),
|
||||
- Account for states dependent on data size ([empty](https://design.gitlab.com/regions/empty-states/),
|
||||
some data, and lots of data).
|
||||
- Account for states dependent on user role, user preferences, and subscription.
|
||||
- Consider animations and transitions, and follow their [guidelines](https://design.gitlab.com/product-foundations/motion/).
|
||||
|
@ -113,7 +113,7 @@ When the design is ready, _before_ starting its implementation:
|
|||
|
||||
At any moment, but usually _during_ or _after_ the design's implementation:
|
||||
|
||||
- Contribute [issues to Pajamas](https://design.gitlab.com/get-started/contribute#contribute-an-issue)
|
||||
- Contribute [issues to Pajamas](https://design.gitlab.com/get-started/contribute/#contribute-an-issue)
|
||||
for additions or enhancements to the design system.
|
||||
- Create issues with the [`~UX debt`](issue_workflow.md#technical-and-ux-debt)
|
||||
label for intentional deviations from the agreed-upon UX requirements due to
|
||||
|
|
|
@ -161,7 +161,7 @@ For instance, the "DevOps Reports" category is represented by the
|
|||
`devops_reports.name` value is "DevOps Reports".
|
||||
|
||||
If a category's label doesn't respect this naming convention, it should be specified
|
||||
with [the `label` attribute](https://about.gitlab.com/handbook/marketing/inbound-marketing/digital-experience/website/#category-attributes)
|
||||
with [the `label` attribute](https://about.gitlab.com/handbook/marketing/digital-experience/website/#category-attributes)
|
||||
in <https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/categories.yml>.
|
||||
|
||||
### Feature labels
|
||||
|
|
|
@ -36,7 +36,7 @@ projects:
|
|||
|
||||
Create the merge request [using the "Database reviewer" template](https://gitlab.com/gitlab-com/www-gitlab-com/-/blob/master/.gitlab/merge_request_templates/Database%20reviewer.md),
|
||||
adding your expertise your profile YAML file. Assign to a database maintainer or the
|
||||
[Database Team's Engineering Manager](https://about.gitlab.com/handbook/engineering/development/enablement/database/).
|
||||
[Database Team's Engineering Manager](https://about.gitlab.com/handbook/engineering/development/enablement/data_stores/database/).
|
||||
|
||||
After the `team.yml` update is merged, the [Reviewer roulette](../code_review.md#reviewer-roulette)
|
||||
may recommend you as a database reviewer.
|
||||
|
|
|
@ -12,7 +12,7 @@ For further reference, check PostgreSQL documentation about [transactions](https
|
|||
|
||||
## Database decomposition and sharding
|
||||
|
||||
The [sharding group](https://about.gitlab.com/handbook/engineering/development/enablement/sharding/) plans
|
||||
The [Pods Group](https://about.gitlab.com/handbook/engineering/development/enablement/data_stores/pods/) plans
|
||||
to split the main GitLab database and move some of the database tables to other database servers.
|
||||
|
||||
We start decomposing the `ci_*`-related database tables first. To maintain the current application
|
||||
|
|
|
@ -1127,7 +1127,7 @@ in present tense, active voice.
|
|||
## you, your, yours
|
||||
|
||||
Use **you**, **your**, and **yours** instead of [**the user** and **the user's**](#user-users).
|
||||
Documentation should be from the [point of view](https://design.gitlab.com/content/voice-tone#point-of-view) of the reader.
|
||||
Documentation should be from the [point of view](https://design.gitlab.com/content/voice-tone/#point-of-view) of the reader.
|
||||
|
||||
Use:
|
||||
|
||||
|
|
|
@ -219,12 +219,12 @@ You can use markdownlint:
|
|||
|
||||
### Vale
|
||||
|
||||
[Vale](https://docs.errata.ai/vale/about/) is a grammar, style, and word usage linter for the
|
||||
[Vale](https://vale.sh/) is a grammar, style, and word usage linter for the
|
||||
English language. Vale's configuration is stored in the
|
||||
[`.vale.ini`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.vale.ini) file located in the root
|
||||
directory of projects.
|
||||
|
||||
Vale supports creating [custom tests](https://docs.errata.ai/vale/styles) that extend any of
|
||||
Vale supports creating [custom tests](https://vale.sh/docs/topics/styles/) that extend any of
|
||||
several types of checks, which we store in the `.linting/vale/styles/gitlab` directory in the
|
||||
documentation directory of projects.
|
||||
|
||||
|
@ -241,7 +241,7 @@ This configuration is also used in build pipelines, where
|
|||
|
||||
You can use Vale:
|
||||
|
||||
- [On the command line](https://docs.errata.ai/vale/cli).
|
||||
- [On the command line](https://vale.sh/docs/vale-cli/structure/).
|
||||
- [In a code editor](#configure-editors).
|
||||
- [In a Git hook](#configure-pre-push-hooks). Vale only reports errors in the Git hook (the same
|
||||
configuration as the CI/CD pipelines), and does not report suggestions or warnings.
|
||||
|
@ -305,7 +305,7 @@ For example, a page that scores `12` before a set of changes, and `9` after, ind
|
|||
general complexity level of the page.
|
||||
|
||||
The readability score is calculated based on the number of words per sentence, and the number
|
||||
of syllables per word. For more information, see [the Vale documentation](https://docs.errata.ai/vale/styles#metric).
|
||||
of syllables per word. For more information, see [the Vale documentation](https://vale.sh/docs/topics/styles/#metric).
|
||||
|
||||
### Install linters
|
||||
|
||||
|
@ -400,8 +400,6 @@ To configure Vale in your editor, install one of the following as appropriate:
|
|||
In this setup the `markdownlint` checker is set as a "next" checker from the defined `vale` checker.
|
||||
Enabling this custom Vale checker provides error linting from both Vale and markdownlint.
|
||||
|
||||
We don't use [Vale Server](https://docs.errata.ai/vale-server/install).
|
||||
|
||||
### Configure pre-push hooks
|
||||
|
||||
Git [pre-push hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) allow Git users to:
|
||||
|
@ -480,7 +478,7 @@ document:
|
|||
Whenever possible, exclude only the problematic rule and lines.
|
||||
|
||||
For more information, see
|
||||
[Vale's documentation](https://docs.errata.ai/vale/scoping#markup-based-configuration).
|
||||
[Vale's documentation](https://vale.sh/docs/topics/scoping/).
|
||||
|
||||
### Disable markdownlint tests
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ GitLab supports the current major version and two previous major versions.
|
|||
For example, if 15.0 is the current major version, all major and minor releases of
|
||||
GitLab 15.0, 14.0, and 13.0 are supported.
|
||||
|
||||
[View the list of supported versions](https://about.gitlab.com/support/statement-of-support.html#version-support).
|
||||
[View the list of supported versions](https://about.gitlab.com/support/statement-of-support/#version-support).
|
||||
|
||||
If you see version history items or inline text that refers to unsupported versions, you can remove it.
|
||||
|
||||
|
|
|
@ -1041,7 +1041,7 @@ information on managing page-specific JavaScript within EE.
|
|||
|
||||
#### Child Component only used in EE
|
||||
|
||||
To separate Vue template differences we should [import the components asynchronously](https://vuejs.org/v2/guide/components-dynamic-async.html#Async-Components).
|
||||
To separate Vue template differences we should [import the components asynchronously](https://v2.vuejs.org/v2/guide/components-dynamic-async.html#Async-Components).
|
||||
|
||||
Doing this allows for us to load the correct component in EE while in CE
|
||||
we can load a empty component that renders nothing. This code **should**
|
||||
|
|
|
@ -38,7 +38,7 @@ Additionally, if you need large repositories or multiple forks for testing, plea
|
|||
|
||||
The Elasticsearch integration depends on an external indexer. We ship an [indexer written in Go](https://gitlab.com/gitlab-org/gitlab-elasticsearch-indexer). The user must trigger the initial indexing via a Rake task but, after this is done, GitLab itself will trigger reindexing when required via `after_` callbacks on create, update, and destroy that are inherited from [`/ee/app/models/concerns/elastic/application_versioned_search.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/app/models/concerns/elastic/application_versioned_search.rb).
|
||||
|
||||
After initial indexing is complete, create, update, and delete operations for all models except projects (see [#207494](https://gitlab.com/gitlab-org/gitlab/-/issues/207494)) are tracked in a Redis [`ZSET`](https://redis.io/topics/data-types#sorted-sets). A regular `sidekiq-cron` `ElasticIndexBulkCronWorker` processes this queue, updating many Elasticsearch documents at a time with the [Bulk Request API](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html).
|
||||
After initial indexing is complete, create, update, and delete operations for all models except projects (see [#207494](https://gitlab.com/gitlab-org/gitlab/-/issues/207494)) are tracked in a Redis [`ZSET`](https://redis.io/docs/manual/data-types/#sorted-sets). A regular `sidekiq-cron` `ElasticIndexBulkCronWorker` processes this queue, updating many Elasticsearch documents at a time with the [Bulk Request API](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html).
|
||||
|
||||
Search queries are generated by the concerns found in [`ee/app/models/concerns/elastic`](https://gitlab.com/gitlab-org/gitlab/-/tree/master/ee/app/models/concerns/elastic). These concerns are also in charge of access control, and have been a historic source of security bugs so please pay close attention to them!
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ This page contains guidelines we should follow.
|
|||
|
||||
## Quick summary
|
||||
|
||||
Since [no ARIA is better than bad ARIA](https://www.w3.org/TR/wai-aria-practices/#no_aria_better_bad_aria),
|
||||
Since [no ARIA is better than bad ARIA](https://w3c.github.io/aria-practices/#no_aria_better_bad_aria),
|
||||
review the following recommendations before using `aria-*`, `role`, and `tabindex`.
|
||||
Use semantic HTML, which has accessibility semantics baked in, and ideally test with
|
||||
[relevant combinations of screen readers and browsers](https://www.accessibility-developer-guide.com/knowledge/screen-readers/relevant-combinations/).
|
||||
|
|
|
@ -19,7 +19,7 @@ You can find the Frontend Architecture experts on the [team page](https://about.
|
|||
|
||||
## Widget Architecture
|
||||
|
||||
The [Plan stage](https://about.gitlab.com/handbook/engineering/development/dev/fe-plan/)
|
||||
The [Plan stage](https://about.gitlab.com/handbook/engineering/development/dev/plan-project-management/)
|
||||
is refactoring the right sidebar to consist of **widgets**. They have a specific architecture to be
|
||||
reusable and to expose an interface that can be used by external Vue applications on the page.
|
||||
Learn more about the [widget architecture](widgets.md).
|
||||
|
|
|
@ -14,7 +14,7 @@ info: "See the Technical Writers assigned to Development Guidelines: https://abo
|
|||
**General resources**:
|
||||
|
||||
- [📚 Official Introduction to GraphQL](https://graphql.org/learn/)
|
||||
- [📚 Official Introduction to Apollo](https://www.apollographql.com/docs/tutorial/introduction/)
|
||||
- [📚 Official Introduction to Apollo](https://www.apollographql.com/tutorials/fullstack-quickstart/introduction)
|
||||
|
||||
**GraphQL at GitLab**:
|
||||
|
||||
|
|
|
@ -434,7 +434,7 @@ Use `webpackChunkName` when generating dynamic imports as
|
|||
it provides a deterministic filename for the chunk which can then be cached
|
||||
in the browser across GitLab versions.
|
||||
|
||||
More information is available in [webpack's code splitting documentation](https://webpack.js.org/guides/code-splitting/#dynamic-imports) and [vue's dynamic component documentation](https://vuejs.org/v2/guide/components-dynamic-async.html).
|
||||
More information is available in [webpack's code splitting documentation](https://webpack.js.org/guides/code-splitting/#dynamic-imports) and [vue's dynamic component documentation](https://v2.vuejs.org/v2/guide/components-dynamic-async.html).
|
||||
|
||||
### Minimizing page size
|
||||
|
||||
|
|
|
@ -129,7 +129,7 @@ with additional functions on the instance level:
|
|||
|
||||
Source Editor provides a universal, extensible editing tool to the whole product,
|
||||
and doesn't depend on any particular group. Even though the Source Editor's core is owned by
|
||||
[Create::Editor FE Team](https://about.gitlab.com/handbook/engineering/development/dev/create-editor/),
|
||||
[Create::Editor FE Team](https://about.gitlab.com/handbook/engineering/development/dev/create/editor/),
|
||||
any group can own the extensions—the main functional elements. The goal of
|
||||
Source Editor extensions is to keep the editor's core slim and stable. Any
|
||||
needed features can be added as extensions to this core. Any group can
|
||||
|
|
|
@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
# Storybook
|
||||
|
||||
The Storybook for the `gitlab-org/gitlab` project is available on our [GitLab Pages site](https://gitlab-org.gitlab.io/gitlab/storybook).
|
||||
The Storybook for the `gitlab-org/gitlab` project is available on our [GitLab Pages site](https://gitlab-org.gitlab.io/gitlab/storybook/).
|
||||
|
||||
## Storybook in local development
|
||||
|
||||
|
|
|
@ -212,7 +212,7 @@ The following Elasticsearch settings are available:
|
|||
| `Password` | The password of your Elasticsearch instance. |
|
||||
| `Number of Elasticsearch shards` | Elasticsearch indices are split into multiple shards for performance reasons. In general, you should use at least 5 shards, and indices with tens of millions of documents need to have more shards ([see below](#guidance-on-choosing-optimal-cluster-configuration)). Changes to this value do not take effect until the index is recreated. You can read more about tradeoffs in the [Elasticsearch documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/scalability.html). |
|
||||
| `Number of Elasticsearch replicas` | Each Elasticsearch shard can have a number of replicas. These are a complete copy of the shard, and can provide increased query performance or resilience against hardware failure. Increasing this value increases total disk space required by the index. |
|
||||
| `Limit the number of namespaces and projects that can be indexed` | Enabling this allows you to select namespaces and projects to index. All other namespaces and projects use database search instead. If you enable this option but do not select any namespaces or projects, none are indexed. [Read more below](#limit-the-number-of-namespaces-and-projects-that-can-be-indexed).
|
||||
| `Limit the number of namespaces and projects that can be indexed` | Enabling this allows you to select namespaces and projects to index. All other namespaces and projects use database search instead. If you enable this option but do not select any namespaces or projects, none are indexed. [Read more below](#limit-the-number-of-namespaces-and-projects-that-can-be-indexed).|
|
||||
| `Using AWS hosted Elasticsearch with IAM credentials` | Sign your Elasticsearch requests using [AWS IAM authorization](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html), [AWS EC2 Instance Profile Credentials](https://docs.aws.amazon.com/codedeploy/latest/userguide/getting-started-create-iam-instance-profile.html#getting-started-create-iam-instance-profile-cli), or [AWS ECS Tasks Credentials](https://docs.aws.amazon.com/AmazonECS/latest/userguide/task-iam-roles.html). Please refer to [Identity and Access Management in Amazon OpenSearch Service](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/ac.html) for details of AWS hosted OpenSearch domain access policy configuration. |
|
||||
| `AWS Region` | The AWS region in which your OpenSearch Service is located. |
|
||||
| `AWS Access Key` | The AWS access key. |
|
||||
|
|
|
@ -333,7 +333,14 @@ sudo -u git -H bundle exec rake gitlab:elastic:list_pending_migrations
|
|||
|
||||
### What do you do if your Advanced Search migrations are stuck?
|
||||
|
||||
See [how to retry a halted migration](../integration/advanced_search/elasticsearch.md#retry-a-halted-migration).
|
||||
In GitLab 15.0, an Advanced Search migration named `DeleteOrphanedCommit` can be permanently stuck
|
||||
in a pending state across upgrades. This issue [is corrected in
|
||||
GitLab 15.1](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/89539).
|
||||
|
||||
If you are a self-managed customer who uses GitLab 15.0 with Advanced Search, you will experience performance degradation.
|
||||
To clean up the migration, upgrade to 15.1 or later.
|
||||
|
||||
For other Advanced Search migrations stuck in pending, see [how to retry a halted migration](../integration/advanced_search/elasticsearch.md#retry-a-halted-migration).
|
||||
|
||||
### What do you do for the error `Elasticsearch version not compatible`
|
||||
|
||||
|
|
|
@ -21,8 +21,18 @@ module Gitlab
|
|||
validate :milestone_is_string
|
||||
validate :reason_known_or_string
|
||||
|
||||
def self.parse(options)
|
||||
new(**options) if options
|
||||
def self.parse(alpha: nil, deprecated: nil)
|
||||
options = alpha || deprecated
|
||||
return unless options
|
||||
|
||||
if alpha
|
||||
raise ArgumentError, '`alpha` and `deprecated` arguments cannot be passed at the same time' \
|
||||
if deprecated
|
||||
|
||||
options[:reason] = :alpha
|
||||
end
|
||||
|
||||
new(**options)
|
||||
end
|
||||
|
||||
def initialize(reason: nil, milestone: nil, replacement: nil)
|
||||
|
|
|
@ -86,4 +86,9 @@ namespace :test_resources do
|
|||
QA::Tools::TestResourcesHandler.new.download(args[:ci_project_name])
|
||||
end
|
||||
end
|
||||
|
||||
desc "Deletes user's projects"
|
||||
task :delete_user_projects, [:delete_before, :dry_run] do |t, args|
|
||||
QA::Tools::DeleteUserProjects.new(args).run
|
||||
end
|
||||
# rubocop:enable Rails/RakeEnvironment
|
||||
|
|
|
@ -36,13 +36,14 @@ module QA
|
|||
end
|
||||
|
||||
def register!
|
||||
shell <<~CMD.tr("\n", ' ')
|
||||
cmd = <<~CMD.tr("\n", ' ')
|
||||
docker run -d --rm --network #{runner_network} --name #{@name}
|
||||
#{'-v /var/run/docker.sock:/var/run/docker.sock' if @executor == :docker}
|
||||
--privileged
|
||||
#{@image} #{add_gitlab_tls_cert if @address.include? 'https'}
|
||||
&& docker exec --detach #{@name} sh -c "#{register_command}"
|
||||
CMD
|
||||
shell(cmd, mask_secrets: [@token])
|
||||
|
||||
wait_until_running_and_configured
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ module QA
|
|||
module Tools
|
||||
class DeleteProjects
|
||||
include Support::API
|
||||
include Lib::Project
|
||||
|
||||
def initialize
|
||||
raise ArgumentError, "Please provide GITLAB_ADDRESS environment variable" unless ENV['GITLAB_ADDRESS']
|
||||
|
@ -30,25 +31,12 @@ module QA
|
|||
project_ids = fetch_project_ids(group_id, total_project_pages)
|
||||
$stdout.puts "Number of projects to be deleted: #{project_ids.length}"
|
||||
|
||||
delete_projects(project_ids) unless project_ids.empty?
|
||||
delete_projects(project_ids, @api_client) unless project_ids.empty?
|
||||
$stdout.puts "\nDone"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def delete_projects(project_ids)
|
||||
$stdout.puts "Deleting #{project_ids.length} projects..."
|
||||
project_ids.each do |project_id|
|
||||
request_url = Runtime::API::Request.new(@api_client, "/projects/#{project_id}").url
|
||||
path = parse_body(get(request_url))[:path_with_namespace]
|
||||
$stdout.puts "\nDeleting project #{path}..."
|
||||
|
||||
delete_response = delete(request_url)
|
||||
dot_or_f = delete_response.code.between?(200, 300) ? "\e[32m.\e[0m" : "\e[31mF - #{delete_response}\e[0m"
|
||||
print dot_or_f
|
||||
end
|
||||
end
|
||||
|
||||
def fetch_group_id
|
||||
group_name = ENV['TOP_LEVEL_GROUP_NAME'] || "gitlab-qa-sandbox-group-#{Time.now.wday + 1}"
|
||||
group_search_response = get Runtime::API::Request.new(@api_client, "/groups/#{group_name}").url
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# This script deletes all projects owned by a given USER_ID in their personal namespace
|
||||
# Required environment variables: USER_ID, GITLAB_QA_ACCESS_TOKEN and GITLAB_ADDRESS
|
||||
# Run `rake delete_user_projects`
|
||||
|
||||
module QA
|
||||
module Tools
|
||||
class DeleteUserProjects
|
||||
include Support::API
|
||||
include Lib::Project
|
||||
|
||||
def initialize(delete_before: (Date.today - 1).to_s, dry_run: false)
|
||||
unless ENV['GITLAB_ADDRESS']
|
||||
raise ArgumentError, "Please provide GITLAB_ADDRESS environment variable"
|
||||
end
|
||||
|
||||
unless ENV['GITLAB_QA_ACCESS_TOKEN']
|
||||
raise ArgumentError, "Please provide GITLAB_QA_ACCESS_TOKEN environment variable"
|
||||
end
|
||||
|
||||
unless ENV['USER_ID']
|
||||
raise ArgumentError, "Please provide USER_ID environment variable"
|
||||
end
|
||||
|
||||
@delete_before = Date.parse(delete_before)
|
||||
@dry_run = dry_run
|
||||
@api_client = Runtime::API::Client.new(ENV['GITLAB_ADDRESS'],
|
||||
personal_access_token: ENV['GITLAB_QA_ACCESS_TOKEN'])
|
||||
end
|
||||
|
||||
def run
|
||||
$stdout.puts 'Running...'
|
||||
|
||||
projects_head_response = head Runtime::API::Request.new(@api_client, "/users/#{ENV['USER_ID']}/projects",
|
||||
per_page: "100").url
|
||||
total_project_pages = projects_head_response.headers[:x_total_pages]
|
||||
|
||||
$stdout.puts "Total project pages: #{total_project_pages}"
|
||||
|
||||
project_ids = fetch_project_ids(total_project_pages)
|
||||
|
||||
delete_projects(project_ids, @api_client, @dry_run) unless project_ids.empty?
|
||||
$stdout.puts "\nDone"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def fetch_project_ids(total_project_pages)
|
||||
projects_ids = []
|
||||
|
||||
total_project_pages.to_i.times do |page_no|
|
||||
projects_response = get Runtime::API::Request.new(@api_client, "/users/#{ENV['USER_ID']}/projects",
|
||||
page: (page_no + 1).to_s, per_page: "100").url
|
||||
projects_ids.concat(JSON.parse(projects_response.body)
|
||||
.select { |project| Date.parse(project["created_at"]) < @delete_before }
|
||||
.map { |project| project["id"] })
|
||||
end
|
||||
|
||||
projects_ids.uniq
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module QA
|
||||
module Tools
|
||||
module Lib
|
||||
module Project
|
||||
def delete_projects(project_ids, api_client, dry_run = false)
|
||||
if dry_run
|
||||
$stdout.puts "Following #{project_ids.length} projects would be deleted:"
|
||||
else
|
||||
$stdout.puts "Deleting #{project_ids.length} projects..."
|
||||
end
|
||||
|
||||
project_ids.each do |project_id|
|
||||
request_url = Runtime::API::Request.new(api_client, "/projects/#{project_id}").url
|
||||
parsed_body = parse_body(get(request_url))
|
||||
path = parsed_body[:path_with_namespace]
|
||||
created_at = parsed_body[:created_at]
|
||||
|
||||
if dry_run
|
||||
$stdout.puts "#{path} - created at: #{created_at}"
|
||||
else
|
||||
$stdout.puts "\nDeleting project #{path} - created at: #{created_at}"
|
||||
delete_response = delete(request_url)
|
||||
dot_or_f = delete_response.code.between?(200, 300) ? "\e[32m.\e[0m" : "\e[31mF - #{delete_response}\e[0m"
|
||||
print dot_or_f
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -33,17 +33,21 @@ module QA
|
|||
end
|
||||
|
||||
it 'runs non-interactively' do
|
||||
expect(subject).to have_received(:shell).with(/ --non-interactive /)
|
||||
expect(subject).to have_received_masked_shell_command(/ --non-interactive /)
|
||||
end
|
||||
|
||||
it 'sets pertinent information' do
|
||||
expect(subject).to have_received(:shell).with(/--name #{runner_name} /)
|
||||
expect(subject).to have_received(:shell).with(/--url #{subject.address} /)
|
||||
expect(subject).to have_received(:shell).with(/--registration-token #{subject.token} /)
|
||||
expect(subject).to have_received_masked_shell_command(/--name #{runner_name} /)
|
||||
expect(subject).to have_received_masked_shell_command(/--url #{subject.address} /)
|
||||
expect(subject).to have_received_masked_shell_command(/--registration-token **** /)
|
||||
end
|
||||
|
||||
it 'masks the registration token' do
|
||||
expect(subject).to have_received(:shell).with(/#{subject.token}/, mask_secrets: [subject.token])
|
||||
end
|
||||
|
||||
it 'runs untagged' do
|
||||
expect(subject).to have_received(:shell).with(/--run-untagged=true /)
|
||||
expect(subject).to have_received_masked_shell_command(/--run-untagged=true /)
|
||||
end
|
||||
|
||||
it 'has no tags' do
|
||||
|
@ -51,11 +55,11 @@ module QA
|
|||
end
|
||||
|
||||
it 'runs daemonized' do
|
||||
expect(subject).to have_received(:shell).with(/ -d /)
|
||||
expect(subject).to have_received_masked_shell_command(/ -d /)
|
||||
end
|
||||
|
||||
it 'cleans itself up' do
|
||||
expect(subject).to have_received(:shell).with(/ --rm /)
|
||||
expect(subject).to have_received_masked_shell_command(/ --rm /)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -65,11 +69,11 @@ module QA
|
|||
end
|
||||
|
||||
it 'passes --run-untagged=true' do
|
||||
expect(subject).to have_received(:shell).with(/--run-untagged=true /)
|
||||
expect(subject).to have_received_masked_shell_command(/--run-untagged=true /)
|
||||
end
|
||||
|
||||
it 'does not pass tag list' do
|
||||
expect(subject).not_to have_received(:shell).with(/--tag-list/)
|
||||
expect(subject).not_to have_received_masked_shell_command(/--tag-list/)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -82,11 +86,11 @@ module QA
|
|||
end
|
||||
|
||||
it 'does not pass --run-untagged' do
|
||||
expect(subject).not_to have_received(:shell).with(/--run-untagged=true/)
|
||||
expect(subject).not_to have_received_masked_shell_command(/--run-untagged=true/)
|
||||
end
|
||||
|
||||
it 'passes the tags with comma-separation' do
|
||||
expect(subject).to have_received(:shell).with(/--tag-list #{tags.join(',')} /)
|
||||
expect(subject).to have_received_masked_shell_command(/--tag-list #{tags.join(',')} /)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -116,7 +120,7 @@ module QA
|
|||
it 'defaults to the shell executor' do
|
||||
register
|
||||
|
||||
expect(subject).to have_received(:shell).with(/--executor shell /)
|
||||
expect(subject).to have_received_masked_shell_command(/--executor shell /)
|
||||
end
|
||||
|
||||
context 'docker' do
|
||||
|
@ -127,31 +131,31 @@ module QA
|
|||
end
|
||||
|
||||
it 'specifies the docker executor' do
|
||||
expect(subject).to have_received(:shell).with(/--executor docker /)
|
||||
expect(subject).to have_received_masked_shell_command(/--executor docker /)
|
||||
end
|
||||
|
||||
it 'mounts the docker socket to the host runner' do
|
||||
expect(subject).to have_received(:shell).with(%r{-v /var/run/docker.sock:/var/run/docker.sock })
|
||||
expect(subject).to have_received_masked_shell_command(%r{-v /var/run/docker.sock:/var/run/docker.sock })
|
||||
end
|
||||
|
||||
it 'runs in privileged mode' do
|
||||
expect(subject).to have_received(:shell).with(/--privileged /)
|
||||
expect(subject).to have_received_masked_shell_command(/--privileged /)
|
||||
end
|
||||
|
||||
it 'has a default image' do
|
||||
expect(subject).to have_received(:shell).with(/--docker-image \b.+\b /)
|
||||
expect(subject).to have_received_masked_shell_command(/--docker-image \b.+\b /)
|
||||
end
|
||||
|
||||
it 'does not verify TLS' do
|
||||
expect(subject).to have_received(:shell).with(/--docker-tlsverify=false /)
|
||||
expect(subject).to have_received_masked_shell_command(/--docker-tlsverify=false /)
|
||||
end
|
||||
|
||||
it 'passes privileged mode' do
|
||||
expect(subject).to have_received(:shell).with(/--docker-privileged=true /)
|
||||
expect(subject).to have_received_masked_shell_command(/--docker-privileged=true /)
|
||||
end
|
||||
|
||||
it 'passes the host network' do
|
||||
expect(subject).to have_received(:shell).with(/--docker-network-mode=#{subject.network}/)
|
||||
expect(subject).to have_received_masked_shell_command(/--docker-network-mode=#{subject.network}/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -170,5 +174,15 @@ module QA
|
|||
expect(subject.run_untagged).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
RSpec::Matchers.define "have_received_masked_shell_command" do |cmd|
|
||||
match do |actual|
|
||||
expect(actual).to have_received(:shell).with(cmd, mask_secrets: anything)
|
||||
end
|
||||
|
||||
match_when_negated do |actual|
|
||||
expect(actual).not_to have_received(:shell).with(cmd, mask_secrets: anything)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -22,4 +22,5 @@ end
|
|||
compare_base = ARGV[0]
|
||||
compare_base ||= IO.popen(%w(git merge-base origin/master HEAD)) { |p| p.read.chomp }
|
||||
|
||||
Undercover::CLI.run(%W(-c #{compare_base}))
|
||||
result = Undercover::CLI.run(%W(-c #{compare_base}))
|
||||
exit result
|
||||
|
|
|
@ -6,30 +6,57 @@ require 'active_model'
|
|||
RSpec.describe ::Gitlab::Graphql::Deprecation do
|
||||
let(:options) { {} }
|
||||
|
||||
subject(:deprecation) { described_class.parse(options) }
|
||||
subject(:deprecation) { described_class.new(**options) }
|
||||
|
||||
describe '.parse' do
|
||||
context 'with nil' do
|
||||
let(:options) { nil }
|
||||
subject(:parsed_deprecation) { described_class.parse(**options) }
|
||||
|
||||
it 'parses to nil' do
|
||||
expect(deprecation).to be_nil
|
||||
context 'with no arguments' do
|
||||
it 'returns nil' do
|
||||
expect(parsed_deprecation).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'with empty options' do
|
||||
let(:options) { {} }
|
||||
context 'with an incomplete `deprecated` argument' do
|
||||
let(:options) { { deprecated: {} } }
|
||||
|
||||
it 'parses to an empty deprecation' do
|
||||
expect(deprecation).to eq(described_class.new)
|
||||
it 'parses as an invalid deprecation' do
|
||||
expect(parsed_deprecation).not_to be_valid
|
||||
expect(parsed_deprecation).to eq(described_class.new)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with defined options' do
|
||||
let(:options) { { reason: :renamed, milestone: '10.10' } }
|
||||
context 'with a `deprecated` argument' do
|
||||
let(:options) { { deprecated: { reason: :renamed, milestone: '10.10' } } }
|
||||
|
||||
it 'assigns the properties' do
|
||||
expect(deprecation).to eq(described_class.new(reason: 'This was renamed', milestone: '10.10'))
|
||||
it 'parses as a deprecation' do
|
||||
expect(parsed_deprecation).to be_valid
|
||||
expect(parsed_deprecation).to eq(
|
||||
described_class.new(reason: 'This was renamed', milestone: '10.10')
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with an `alpha` argument' do
|
||||
let(:options) { { alpha: { milestone: '10.10' } } }
|
||||
|
||||
it 'parses as an alpha' do
|
||||
expect(parsed_deprecation).to be_valid
|
||||
expect(parsed_deprecation).to eq(
|
||||
described_class.new(reason: :alpha, milestone: '10.10')
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with both `deprecated` and `alpha` arguments' do
|
||||
let(:options) do
|
||||
{ alpha: { milestone: '10.10' }, deprecated: { reason: :renamed, milestone: '10.10' } }
|
||||
end
|
||||
|
||||
it 'raises an error' do
|
||||
expect { parsed_deprecation }.to raise_error(ArgumentError,
|
||||
'`alpha` and `deprecated` arguments cannot be passed at the same time'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -69,4 +69,21 @@ RSpec.shared_examples 'Gitlab-style deprecations' do
|
|||
'This feature is in Alpha. It can be changed or removed at any time. Introduced in 1.10.'
|
||||
)
|
||||
end
|
||||
|
||||
it 'supports :alpha' do
|
||||
deprecable = subject(alpha: { milestone: '1.10' })
|
||||
|
||||
expect(deprecable.deprecation_reason).to eq(
|
||||
'This feature is in Alpha. It can be changed or removed at any time. Introduced in 1.10.'
|
||||
)
|
||||
end
|
||||
|
||||
it 'does not allow :alpha and :deprecated together' do
|
||||
expect do
|
||||
subject(alpha: { milestone: '1.10' }, deprecated: { milestone: '1.10', reason: 'my reason' } )
|
||||
end.to raise_error(
|
||||
ArgumentError,
|
||||
eq("`alpha` and `deprecated` arguments cannot be passed at the same time")
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue