summaryrefslogtreecommitdiff
path: root/doc/development
diff options
context:
space:
mode:
authorDJ Mountney <dj@gitlab.com>2019-06-28 16:27:39 +0000
committerDJ Mountney <dj@gitlab.com>2019-06-28 16:27:39 +0000
commitc1b1a1fb5e648d44286e6312daa9fa7980202914 (patch)
tree152b36c6bdd8384cc2c842d787f9058bee6bb67c /doc/development
parentde93bf1fbbd091075ef7ebafb2ab9dabc2e6563c (diff)
parent1cd8fb49f9b9150faf50767edbdfb564fde8576b (diff)
downloadgitlab-ce-c1b1a1fb5e648d44286e6312daa9fa7980202914.tar.gz
Merge branch 'master' into 'check-min-schema-migrate'
# Conflicts: # lib/gitlab/database.rb
Diffstat (limited to 'doc/development')
-rw-r--r--doc/development/api_graphql_styleguide.md2
-rw-r--r--doc/development/chatops_on_gitlabcom.md9
-rw-r--r--doc/development/contributing/issue_workflow.md7
-rw-r--r--doc/development/contributing/style_guides.md4
-rw-r--r--doc/development/documentation/site_architecture/index.md42
-rw-r--r--doc/development/documentation/styleguide.md113
-rw-r--r--doc/development/fe_guide/accessibility.md12
-rw-r--r--doc/development/feature_flags.md128
-rw-r--r--doc/development/feature_flags/controls.md123
-rw-r--r--doc/development/feature_flags/development.md131
-rw-r--r--doc/development/feature_flags/index.md12
-rw-r--r--doc/development/feature_flags/process.md130
-rw-r--r--doc/development/i18n/externalization.md45
-rw-r--r--doc/development/new_fe_guide/tips.md10
-rw-r--r--doc/development/rolling_out_changes_using_feature_flags.md226
-rw-r--r--doc/development/testing_guide/end_to_end/quick_start_guide.md12
-rw-r--r--doc/development/testing_guide/frontend_testing.md13
17 files changed, 625 insertions, 394 deletions
diff --git a/doc/development/api_graphql_styleguide.md b/doc/development/api_graphql_styleguide.md
index 2ed2a905db7..aeddad14995 100644
--- a/doc/development/api_graphql_styleguide.md
+++ b/doc/development/api_graphql_styleguide.md
@@ -447,7 +447,7 @@ want to validate the abilities for.
Alternatively, we can add a `find_object` method that will load the
object on the mutation. This would allow you to use the
-`authorized_find!` and `authorized_find!` helper methods.
+`authorized_find!` helper method.
When a user is not allowed to perform the action, or an object is not
found, we should raise a
diff --git a/doc/development/chatops_on_gitlabcom.md b/doc/development/chatops_on_gitlabcom.md
index c63ec53414c..a7b402c3fb0 100644
--- a/doc/development/chatops_on_gitlabcom.md
+++ b/doc/development/chatops_on_gitlabcom.md
@@ -1,12 +1,13 @@
# Chatops on GitLab.com
-Chatops on GitLab.com allows GitLabbers to run various automation tasks on GitLab.com using Slack.
+ChatOps on GitLab.com allows GitLab team members to run various automation tasks on GitLab.com using Slack.
## Requesting access
-GitLabbers may need access to Chatops on GitLab.com for administration tasks such as:
+GitLab team-members may need access to Chatops on GitLab.com for administration
+tasks such as:
-- Configuring feature flags on staging.
+- Configuring feature flags.
- Running `EXPLAIN` queries against the GitLab.com production replica.
To request access to Chatops on GitLab.com:
@@ -18,4 +19,4 @@ To request access to Chatops on GitLab.com:
- [Chatops Usage](https://docs.gitlab.com/ee/ci/chatops/README.html)
- [Understanding EXPLAIN plans](understanding_explain_plans.md)
- - [Feature Groups](feature_flags.md#feature-groups)
+ - [Feature Groups](feature_flags/development.md#feature-groups)
diff --git a/doc/development/contributing/issue_workflow.md b/doc/development/contributing/issue_workflow.md
index 3d36a7bf3b1..db426dec5e4 100644
--- a/doc/development/contributing/issue_workflow.md
+++ b/doc/development/contributing/issue_workflow.md
@@ -43,6 +43,10 @@ The descriptions on the [labels page][labels-page] explain what falls under each
Subject labels are labels that define what area or feature of GitLab this issue
hits. They are not always necessary, but very convenient.
+Subject labels are now used to infer and apply relevant group and devops stage
+labels. Please apply them whenever possible to facilitate accurate matching.
+Please refer to [this merge request][inferred-labels] for more information.
+
Examples of subject labels are ~wiki, ~ldap, ~api,
~issues, ~"merge requests", ~labels, and ~"Container Registry".
@@ -65,10 +69,12 @@ The current team labels are:
- ~Defend
- ~Distribution
- ~Documentation
+- ~Ecosystem
- ~Geo
- ~Gitaly
- ~Growth
- ~Manage
+- ~Memory
- ~Monitor
- ~Plan
- ~Quality
@@ -442,3 +448,4 @@ A recent example of this was the issue for
[labels-page]: https://gitlab.com/gitlab-org/gitlab-ce/labels
[ce-tracker]: https://gitlab.com/gitlab-org/gitlab-ce/issues
[ee-tracker]: https://gitlab.com/gitlab-org/gitlab-ee/issues
+[inferred-labels]: https://gitlab.com/gitlab-org/quality/triage-ops/merge_requests/155
diff --git a/doc/development/contributing/style_guides.md b/doc/development/contributing/style_guides.md
index f319d00d7fe..87e61a7476f 100644
--- a/doc/development/contributing/style_guides.md
+++ b/doc/development/contributing/style_guides.md
@@ -31,8 +31,8 @@ This is also the style used by linting tools such as
[Return to Contributing documentation](index.md)
-[rss-source]: https://github.com/bbatsov/ruby-style-guide/blob/master/README.md#source-code-layout
-[rss-naming]: https://github.com/bbatsov/ruby-style-guide/blob/master/README.md#naming
+[rss-source]: https://github.com/rubocop-hq/ruby-style-guide/blob/master/README.adoc#source-code-layout
+[rss-naming]: https://github.com/rubocop-hq/ruby-style-guide/blob/master/README.adoc#naming-conventions
[doc-guidelines]: ../documentation/index.md "Documentation guidelines"
[js-styleguide]: ../fe_guide/style_guide_js.md "JavaScript styleguide"
[scss-styleguide]: ../fe_guide/style_guide_scss.md "SCSS styleguide"
diff --git a/doc/development/documentation/site_architecture/index.md b/doc/development/documentation/site_architecture/index.md
index ee3a9caf9a0..6dd12b5efa7 100644
--- a/doc/development/documentation/site_architecture/index.md
+++ b/doc/development/documentation/site_architecture/index.md
@@ -11,8 +11,40 @@ and deploy it to <https://docs.gitlab.com>.
While the source of the documentation content is stored in GitLab's respective product
repositories, the source that is used to build the documentation site _from that content_
-is located at <https://gitlab.com/gitlab-com/gitlab-docs>. See the README there for
-detailed information.
+is located at <https://gitlab.com/gitlab-com/gitlab-docs>.
+
+The following diagram illustrates the relationship between the repositories
+from where content is sourced, the `gitlab-docs` project, and the published output.
+
+```mermaid
+ graph LR
+ A[gitlab-ce/doc]
+ B[gitlab-ee/doc]
+ C[gitlab-runner/docs]
+ D[omnibus-gitlab/doc]
+ E[charts/doc]
+ F[gitlab-docs]
+ A --> F
+ B --> F
+ C --> F
+ D --> F
+ E --> F
+ F -- Build pipeline --> G
+ G[docs.gitlab.com]
+ H[/ce/]
+ I[/ee/]
+ J[/runner/]
+ K[/omnibus/]
+ L[/charts/]
+ G --> H
+ G --> I
+ G --> J
+ G --> K
+ G --> L
+```
+
+See the [README there](https://gitlab.com/gitlab-com/gitlab-docs/blob/master/README.md)
+for detailed information.
## Assets
@@ -22,9 +54,9 @@ the GitLab Documentation website.
### Libraries
-- [Bootstrap 3.3 components](https://getbootstrap.com/docs/3.3/components/)
-- [Bootstrap 3.3 JS](https://getbootstrap.com/docs/3.3/javascript/)
-- [jQuery](https://jquery.com/) 3.2.1
+- [Bootstrap 4.3.1 components](https://getbootstrap.com/docs/4.3/components/)
+- [Bootstrap 4.3.1 JS](https://getbootstrap.com/docs/4.3/getting-started/javascript/)
+- [jQuery](https://jquery.com/) 3.3.1
- [Clipboard JS](https://clipboardjs.com/)
- [Font Awesome 4.7.0](https://fontawesome.com/v4.7.0/icons/)
diff --git a/doc/development/documentation/styleguide.md b/doc/development/documentation/styleguide.md
index 23d52a33881..7cd3d82ec4e 100644
--- a/doc/development/documentation/styleguide.md
+++ b/doc/development/documentation/styleguide.md
@@ -100,6 +100,13 @@ use regular Markdown markup, following the rules in the linked style guide.
Note that Kramdown-specific markup (e.g., `{:.class}`) will not render properly on GitLab instances under [`/help`](index.md#gitlab-help).
+Hard-coded HTML is valid, although it's discouraged to be used while we have `/help`. HTML is permitted as long as:
+
+- There's no equivalent markup in markdown.
+- Advanced tables are necessary.
+- Special styling is required.
+- Reviewed and approved by a technical writer.
+
## Structure
### Organize by topic, not by type
@@ -143,7 +150,8 @@ The table below shows what kind of documentation goes where.
a proper naming would be `import_projects_from_github.md`. The same rule
applies to images.
1. For image files, do not exceed 100KB.
-1. We do not yet support embedded videos. Please link out.
+1. Do not upload video files to the product repositories.
+[Link or embed videos](#videos) instead.
1. There are four main directories, `user`, `administration`, `api` and `development`.
1. The `doc/user/` directory has five main subdirectories: `project/`, `group/`,
`profile/`, `dashboard/` and `admin_area/`.
@@ -207,6 +215,7 @@ Do not include the same information in multiple places. [Link to a SSOT instead.
## Text
+- [Write in markdown](#markdown).
- Splitting long lines (preferably up to 100 characters) can make it easier to provide feedback on small chunks of text.
- Insert an empty line for new paragraphs.
- Use sentence case for titles, headings, labels, menu items, and buttons.
@@ -409,11 +418,20 @@ To indicate the steps of navigation through the UI:
## Images
- Place images in a separate directory named `img/` in the same directory where
- the `.md` document that you're working on is located. Always prepend their
- names with the name of the document that they will be included in. For
- example, if there is a document called `twitter.md`, then a valid image name
- could be `twitter_login_screen.png`.
-- Images should have a specific, non-generic name that will differentiate and describe them properly.
+ the `.md` document that you're working on is located.
+- Images should have a specific, non-generic name that will
+ differentiate and describe them properly.
+- Always add to the end of the file name the GitLab release version
+ number corresponding to the release milestone the image was added to,
+ or corresponding to the release the screenshot was taken from, using the
+ format `image_name_vX_Y.png`.
+ ([Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/61027) in GitLab 12.1.)
+- For example, for a screenshot taken from the pipelines page of
+ GitLab 11.1, a valid name is `pipelines_v11_1.png`. If you're
+ adding an illustration that does not include parts of the UI,
+ add the release number corresponding to the release the image
+ was added to. Example, for an MR added to 11.1's milestone,
+ a valid name for an illustration is `devops_diagram_v11_1.png`.
- Keep all file names in lower case.
- Consider using PNG images instead of JPEG.
- Compress all images with <https://tinypng.com/> or similar tool.
@@ -421,12 +439,12 @@ To indicate the steps of navigation through the UI:
- Images should be used (only when necessary) to _illustrate_ the description
of a process, not to _replace_ it.
- Max image size: 100KB (gifs included).
-- The GitLab docs do not support videos yet.
+- See also how to link and embed [videos](#videos) to illustrate the docs.
Inside the document:
- The Markdown way of using an image inside a document is:
- `![Proper description what the image is about](img/document_image_title.png)`
+ `![Proper description what the image is about](img/document_image_title_vX_Y.png)`
- Always use a proper description for what the image is about. That way, when a
browser fails to show the image, this text will be used as an alternative
description.
@@ -446,6 +464,85 @@ directly to an HTML `img` tag:
<img src="path/to/image.jpg" alt="Alt text (required)" class="image-noshadow">
```
+## Videos
+
+Adding GitLab's existing YouTube video tutorials to the documentation is
+highly encouraged, unless the video is outdated. Videos should not
+replace documentation, but complement or illustrate it. If content in a video is
+fundamental to a feature and its key use cases, but this is not adequately covered in the documentation,
+add this detail to the documentation text or create an issue to review the video and do so.
+
+Do not upload videos to the product repositories. [Link](#link-to-video) or [embed](#embed-videos) them instead.
+
+### Link to video
+
+To link out to a video, include a YouTube icon so that readers can
+quickly and easily scan the page for videos before reading:
+
+```md
+<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
+For an overview, see [Video Title](link-to-video).
+```
+
+You can link any up-to-date video that is useful to the GitLab user.
+
+### Embed videos
+
+> [Introduced](https://gitlab.com/gitlab-com/gitlab-docs/merge_requests/472) in GitLab 12.1.
+
+GitLab docs (docs.gitlab.com) support embedded videos.
+
+You can only embed videos from
+[GitLab's official YouTube account](https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg).
+For videos from other sources, [link](#link-to-video) them instead.
+
+In most cases, it is better to [link to video](#link-to-video) instead,
+because an embed takes up a lot of space on the page and can be distracting
+to readers.
+
+To embed a video, follow the instructions below and make sure
+you have your MR reviewed and approved by a technical writer.
+
+1. Copy the code below and paste it into your markdown file.
+ Leave a blank line above and below it. Do NOT edit the code
+ (don't remove or add any spaces, etc).
+1. On YouTube, visit the video URL you want to display. Copy
+ the regular URL from your browser (`https://www.youtube.com/watch?v=VIDEO-ID`)
+ and replace the video title and link in the line under `<div class="video-fallback">`.
+1. On YouTube, click **Share**, then **Embed**.
+1. Copy the `<iframe>` source (`src`) **URL only**
+ (`https://www.youtube.com/embed/VIDEO-ID`),
+ and paste it, replacing the content of the `src` field in the
+ `iframe` tag.
+
+```html
+leave a blank line here
+<div class="video-fallback">
+ See the video: [Video title](https://www.youtube.com/watch?v=MqL6BMOySIQ).
+</div>
+<figure class="video-container">
+ <iframe src="https://www.youtube.com/embed/MqL6BMOySIQ" frameborder="0" allowfullscreen="true"> </iframe>
+</figure>
+leave a blank line here
+```
+
+This is how it renders on docs.gitlab.com:
+
+<div class="video-fallback">
+ See the video: [What is GitLab](https://www.youtube.com/watch?v=enMumwvLAug).
+</div>
+<figure class="video-container">
+ <iframe src="https://www.youtube.com/embed/MqL6BMOySIQ" frameborder="0" allowfullscreen="true"> </iframe>
+</figure>
+
+> Notes:
+>
+> - The `figure` tag is required for semantic SEO and the `video_container`
+class is necessary to make sure the video is responsive and displays
+nicely on different mobile devices.
+> - The `<div class="video-fallback">` is a fallback necessary for GitLab's
+`/help`, as GitLab's markdown processor does not support iframes. It's hidden on the docs site but will be displayed on GitLab's `/help`.
+
## Code blocks
- Always wrap code added to a sentence in inline code blocks (``` ` ```).
diff --git a/doc/development/fe_guide/accessibility.md b/doc/development/fe_guide/accessibility.md
index df32242a522..64c793cfd64 100644
--- a/doc/development/fe_guide/accessibility.md
+++ b/doc/development/fe_guide/accessibility.md
@@ -5,8 +5,16 @@
[Chrome Accessibility Developer Tools][chrome-accessibility-developer-tools]
are useful for testing for potential accessibility problems in GitLab.
-Accessibility best-practices and more in-depth information is available on
-[the Audit Rules page][audit-rules] for the Chrome Accessibility Developer Tools.
+The [axe][axe-website] browser extension (available for [Firefox][axe-firefox-extension] and [Chrome][axe-chrome-extension]) is
+also a handy tool for running audits and getting feedback on markup, CSS and even potentially problematic color usages.
+
+Accessibility best-practices and more in-depth information are available on
+[the Audit Rules page][audit-rules] for the Chrome Accessibility Developer Tools. The "[awesome a11y][awesome-a11y]" list is also a
+useful compilation of accessibility-related material.
[chrome-accessibility-developer-tools]: https://github.com/GoogleChrome/accessibility-developer-tools
[audit-rules]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules
+[axe-website]: https://www.deque.com/axe/
+[axe-firefox-extension]: https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/
+[axe-chrome-extension]: https://chrome.google.com/webstore/detail/axe/lhdoppojpmngadmnindnejefpokejbdd
+[awesome-a11y]: https://github.com/brunopulis/awesome-a11y
diff --git a/doc/development/feature_flags.md b/doc/development/feature_flags.md
index 13f0c5cc33e..6bad91d6287 100644
--- a/doc/development/feature_flags.md
+++ b/doc/development/feature_flags.md
@@ -1,127 +1 @@
-# Manage feature flags
-
-Starting from GitLab 9.3 we support feature flags for features in GitLab via
-[Flipper](https://github.com/jnunemaker/flipper/). You should use the `Feature`
-class (defined in `lib/feature.rb`) in your code to get, set and list feature
-flags.
-
-During runtime you can set the values for the gates via the
-[features API](../api/features.md) (accessible to admins only).
-
-## Feature groups
-
-Starting from GitLab 9.4 we support feature groups via
-[Flipper groups](https://github.com/jnunemaker/flipper/blob/v0.10.2/docs/Gates.md#2-group).
-
-Feature groups must be defined statically in `lib/feature.rb` (in the
-`.register_feature_groups` method), but their implementation can obviously be
-dynamic (querying the DB etc.).
-
-Once defined in `lib/feature.rb`, you will be able to activate a
-feature for a given feature group via the [`feature_group` param of the features API](../api/features.md#set-or-create-a-feature)
-
-For GitLab.com, [team members have access to feature flags through Chatops](chatops_on_gitlabcom.md). Only
-percentage gates are supported at this time. Setting a feature to be used 50% of
-the time, you should execute `/chatops run feature set my_feature_flag 50`.
-
-## Feature flags for user applications
-
-This document only covers feature flags used in the development of GitLab
-itself. Feature flags in deployed user applications can be found at
-[Feature Flags](../user/project/operations/feature_flags.md)
-
-## Developing with feature flags
-
-In general, it's better to have a group- or user-based gate, and you should prefer
-it over the use of percentage gates. This would make debugging easier, as you
-filter for example logs and errors based on actors too. Furthermore, this allows
-for enabling for the `gitlab-org` group first, while the rest of the users
-aren't impacted.
-
-```ruby
-# Good
-Feature.enabled?(:feature_flag, project)
-
-# Avoid, if possible
-Feature.enabled?(:feature_flag)
-```
-
-To use feature gates based on actors, the model needs to respond to
-`flipper_id`. For example, to enable for the Foo model:
-
-```ruby
-class Foo < ActiveRecord::Base
- include FeatureGate
-end
-```
-
-Features that are developed and are intended to be merged behind a feature flag
-should not include a changelog entry. The entry should be added in the merge
-request removing the feature flags.
-
-In the rare case that you need the feature flag to be on automatically, use
-`default_enabled: true` when checking:
-
-```ruby
-Feature.enabled?(:feature_flag, project, default_enabled: true)
-```
-
-For more information about rolling out changes using feature flags, refer to the
-[Rolling out changes using feature flags](rolling_out_changes_using_feature_flags.md)
-guide.
-
-### Frontend
-
-For frontend code you can use the method `push_frontend_feature_flag`, which is
-available to all controllers that inherit from `ApplicationController`. Using
-this method you can expose the state of a feature flag as follows:
-
-```ruby
-before_action do
- push_frontend_feature_flag(:vim_bindings)
-end
-
-def index
- # ...
-end
-
-def edit
- # ...
-end
-```
-
-You can then check for the state of the feature flag in JavaScript as follows:
-
-```javascript
-if ( gon.features.vimBindings ) {
- // ...
-}
-```
-
-The name of the feature flag in JavaScript will always be camelCased, meaning
-that checking for `gon.features.vim_bindings` would not work.
-
-### Specs
-
-In the test environment `Feature.enabled?` is stubbed to always respond to `true`,
-so we make sure behavior under feature flag doesn't go untested in some non-specific
-contexts.
-
-Whenever a feature flag is present, make sure to test _both_ states of the
-feature flag.
-
-See the
-[testing guide](testing_guide/best_practices.md#feature-flags-in-tests)
-for information and examples on how to stub feature flags in tests.
-
-## Enabling a feature flag (in development)
-
-In the rails console (`rails c`), enter the following command to enable your feature flag
-
-```ruby
-Feature.enable(:feature_flag_name)
-```
-
-## Enabling a feature flag (in production)
-
-Check how to [roll out changes using feature flags](rolling_out_changes_using_feature_flags.md).
+This document was moved to [another location](feature_flags/index.md).
diff --git a/doc/development/feature_flags/controls.md b/doc/development/feature_flags/controls.md
new file mode 100644
index 00000000000..c67467b7c11
--- /dev/null
+++ b/doc/development/feature_flags/controls.md
@@ -0,0 +1,123 @@
+# Access for enabling a feature flag in production
+
+In order to be able to turn on/off features behind feature flags in any of the
+GitLab Inc. provided environments such as staging and production, you need to
+have access to the chatops bot. Chatops bot is currently running on the ops instance,
+which is different from GitLab.com or dev.gitlab.org.
+
+Follow the Chatops document to [request access](https://docs.gitlab.com/ee/development/chatops_on_gitlabcom.html#requesting-access).
+
+Once you are added to the project test if your access propagated,
+run:
+
+```
+/chatops run feature --help
+```
+
+## Rolling out changes
+
+When the changes are deployed to the environments it is time to start
+rolling out the feature to our users. The exact procedure of rolling out a
+change is unspecified, as this can vary from change to change. However, in
+general we recommend rolling out changes incrementally, instead of enabling them
+for everybody right away. We also recommend you to _not_ enable a feature
+_before_ the code is being deployed.
+This allows you to separate rolling out a feature from a deploy, making it
+easier to measure the impact of both separately.
+
+GitLab's feature library (using
+[Flipper](https://github.com/jnunemaker/flipper), and covered in the [Feature
+Flags process](process.md) guide) supports rolling out changes to a percentage of
+users. This in turn can be controlled using [GitLab chatops](../../ci/chatops/README.md).
+
+For an up to date list of feature flag commands please see [the source
+code](https://gitlab.com/gitlab-com/chatops/blob/master/lib/chatops/commands/feature.rb).
+Note that all the examples in that file must be preceded by
+`/chatops run`.
+
+If you get an error "Whoops! This action is not allowed. This incident
+will be reported." that means your Slack account is not allowed to
+change feature flags or you do not [have access](#access-for-enabling-a-feature-flag-in-production).
+
+### Enabling feature for staging and dev.gitlab.org
+
+As a first step in a feature rollout, you should enable the feature on <https://staging.gitlab.com>
+and <https://dev.gitlab.org>.
+
+For example, to enable a feature for 25% of all users, run the following in
+Slack:
+
+```
+/chatops run feature set new_navigation_bar 25 --dev
+/chatops run feature set new_navigation_bar 25 --staging
+```
+
+These two environments have different scopes.
+`dev.gitlab.org` is a production CE environment that has internal GitLab Inc.
+traffic and is used for some development and other related work.
+`staging.gitlab.com` has a smaller subset of GitLab.com database and repositories
+and does not have regular traffic. Staging is an EE instance and can give you
+a (very) rough estimate of how your feature will look/behave on GitLab.com.
+Both of these instances are connected to Sentry so make sure you check the projects
+there for any exceptions while testing your feature after enabling the feature flag.
+
+Once you are confident enough that these environments are in a good state with your
+feature enabled, you can roll out the change to GitLab.com.
+
+## Enabling feature for GitLab.com
+
+Similar to above, to enable a feature for 25% of all users, run the following in
+Slack:
+
+```
+/chatops run feature set new_navigation_bar 25
+```
+
+This will enable the feature for GitLab.com, with `new_navigation_bar` being the
+name of the feature.
+
+If you are not certain what percentages to use, simply use the following steps:
+
+1. 25%
+1. 50%
+1. 75%
+1. 100%
+
+Between every step you'll want to wait a little while and monitor the
+appropriate graphs on <https://dashboards.gitlab.net>. The exact time to wait
+may differ. For some features a few minutes is enough, while for others you may
+want to wait several hours or even days. This is entirely up to you, just make
+sure it is clearly communicated to your team, and the Production team if you
+anticipate any potential problems.
+
+Feature gates can also be actor based, for example a feature could first be
+enabled for only the `gitlab-ce` project. The project is passed by supplying a
+`--project` flag:
+
+```
+/chatops run feature set --project=gitlab-org/gitlab-ce some_feature true
+```
+
+For groups the `--group` flag is available:
+
+```
+/chatops run feature set --group=gitlab-org some_feature true
+```
+
+## Cleaning up
+
+Once the change is deemed stable, submit a new merge request to remove the
+feature flag. This ensures the change is available to all users and self-hosted
+instances. Make sure to add the ~"feature flag" label to this merge request so
+release managers are aware the changes are hidden behind a feature flag. If the
+merge request has to be picked into a stable branch, make sure to also add the
+appropriate "Pick into X" label (e.g. "Pick into XX.X").
+See [the process document](https://docs.gitlab.com/ee/development/feature_flags/process.html#including-a-feature-behind-feature-flag-in-the-final-release) for further details.
+
+When a feature gate has been removed from the code base, the value still exists
+in the database.
+This can be removed through ChatOps:
+
+```
+/chatops run feature delete some_feature
+```
diff --git a/doc/development/feature_flags/development.md b/doc/development/feature_flags/development.md
new file mode 100644
index 00000000000..238052529d9
--- /dev/null
+++ b/doc/development/feature_flags/development.md
@@ -0,0 +1,131 @@
+# Developing with feature flags
+
+In general, it's better to have a group- or user-based gate, and you should prefer
+it over the use of percentage gates. This would make debugging easier, as you
+filter for example logs and errors based on actors too. Furthermore, this allows
+for enabling for the `gitlab-org` or `gitlab-com` group first, while the rest of
+the users aren't impacted.
+
+```ruby
+# Good
+Feature.enabled?(:feature_flag, project)
+
+# Avoid, if possible
+Feature.enabled?(:feature_flag)
+```
+
+To use feature gates based on actors, the model needs to respond to
+`flipper_id`. For example, to enable for the Foo model:
+
+```ruby
+class Foo < ActiveRecord::Base
+ include FeatureGate
+end
+```
+
+Features that are developed and are intended to be merged behind a feature flag
+should not include a changelog entry. The entry should be added in the merge
+request removing the feature flags.
+
+In the rare case that you need the feature flag to be on automatically, use
+`default_enabled: true` when checking:
+
+```ruby
+Feature.enabled?(:feature_flag, project, default_enabled: true)
+```
+
+The [`Project#feature_available?`][project-fa],
+[`Namespace#feature_available?`][namespace-fa] (EE), and
+[`License.feature_available?`][license-fa] (EE) methods all implicitly check for
+a feature flag by the same name as the provided argument.
+
+For example if a feature is license-gated, there's no need to add an additional
+explicit feature flag check since the flag will be checked as part of the
+`License.feature_available?` call. Similarly, there's no need to "clean up" a
+feature flag once the feature has reached general availability.
+
+You'd still want to use an explicit `Feature.enabled?` check if your new feature
+isn't gated by a License or Plan.
+
+[project-fa]: https://gitlab.com/gitlab-org/gitlab-ee/blob/4cc1c62918aa4c31750cb21dfb1a6c3492d71080/app/models/project_feature.rb#L63-68
+[namespace-fa]: https://gitlab.com/gitlab-org/gitlab-ee/blob/4cc1c62918aa4c31750cb21dfb1a6c3492d71080/ee/app/models/ee/namespace.rb#L71-85
+[license-fa]: https://gitlab.com/gitlab-org/gitlab-ee/blob/4cc1c62918aa4c31750cb21dfb1a6c3492d71080/ee/app/models/license.rb#L293-300
+
+An important side-effect of the implicit feature flags mentioned above is that
+unless the feature is explicitly disabled or limited to a percentage of users,
+the feature flag check will default to `true`.
+
+As an example, if you were to ship the backend half of a feature behind a flag,
+you'd want to explicitly disable that flag until the frontend half is also ready
+to be shipped. [You can do this via Chatops](https://docs.gitlab.com/ee/development/feature_flags/controls.html):
+
+```
+/chatops run feature set some_feature 0
+```
+
+Note that you can do this at any time, even before the merge request using the
+flag has been merged!
+
+## Feature groups
+
+Starting from GitLab 9.4 we support feature groups via
+[Flipper groups](https://github.com/jnunemaker/flipper/blob/v0.10.2/docs/Gates.md#2-group).
+
+Feature groups must be defined statically in `lib/feature.rb` (in the
+`.register_feature_groups` method), but their implementation can obviously be
+dynamic (querying the DB etc.).
+
+Once defined in `lib/feature.rb`, you will be able to activate a
+feature for a given feature group via the [`feature_group` param of the features API](../../api/features.md#set-or-create-a-feature)
+
+### Frontend
+
+For frontend code you can use the method `push_frontend_feature_flag`, which is
+available to all controllers that inherit from `ApplicationController`. Using
+this method you can expose the state of a feature flag as follows:
+
+```ruby
+before_action do
+ push_frontend_feature_flag(:vim_bindings)
+end
+
+def index
+ # ...
+end
+
+def edit
+ # ...
+end
+```
+
+You can then check for the state of the feature flag in JavaScript as follows:
+
+```javascript
+if ( gon.features.vimBindings ) {
+ // ...
+}
+```
+
+The name of the feature flag in JavaScript will always be camelCased, meaning
+that checking for `gon.features.vim_bindings` would not work.
+
+### Specs
+
+In the test environment `Feature.enabled?` is stubbed to always respond to `true`,
+so we make sure behavior under feature flag doesn't go untested in some non-specific
+contexts.
+
+Whenever a feature flag is present, make sure to test _both_ states of the
+feature flag.
+
+See the
+[testing guide](../testing_guide/best_practices.md#feature-flags-in-tests)
+for information and examples on how to stub feature flags in tests.
+
+### Enabling a feature flag (in development)
+
+In the rails console (`rails c`), enter the following command to enable your feature flag
+
+```ruby
+Feature.enable(:feature_flag_name)
+```
diff --git a/doc/development/feature_flags/index.md b/doc/development/feature_flags/index.md
new file mode 100644
index 00000000000..56872f8c075
--- /dev/null
+++ b/doc/development/feature_flags/index.md
@@ -0,0 +1,12 @@
+# Feature flags in development of GitLab
+
+Feature flags can be used to gradually roll out changes, be
+it a new feature, or a performance improvement. By using feature flags, we can
+comfortably measure the impact of our changes, while still being able to easily
+disable those changes, without having to revert an entire release.
+
+Before using feature flags for GitLab's development, read through the following:
+
+- [Process for using features flags](process.md).
+- [Developing with feature flags documentation](development.md).
+- [Controlling feature flags documentation](controls.md).
diff --git a/doc/development/feature_flags/process.md b/doc/development/feature_flags/process.md
new file mode 100644
index 00000000000..ee142b0da66
--- /dev/null
+++ b/doc/development/feature_flags/process.md
@@ -0,0 +1,130 @@
+# Feature flags process
+## Feature flags for user applications
+
+This document only covers feature flags used in the development of GitLab
+itself. Feature flags in deployed user applications can be found at
+[Feature Flags feature documentation](../../user/project/operations/feature_flags.md).
+
+## Feature flags in GitLab development
+
+The following highlights should be considered when deciding if feature flags
+should be leveraged:
+
+- By default, the feature flags should be **off**.
+- Feature flags should remain in the codebase for as short period as possible
+to reduce the need for feature flag accounting.
+- The person operating with feature flags is responsible for clearly communicating
+the status of a feature behind the feature flag with responsible stakeholders.
+- Merge requests that make changes hidden behind a feature flag, or remove an
+existing feature flag because a feature is deemed stable must have the
+~"feature flag" label assigned.
+
+One might be tempted to think that feature flags will delay the release of a
+feature by at least one month (= one release). This is not the case. A feature
+flag does not have to stick around for a specific amount of time
+(e.g. at least one release), instead they should stick around until the feature
+is deemed stable. Stable means it works on GitLab.com without causing any
+problems, such as outages.
+
+### When to use feature flags
+
+Starting with GitLab 11.4, developers are required to use feature flags for
+non-trivial changes. Such changes include:
+
+- New features (e.g. a new merge request widget, epics, etc).
+- Complex performance improvements that may require additional testing in
+ production, such as rewriting complex queries.
+- Invasive changes to the user interface, such as a new navigation bar or the
+ removal of a sidebar.
+- Adding support for importing projects from a third-party service.
+
+In all cases, those working on the changes can best decide if a feature flag is
+necessary. For example, changing the color of a button doesn't need a feature
+flag, while changing the navigation bar definitely needs one. In case you are
+uncertain if a feature flag is necessary, simply ask about this in the merge
+request, and those reviewing the changes will likely provide you with an answer.
+
+When using a feature flag for UI elements, make sure to _also_ use a feature
+flag for the underlying backend code, if there is any. This ensures there is
+absolutely no way to use the feature until it is enabled.
+
+### Including a feature behind feature flag in the final release
+
+In order to build a final release and present the feature for self-hosted
+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. Take into consideration that such
+action can make the feature available on GitLab.com shortly after the change to
+the feature flag is merged.
+
+Changing the default state or removing the feature flag has to be done before
+the 22nd of the month, _at least_ 2 working days before, in order for the change
+to be included in the final self-managed release.
+
+In addition to this, the feature behind feature flag should:
+
+- Run in all GitLab.com environments for a sufficient period of time. This time
+period depends on the feature behind the feature flag, but as a general rule of
+thumb 2-4 working days should be sufficient to gather enough feedback.
+- The feature should be exposed to all users within the GitLab.com plan during
+the above mentioned period of time. Exposing the feature to a smaller percentage
+or only a group of users might not expose a sufficient amount of information to aid in
+making a decision on feature stability.
+
+While rare, release managers may decide to reject picking or revert a change in
+a stable branch, even when feature flags are used. This might be necessary if
+the changes are deemed problematic, too invasive, or there simply isn't enough
+time to properly measure how the changes behave on GitLab.com.
+
+### The cost of feature flags
+
+When reading the above, one might be tempted to think this procedure is going to
+add a lot of work. Fortunately, this is not the case, and we'll show why. For
+this example we'll specify the cost of the work to do as a number, ranging from
+0 to infinity. The greater the number, the more expensive the work is. The cost
+does _not_ translate to time, it's just a way of measuring complexity of one
+change relative to another.
+
+Let's say we are building a new feature, and we have determined that the cost of
+this is 10. We have also determined that the cost of adding a feature flag check
+in a variety of places is 1. If we do not use feature flags, and our feature
+works as intended, our total cost is 10. This however is the best case scenario.
+Optimizing for the best case scenario is guaranteed to lead to trouble, whereas
+optimizing for the worst case scenario is almost always better.
+
+To illustrate this, let's say our feature causes an outage, and there's no
+immediate way to resolve it. This means we'd have to take the following steps to
+resolve the outage:
+
+1. Revert the release.
+1. Perform any cleanups that might be necessary, depending on the changes that
+ were made.
+1. Revert the commit, ensuring the "master" branch remains stable. This is
+ especially necessary if solving the problem can take days or even weeks.
+1. Pick the revert commit into the appropriate stable branches, ensuring we
+ don't block any future releases until the problem is resolved.
+
+As history has shown, these steps are time consuming, complex, often involve
+many developers, and worst of all: our users will have a bad experience using
+GitLab.com until the problem is resolved.
+
+Now let's say that all of this has an associated cost of 10. This means that in
+the worst case scenario, which we should optimize for, our total cost is now 20.
+
+If we had used a feature flag, things would have been very different. We don't
+need to revert a release, and because feature flags are disabled by default we
+don't need to revert and pick any Git commits. In fact, all we have to do is
+disable the feature, and in the worst case, perform cleanup. Let's say that
+the cost of this is 2. In this case, our best case cost is 11: 10 to build the
+feature, and 1 to add the feature flag. The worst case cost is now 13: 10 to
+build the feature, 1 to add the feature flag, and 2 to disable and clean up.
+
+Here we can see that in the best case scenario the work necessary is only a tiny
+bit more compared to not using a feature flag. Meanwhile, the process of
+reverting our changes has been made significantly and reliably cheaper.
+
+In other words, feature flags do not slow down the development process. Instead,
+they speed up the process as managing incidents now becomes _much_ easier. Once
+continuous deployments are easier to perform, the time to iterate on a feature
+is reduced even further, as you no longer need to wait weeks before your changes
+are available on GitLab.com.
diff --git a/doc/development/i18n/externalization.md b/doc/development/i18n/externalization.md
index ce310672dad..17462887162 100644
--- a/doc/development/i18n/externalization.md
+++ b/doc/development/i18n/externalization.md
@@ -135,7 +135,7 @@ There is also and alternative method to [translate messages from validation erro
### Interpolation
Placeholders in translated text should match the code style of the respective source file.
-For example use `%{created_at}` in Ruby but `%{createdAt}` in JavaScript.
+For example use `%{created_at}` in Ruby but `%{createdAt}` in JavaScript. Make sure to [avoid splitting sentences when adding links](#avoid-splitting-sentences-when-adding-links).
- In Ruby/HAML:
@@ -267,20 +267,41 @@ should be externalized as follows:
This also applies when using links in between translated sentences, otherwise these texts are not translatable in certain languages.
-Instead of:
+- In Ruby/HAML, instead of:
+
+ ```haml
+ - zones_link = link_to(s_('ClusterIntegration|zones'), 'https://cloud.google.com/compute/docs/regions-zones/regions-zones', target: '_blank', rel: 'noopener noreferrer')
+ = s_('ClusterIntegration|Learn more about %{zones_link}').html_safe % { zones_link: zones_link }
+ ```
+
+ Set the link starting and ending HTML fragments as variables like so:
+
+ ```haml
+ - zones_link_url = 'https://cloud.google.com/compute/docs/regions-zones/regions-zones'
+ - zones_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: zones_link_url }
+ = s_('ClusterIntegration|Learn more about %{zones_link_start}zones%{zones_link_end}').html_safe % { zones_link_start: zones_link_start, zones_link_end: '</a>'.html_safe }
+ ```
-```haml
-- zones_link = link_to(s_('ClusterIntegration|zones'), 'https://cloud.google.com/compute/docs/regions-zones/regions-zones', target: '_blank', rel: 'noopener noreferrer')
-= s_('ClusterIntegration|Learn more about %{zones_link}').html_safe % { zones_link: zones_link }
-```
+- In JavaScript, instead of:
-Set the link starting and ending HTML fragments as variables like so:
+ ```js
+ {{
+ sprintf(s__("ClusterIntegration|Learn more about %{link}"), {
+ link: '<a href="https://cloud.google.com/compute/docs/regions-zones/regions-zones" target="_blank" rel="noopener noreferrer">zones</a>'
+ })
+ }}
+ ```
-```haml
-- zones_link_url = 'https://cloud.google.com/compute/docs/regions-zones/regions-zones'
-- zones_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: zones_link_url }
-= s_('ClusterIntegration|Learn more about %{zones_link_start}zones%{zones_link_end}').html_safe % { zones_link_start: zones_link_start, zones_link_end: '</a>'.html_safe }
-```
+ Set the link starting and ending HTML fragments as variables like so:
+
+ ```js
+ {{
+ sprintf(s__("ClusterIntegration|Learn more about %{linkStart}zones%{linkEnd}"), {
+ linkStart: '<a href="https://cloud.google.com/compute/docs/regions-zones/regions-zones" target="_blank" rel="noopener noreferrer">'
+ linkEnd: '</a>',
+ })
+ }}
+ ```
The reasoning behind this is that in some languages words change depending on context. For example in Japanese は is added to the subject of a sentence and を to the object. This is impossible to translate correctly if we extract individual words from the sentence.
diff --git a/doc/development/new_fe_guide/tips.md b/doc/development/new_fe_guide/tips.md
index 4564f678ec0..879b54bd93c 100644
--- a/doc/development/new_fe_guide/tips.md
+++ b/doc/development/new_fe_guide/tips.md
@@ -10,16 +10,16 @@ yarn clean
## Creating feature flags in development
-The process for creating a feature flag is the same as [enabling a feature flag in development](../feature_flags.md#enabling-a-feature-flag-in-development).
+The process for creating a feature flag is the same as [enabling a feature flag in development](../feature_flags/development.md#enabling-a-feature-flag-in-development).
Your feature flag can now be:
-- [made available to the frontend](../feature_flags.md#frontend) via the `gon`
-- queried in [tests](../feature_flags.md#specs)
-- queried in HAML templates and ruby files via the `Feature.enabled?(:my_shiny_new_feature_flag)` method
+- [Made available to the frontend](../feature_flags/development.md#frontend) via the `gon`
+- Queried in [tests](../feature_flags/development.md#specs)
+- Queried in HAML templates and ruby files via the `Feature.enabled?(:my_shiny_new_feature_flag)` method
### More on feature flags
- [Deleting a feature flag](../../api/features.md#delete-a-feature)
-- [Manage feature flags](../feature_flags.md)
+- [Manage feature flags](../feature_flags/process.md)
- [Feature flags API](../../api/features.md)
diff --git a/doc/development/rolling_out_changes_using_feature_flags.md b/doc/development/rolling_out_changes_using_feature_flags.md
index 84028b1b342..6bad91d6287 100644
--- a/doc/development/rolling_out_changes_using_feature_flags.md
+++ b/doc/development/rolling_out_changes_using_feature_flags.md
@@ -1,225 +1 @@
-# Rolling out changes using feature flags
-
-[Feature flags](feature_flags.md) can be used to gradually roll out changes, be
-it a new feature, or a performance improvement. By using feature flags, we can
-comfortably measure the impact of our changes, while still being able to easily
-disable those changes, without having to revert an entire release.
-
-## When to use feature flags
-
-Starting with GitLab 11.4, developers are required to use feature flags for
-non-trivial changes. Such changes include:
-
-- New features (e.g. a new merge request widget, epics, etc).
-- Complex performance improvements that may require additional testing in
- production, such as rewriting complex queries.
-- Invasive changes to the user interface, such as a new navigation bar or the
- removal of a sidebar.
-- Adding support for importing projects from a third-party service.
-
-In all cases, those working on the changes can best decide if a feature flag is
-necessary. For example, changing the color of a button doesn't need a feature
-flag, while changing the navigation bar definitely needs one. In case you are
-uncertain if a feature flag is necessary, simply ask about this in the merge
-request, and those reviewing the changes will likely provide you with an answer.
-
-When using a feature flag for UI elements, make sure to _also_ use a feature
-flag for the underlying backend code, if there is any. This ensures there is
-absolutely no way to use the feature until it is enabled.
-
-## The cost of feature flags
-
-When reading the above, one might be tempted to think this procedure is going to
-add a lot of work. Fortunately, this is not the case, and we'll show why. For
-this example we'll specify the cost of the work to do as a number, ranging from
-0 to infinity. The greater the number, the more expensive the work is. The cost
-does _not_ translate to time, it's just a way of measuring complexity of one
-change relative to another.
-
-Let's say we are building a new feature, and we have determined that the cost of
-this is 10. We have also determined that the cost of adding a feature flag check
-in a variety of places is 1. If we do not use feature flags, and our feature
-works as intended, our total cost is 10. This however is the best case scenario.
-Optimising for the best case scenario is guaranteed to lead to trouble, whereas
-optimising for the worst case scenario is almost always better.
-
-To illustrate this, let's say our feature causes an outage, and there's no
-immediate way to resolve it. This means we'd have to take the following steps to
-resolve the outage:
-
-1. Revert the release.
-1. Perform any cleanups that might be necessary, depending on the changes that
- were made.
-1. Revert the commit, ensuring the "master" branch remains stable. This is
- especially necessary if solving the problem can take days or even weeks.
-1. Pick the revert commit into the appropriate stable branches, ensuring we
- don't block any future releases until the problem is resolved.
-
-As history has shown, these steps are time consuming, complex, often involve
-many developers, and worst of all: our users will have a bad experience using
-GitLab.com until the problem is resolved.
-
-Now let's say that all of this has an associated cost of 10. This means that in
-the worst case scenario, which we should optimise for, our total cost is now 20.
-
-If we had used a feature flag, things would have been very different. We don't
-need to revert a release, and because feature flags are disabled by default we
-don't need to revert and pick any Git commits. In fact, all we have to do is
-disable the feature, and in the worst case, perform cleanup. Let's say that
-the cost of this is 2. In this case, our best case cost is 11: 10 to build the
-feature, and 1 to add the feature flag. The worst case cost is now 13: 10 to
-build the feature, 1 to add the feature flag, and 2 to disable and clean up.
-
-Here we can see that in the best case scenario the work necessary is only a tiny
-bit more compared to not using a feature flag. Meanwhile, the process of
-reverting our changes has been made significantly and reliably cheaper.
-
-In other words, feature flags do not slow down the development process. Instead,
-they speed up the process as managing incidents now becomes _much_ easier. Once
-continuous deployments are easier to perform, the time to iterate on a feature
-is reduced even further, as you no longer need to wait weeks before your changes
-are available on GitLab.com.
-
-## Rolling out changes
-
-The procedure of using feature flags is straightforward, and similar to not
-using them. You add the necessary tests (make sure to test both the on and off
-states of your feature flag(s)), make sure they all pass, have the code
-reviewed, etc. You then submit your merge request, and add the ~"feature flag"
-label. This label is used to signal to release managers that your changes are
-hidden behind a feature flag and that it is safe to pick the MR into a stable
-branch, without the need for an exception request.
-
-When the changes are deployed it is time to start rolling out the feature to our
-users. The exact procedure of rolling out a change is unspecified, as this can
-vary from change to change. However, in general we recommend rolling out changes
-incrementally, instead of enabling them for everybody right away. We also
-recommend you to _not_ enable a feature _before_ the code is being deployed.
-This allows you to separate rolling out a feature from a deploy, making it
-easier to measure the impact of both separately.
-
-GitLab's feature library (using
-[Flipper](https://github.com/jnunemaker/flipper), and covered in the [Feature
-Flags](feature_flags.md) guide) supports rolling out changes to a percentage of
-users. This in turn can be controlled using [GitLab
-chatops](../ci/chatops/README.md).
-
-For an up to date list of feature flag commands please see [the source
-code](https://gitlab.com/gitlab-com/chatops/blob/master/lib/chatops/commands/feature.rb).
-Note that all the examples in that file must be preceded by
-`/chatops run`.
-
-If you get an error "Whoops! This action is not allowed. This incident
-will be reported." that means your Slack account is not allowed to
-change feature flags. To test if you are allowed to do anything at all,
-run:
-
-```
-/chatops run feature --help
-```
-
-For example, to enable a feature for 25% of all users, run the following in
-Slack:
-
-```
-/chatops run feature set new_navigation_bar 25
-```
-
-This will enable the feature for GitLab.com, with `new_navigation_bar` being the
-name of the feature. We can also enable the feature for <https://dev.gitlab.org>
-or <https://staging.gitlab.com>:
-
-```
-/chatops run feature set new_navigation_bar 25 --dev
-/chatops run feature set new_navigation_bar 25 --staging
-```
-
-If you are not certain what percentages to use, simply use the following steps:
-
-1. 25%
-1. 50%
-1. 75%
-1. 100%
-
-Between every step you'll want to wait a little while and monitor the
-appropriate graphs on <https://dashboards.gitlab.net>. The exact time to wait
-may differ. For some features a few minutes is enough, while for others you may
-want to wait several hours or even days. This is entirely up to you, just make
-sure it is clearly communicated to your team, and the Production team if you
-anticipate any potential problems.
-
-Feature gates can also be actor based, for example a feature could first be
-enabled for only the `gitlab-ce` project. The project is passed by supplying a
-`--project` flag:
-
-```
-/chatops run feature set --project=gitlab-org/gitlab-ce some_feature true
-```
-
-For groups the `--group` flag is available:
-
-```
-/chatops run feature set --group=gitlab-org some_feature true
-```
-
-Once a change is deemed stable, submit a new merge request to remove the
-feature flag. This ensures the change is available to all users and self-hosted
-instances. Make sure to add the ~"feature flag" label to this merge request so
-release managers are aware the changes are hidden behind a feature flag. If the
-merge request has to be picked into a stable branch (e.g. after the 7th), make
-sure to also add the appropriate "Pick into X" label (e.g. "Pick into 11.4").
-
-One might be tempted to think this will delay the release of a feature by at
-least one month (= one release). This is not the case. A feature flag does not
-have to stick around for a specific amount of time (e.g. at least one release),
-instead they should stick around until the feature is deemed stable. Stable
-means it works on GitLab.com without causing any problems, such as outages. In
-most cases this will translate to a feature (with a feature flag) being shipped
-in RC1, followed by the feature flag being removed in RC2. This in turn means
-the feature will be stable by the time we publish a stable package around the
-22nd of the month.
-
-## Implicit feature flags
-
-The [`Project#feature_available?`][project-fa],
-[`Namespace#feature_available?`][namespace-fa] (EE), and
-[`License.feature_available?`][license-fa] (EE) methods all implicitly check for
-a feature flag by the same name as the provided argument.
-
-For example if a feature is license-gated, there's no need to add an additional
-explicit feature flag check since the flag will be checked as part of the
-`License.feature_available?` call. Similarly, there's no need to "clean up" a
-feature flag once the feature has reached general availability.
-
-You'd still want to use an explicit `Feature.enabled?` check if your new feature
-isn't gated by a License or Plan.
-
-[project-fa]: https://gitlab.com/gitlab-org/gitlab-ee/blob/4cc1c62918aa4c31750cb21dfb1a6c3492d71080/app/models/project_feature.rb#L63-68
-[namespace-fa]: https://gitlab.com/gitlab-org/gitlab-ee/blob/4cc1c62918aa4c31750cb21dfb1a6c3492d71080/ee/app/models/ee/namespace.rb#L71-85
-[license-fa]: https://gitlab.com/gitlab-org/gitlab-ee/blob/4cc1c62918aa4c31750cb21dfb1a6c3492d71080/ee/app/models/license.rb#L293-300
-
-### Undefined feature flags default to "on"
-
-An important side-effect of the [implicit feature flags](#implicit-feature-flags)
-mentioned above is that unless the feature is explicitly disabled or limited to a
-percentage of users, the feature flag check will default to `true`.
-
-As an example, if you were to ship the backend half of a feature behind a flag,
-you'd want to explicitly disable that flag until the frontend half is also ready
-to be shipped. You can do this via ChatOps:
-
-```
-/chatops run feature set some_feature 0
-```
-
-Note that you can do this at any time, even before the merge request using the
-flag has been merged!
-
-### Cleaning up
-
-When a feature gate has been removed from the code base, the value still exists
-in the database. This can be removed through ChatOps:
-
-```
-/chatops run feature delete some_feature
-```
+This document was moved to [another location](feature_flags/index.md).
diff --git a/doc/development/testing_guide/end_to_end/quick_start_guide.md b/doc/development/testing_guide/end_to_end/quick_start_guide.md
index f96c85be1ba..041bdf716b3 100644
--- a/doc/development/testing_guide/end_to_end/quick_start_guide.md
+++ b/doc/development/testing_guide/end_to_end/quick_start_guide.md
@@ -242,7 +242,7 @@ module QA
issue = Resource::Issue.fabricate_via_api! do |issue|
issue.title = 'Issue to test the scoped labels'
- issue.labels = @initial_label
+ issue.labels = [@initial_label]
end
[@new_label_same_scope, @new_label_different_scope].each do |label|
@@ -365,6 +365,14 @@ Add the following `attribute :id` and `attribute :labels` right above the [`attr
> We add the attributes above the existing attribute to keep them alphabetically organized.
+Then, let's initialize an instance variable for labels to allow an empty array as default value when such information is not passed during the resource fabrication, since this optional. [Between the attributes and the `fabricate!` method](https://gitlab.com/gitlab-org/gitlab-ee/blob/1a1f1408728f19b2aa15887cd20bddab7e70c8bd/qa/qa/resource/issue.rb#L18), add the following:
+
+```ruby
+def initialize
+ @labels = []
+end
+```
+
Next, add the following code right below the [`fabricate!`](https://gitlab.com/gitlab-org/gitlab-ee/blob/d3584e80b4236acdf393d815d604801573af72cc/qa/qa/resource/issue.rb#L27) method.
```ruby
@@ -378,7 +386,7 @@ end
def api_post_body
{
- labels: [labels],
+ labels: labels,
title: title
}
end
diff --git a/doc/development/testing_guide/frontend_testing.md b/doc/development/testing_guide/frontend_testing.md
index fc9b175bc8a..28ebb6f0f64 100644
--- a/doc/development/testing_guide/frontend_testing.md
+++ b/doc/development/testing_guide/frontend_testing.md
@@ -27,7 +27,7 @@ we need to solve before being able to use Jest for all our needs.
### Differences to Karma
- Jest runs in a Node.js environment, not in a browser. Support for running Jest tests in a browser [is planned](https://gitlab.com/gitlab-org/gitlab-ce/issues/58205).
-- Because Jest runs in a Node.js environment, it uses [jsdom](https://github.com/jsdom/jsdom) by default.
+- Because Jest runs in a Node.js environment, it uses [jsdom](https://github.com/jsdom/jsdom) by default. See also its [limitations](#limitations-of-jsdom) below.
- Jest does not have access to Webpack loaders or aliases.
The aliases used by Jest are defined in its [own config](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/jest.config.js).
- All calls to `setTimeout` and `setInterval` are mocked away. See also [Jest Timer Mocks](https://jestjs.io/docs/en/timer-mocks).
@@ -40,6 +40,17 @@ we need to solve before being able to use Jest for all our needs.
- Unhandled Promise rejections.
- Calls to `console.warn`, including warnings from libraries like Vue.
+### Limitations of jsdom
+
+As mentioned [above](#differences-to-karma), Jest uses jsdom instead of a browser for running tests.
+This comes with a number of limitations, namely:
+
+- [No scrolling support](https://github.com/jsdom/jsdom/blob/15.1.1/lib/jsdom/browser/Window.js#L623-L625)
+- [No element sizes or positions](https://github.com/jsdom/jsdom/blob/15.1.1/lib/jsdom/living/nodes/Element-impl.js#L334-L371)
+- [No layout engine](https://github.com/jsdom/jsdom/issues/1322) in general
+
+See also the issue for [support running Jest tests in browsers](https://gitlab.com/gitlab-org/gitlab-ce/issues/58205).
+
### Debugging Jest tests
Running `yarn jest-debug` will run Jest in debug mode, allowing you to debug/inspect as described in the [Jest docs](https://jestjs.io/docs/en/troubleshooting#tests-are-failing-and-you-don-t-know-why).