From 9f46488805e86b1bc341ea1620b866016c2ce5ed Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 20 May 2020 14:34:42 +0000 Subject: Add latest changes from gitlab-org/gitlab@13-0-stable-ee --- doc/development/README.md | 28 +- doc/development/api_graphql_styleguide.md | 16 +- doc/development/api_styleguide.md | 18 +- doc/development/application_limits.md | 4 +- doc/development/architecture.md | 2 +- doc/development/auto_devops.md | 6 +- doc/development/background_migrations.md | 11 +- doc/development/changelog.md | 20 +- doc/development/cicd/img/ci_architecture.png | Bin 0 -> 102944 bytes doc/development/cicd/index.md | 75 +++ doc/development/code_review.md | 64 ++- doc/development/contributing/index.md | 100 ++-- doc/development/contributing/issue_workflow.md | 12 +- .../contributing/merge_request_workflow.md | 8 +- doc/development/contributing/style_guides.md | 2 +- doc/development/creating_enums.md | 89 +++ doc/development/dangerbot.md | 6 +- .../database/add_foreign_key_to_existing_column.md | 2 +- doc/development/database_debugging.md | 30 +- doc/development/database_review.md | 8 +- doc/development/diffs.md | 7 +- doc/development/documentation/feature_flags.md | 188 +++++++ doc/development/documentation/index.md | 112 ++-- .../site_architecture/release_process.md | 14 +- doc/development/documentation/structure.md | 10 +- doc/development/documentation/styleguide.md | 224 +++++--- doc/development/documentation/workflow.md | 382 +------------ doc/development/ee_features.md | 13 +- doc/development/elasticsearch.md | 2 +- doc/development/emails.md | 9 +- doc/development/event_tracking/backend.md | 4 +- doc/development/event_tracking/frontend.md | 4 +- doc/development/event_tracking/index.md | 4 +- doc/development/experiment_guide/index.md | 22 +- doc/development/fe_guide/accessibility.md | 13 +- doc/development/fe_guide/axios.md | 18 +- doc/development/fe_guide/design_patterns.md | 4 +- doc/development/fe_guide/droplab/droplab.md | 18 +- doc/development/fe_guide/droplab/plugins/ajax.md | 2 +- doc/development/fe_guide/droplab/plugins/filter.md | 2 +- .../fe_guide/droplab/plugins/input_setter.md | 2 +- doc/development/fe_guide/event_tracking.md | 4 +- doc/development/fe_guide/frontend_faq.md | 2 +- doc/development/fe_guide/graphql.md | 24 +- doc/development/fe_guide/icons.md | 17 +- doc/development/fe_guide/index.md | 23 +- doc/development/fe_guide/performance.md | 15 +- doc/development/fe_guide/security.md | 31 +- doc/development/fe_guide/style/javascript.md | 5 +- doc/development/fe_guide/style/scss.md | 51 +- doc/development/fe_guide/style/vue.md | 6 +- doc/development/fe_guide/tooling.md | 4 +- doc/development/fe_guide/vue.md | 216 ++++--- doc/development/fe_guide/vue3_migration.md | 124 ++++ doc/development/fe_guide/vuex.md | 85 ++- doc/development/feature_flags/controls.md | 115 ++-- doc/development/feature_flags/index.md | 8 +- doc/development/feature_flags/process.md | 3 + doc/development/file_storage.md | 26 +- doc/development/filtering_by_label.md | 4 +- doc/development/geo.md | 6 +- doc/development/geo/framework.md | 254 +++++++-- doc/development/gitaly.md | 4 +- doc/development/go_guide/index.md | 74 ++- doc/development/hash_indexes.md | 2 +- doc/development/i18n/externalization.md | 32 +- doc/development/i18n/proofreader.md | 2 +- doc/development/img/snowplow_flow.png | Bin 0 -> 16589 bytes doc/development/img/telemetry_system_overview.png | Bin 0 -> 429082 bytes doc/development/import_export.md | 75 +++ doc/development/import_project.md | 3 +- doc/development/instrumentation.md | 2 +- doc/development/integrations/example_vuln.png | Bin 0 -> 102950 bytes doc/development/integrations/secure.md | 164 ++++-- .../integrations/secure_partner_integration.md | 2 +- doc/development/interacting_components.md | 2 +- doc/development/internal_api.md | 10 +- doc/development/lfs.md | 2 +- doc/development/licensed_feature_availability.md | 4 + doc/development/licensing.md | 64 +-- doc/development/logging.md | 7 +- doc/development/mass_insert.md | 6 +- .../merge_request_performance_guidelines.md | 2 +- doc/development/migration_style_guide.md | 95 ++-- doc/development/multi_version_compatibility.md | 62 ++ doc/development/namespaces_storage_statistics.md | 12 +- .../new_fe_guide/development/accessibility.md | 23 +- .../new_fe_guide/modules/dirty_submit.md | 2 +- doc/development/newlines_styleguide.md | 2 +- doc/development/ordering_table_columns.md | 90 +-- doc/development/packages.md | 12 +- doc/development/performance.md | 4 +- doc/development/permissions.md | 6 +- doc/development/pipelines.md | 535 ++++++++++++++---- doc/development/policies.md | 4 +- doc/development/polymorphic_associations.md | 2 +- doc/development/profiling.md | 2 +- doc/development/query_recorder.md | 130 ++--- doc/development/rake_tasks.md | 58 +- doc/development/reactive_caching.md | 12 +- doc/development/repository_mirroring.md | 13 +- doc/development/scalability.md | 6 +- doc/development/secure_coding_guidelines.md | 79 ++- doc/development/shell_scripting_guide/index.md | 20 +- doc/development/sidekiq_style_guide.md | 51 +- doc/development/telemetry/index.md | 165 ++++++ doc/development/telemetry/snowplow.md | 393 +++++++++++++ doc/development/telemetry/usage_ping.md | 489 ++++++++++++++++ doc/development/testing_guide/best_practices.md | 60 +- .../testing_guide/end_to_end/beginners_guide.md | 340 +++++++++++ ...gl-devops-lifecycle-by-stage-numbers_V12_10.png | Bin 0 -> 28571 bytes doc/development/testing_guide/end_to_end/index.md | 2 +- .../testing_guide/end_to_end/page_objects.md | 47 ++ .../testing_guide/end_to_end/quick_start_guide.md | 621 --------------------- .../end_to_end/rspec_metadata_tests.md | 2 + .../testing_guide/end_to_end/style_guide.md | 1 + doc/development/testing_guide/flaky_tests.md | 2 +- doc/development/testing_guide/frontend_testing.md | 60 +- doc/development/testing_guide/index.md | 12 +- doc/development/testing_guide/review_apps.md | 41 +- doc/development/testing_guide/testing_levels.md | 56 +- doc/development/uploads.md | 2 +- doc/development/value_stream_analytics.md | 2 +- doc/development/verifying_database_capabilities.md | 4 +- doc/development/what_requires_downtime.md | 67 ++- doc/development/windows.md | 139 +++++ 126 files changed, 4397 insertions(+), 2363 deletions(-) create mode 100644 doc/development/cicd/img/ci_architecture.png create mode 100644 doc/development/documentation/feature_flags.md create mode 100644 doc/development/fe_guide/vue3_migration.md create mode 100644 doc/development/img/snowplow_flow.png create mode 100644 doc/development/img/telemetry_system_overview.png create mode 100644 doc/development/integrations/example_vuln.png create mode 100644 doc/development/multi_version_compatibility.md create mode 100644 doc/development/telemetry/index.md create mode 100644 doc/development/telemetry/snowplow.md create mode 100644 doc/development/telemetry/usage_ping.md create mode 100644 doc/development/testing_guide/end_to_end/beginners_guide.md create mode 100644 doc/development/testing_guide/end_to_end/img/gl-devops-lifecycle-by-stage-numbers_V12_10.png delete mode 100644 doc/development/testing_guide/end_to_end/quick_start_guide.md create mode 100644 doc/development/windows.md (limited to 'doc/development') diff --git a/doc/development/README.md b/doc/development/README.md index b041e48f0c2..22cc21e12b9 100644 --- a/doc/development/README.md +++ b/doc/development/README.md @@ -9,7 +9,7 @@ description: 'Learn how to contribute to GitLab.' - Set up GitLab's development environment with [GitLab Development Kit (GDK)](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/master/doc/howto/README.md) - [GitLab contributing guide](contributing/index.md) - - [Issues workflow](contributing/issue_workflow.md). For information on: + - [Issues workflow](contributing/issue_workflow.md) for more information on: - Issue tracker guidelines. - Triaging. - Labels. @@ -17,7 +17,7 @@ description: 'Learn how to contribute to GitLab.' - Issue weight. - Regression issues. - Technical or UX debt. - - [Merge requests workflow](contributing/merge_request_workflow.md). For + - [Merge requests workflow](contributing/merge_request_workflow.md) for more information on: - Merge request guidelines. - Contribution acceptance criteria. @@ -57,10 +57,8 @@ Complementary reads: - [GitLab utilities](utilities.md) - [Issuable-like Rails models](issuable-like-models.md) - [Logging](logging.md) -- [API styleguide](api_styleguide.md) Use this styleguide if you are - contributing to the API -- [GraphQL API styleguide](api_graphql_styleguide.md) Use this - styleguide if you are contributing to the [GraphQL API](../api/graphql/index.md) +- [API style guide](api_styleguide.md) for contributing to the API +- [GraphQL API style guide](api_graphql_styleguide.md) for contributing to the [GraphQL API](../api/graphql/index.md) - [Sidekiq guidelines](sidekiq_style_guide.md) for working with Sidekiq workers - [Working with Gitaly](gitaly.md) - [Manage feature flags](feature_flags/index.md) @@ -100,6 +98,7 @@ Complementary reads: - [Rails initializers](rails_initializers.md) - [Code comments](code_comments.md) - [Renaming features](renaming_features.md) +- [Windows Development on GCP](windows.md) ## Performance guides @@ -117,7 +116,7 @@ Complementary reads: ### Tooling - [Understanding EXPLAIN plans](understanding_explain_plans.md) -- [explain.depesz.com](https://explain.depesz.com/) for visualising the output +- [explain.depesz.com](https://explain.depesz.com/) for visualizing the output of `EXPLAIN` - [pgFormatter](http://sqlformat.darold.net/) a PostgreSQL SQL syntax beautifier @@ -178,7 +177,7 @@ Complementary reads: ## Documentation guides - [Writing documentation](documentation/index.md) -- [Documentation styleguide](documentation/styleguide.md) +- [Documentation style guide](documentation/styleguide.md) - [Markdown](../user/markdown.md) ## Internationalization (i18n) guides @@ -189,11 +188,11 @@ Complementary reads: ## Telemetry guides -- [Introduction](../telemetry/index.md) -- [Frontend tracking guide](../telemetry/frontend.md) -- [Backend tracking guide](../telemetry/backend.md) +- [Telemetry guide](telemetry/index.md) +- [Usage Ping guide](telemetry/usage_ping.md) +- [Snowplow guide](telemetry/snowplow.md) -## Experiment Guide +## Experiment guide - [Introduction](experiment_guide/index.md) @@ -221,9 +220,10 @@ Complementary reads: - [Defining relations between files using projections](projections.md) - [Reference processing](./reference_processing.md) +- [Compatibility with multiple versions of the application running at the same time](multi_version_compatibility.md) ## Other GitLab Development Kit (GDK) guides - [Run full Auto DevOps cycle in a GDK instance](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/master/doc/howto/auto_devops.md) -- [Using GitLab Runner with GDK](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/master/doc/howto/runner.md) -- [Using the Web IDE terminal with GDK](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/master/doc/howto/web_ide_terminal_gdk_setup.md) +- [Using GitLab Runner with the GDK](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/master/doc/howto/runner.md) +- [Using the Web IDE terminal with the GDK](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/master/doc/howto/web_ide_terminal_gdk_setup.md) diff --git a/doc/development/api_graphql_styleguide.md b/doc/development/api_graphql_styleguide.md index 036eddd7c37..6d3c0cf0eac 100644 --- a/doc/development/api_graphql_styleguide.md +++ b/doc/development/api_graphql_styleguide.md @@ -1,6 +1,6 @@ -# GraphQL API +# GraphQL API style guide -This document outlines the styleguide for GitLab's [GraphQL API](../api/graphql/index.md). +This document outlines the style guide for GitLab's [GraphQL API](../api/graphql/index.md). ## How GitLab implements GraphQL @@ -12,7 +12,7 @@ which is exposed as an API endpoint at `/api/graphql`. ## Deep Dive -In March 2019, Nick Thomas hosted a [Deep Dive](https://gitlab.com/gitlab-org/create-stage/issues/1) +In March 2019, Nick Thomas hosted a Deep Dive (GitLab team members only: `https://gitlab.com/gitlab-org/create-stage/issues/1`) on GitLab's [GraphQL API](../api/graphql/index.md) to share his domain specific knowledge with anyone who may work in this part of the code base in the future. You can find the [recording on YouTube](https://www.youtube.com/watch?v=-9L_1MWrjkg), and the slides on @@ -102,7 +102,7 @@ be `id` fields. Further reading: - [GraphQL Best Practices Guide](https://graphql.org/learn/best-practices/#nullability) -- [Using nullability in GraphQL](https://blog.apollographql.com/using-nullability-in-graphql-2254f84c4ed7) +- [Using nullability in GraphQL](https://www.apollographql.com/blog/using-nullability-in-graphql-2254f84c4ed7) ### Exposing Global IDs @@ -110,7 +110,7 @@ When exposing an `ID` field on a type, we will by default try to expose a global ID by calling `to_global_id` on the resource being rendered. -To override this behaviour, you can implement an `id` method on the +To override this behavior, you can implement an `id` method on the type for which you are exposing an ID. Please make sure that when exposing a `GraphQL::ID_TYPE` using a custom method that it is globally unique. @@ -365,7 +365,7 @@ field :token, GraphQL::STRING_TYPE, null: true, The original `description:` of the field should be maintained, and should _not_ be updated to mention the deprecation. -### Deprecation reason styleguide +### Deprecation reason style guide Where the reason for deprecation is due to the field being replaced with another field, the `reason` must be: @@ -446,7 +446,7 @@ Descriptions of fields and arguments are viewable to users through: - The [GraphiQL explorer](#graphiql). - The [static GraphQL API reference](../api/graphql/#reference). -### Description styleguide +### Description style guide To ensure consistency, the following should be followed whenever adding or updating descriptions: @@ -598,7 +598,7 @@ ID. Otherwise use a [globally unique ID](#exposing-global-ids). We already have a `FullPathLoader` that can be included in other resolvers to quickly find Projects and Namespaces which will have a -lot of dependant objects. +lot of dependent objects. To limit the amount of queries performed, we can use `BatchLoader`. diff --git a/doc/development/api_styleguide.md b/doc/development/api_styleguide.md index 78e35023766..e9a41e7ec58 100644 --- a/doc/development/api_styleguide.md +++ b/doc/development/api_styleguide.md @@ -1,6 +1,6 @@ -# API styleguide +# API style guide -This styleguide recommends best practices for API development. +This style guide recommends best practices for API development. ## Instance variables @@ -9,7 +9,7 @@ to access them as we do in Rails views), local variables are fine. ## Entities -Always use an [Entity] to present the endpoint's payload. +Always use an [Entity](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/api/entities) to present the endpoint's payload. ## Documentation @@ -29,7 +29,7 @@ for a good example): - If the endpoint is deprecated, and if so, when will it be removed - `params` for the method parameters. This acts as description, - [validation, and coercion of the parameters] + [validation, and coercion of the parameters](https://github.com/ruby-grape/grape#parameter-validation-and-coercion) A good example is as follows: @@ -100,13 +100,13 @@ Model.create(foo: params[:foo]) ## Using HTTP status helpers -For non-200 HTTP responses, use the provided helpers in `lib/api/helpers.rb` to ensure correct behaviour (`not_found!`, `no_content!` etc.). These will `throw` inside Grape and abort the execution of your endpoint. +For non-200 HTTP responses, use the provided helpers in `lib/api/helpers.rb` to ensure correct behavior (`not_found!`, `no_content!` etc.). These will `throw` inside Grape and abort the execution of your endpoint. For `DELETE` requests, you should also generally use the `destroy_conditionally!` helper which by default returns a `204 No Content` response on success, or a `412 Precondition Failed` response if the given `If-Unmodified-Since` header is out of range. This helper calls `#destroy` on the passed resource, but you can also implement a custom deletion method by passing a block. ## Using API path helpers in GitLab Rails codebase -Because we support [installing GitLab under a relative URL], one must take this +Because we support [installing GitLab under a relative URL](../install/relative_url.md), one must take this into account when using API path helpers generated by Grape. Any such API path helper usage must be in wrapped into the `expose_path` helper call. @@ -121,10 +121,6 @@ For instance: The [internal API](./internal_api.md) is documented for internal use. Please keep it up to date so we know what endpoints different components are making use of. -[Entity]: https://gitlab.com/gitlab-org/gitlab/blob/master/lib/api/entities -[validation, and coercion of the parameters]: https://github.com/ruby-grape/grape#parameter-validation-and-coercion -[installing GitLab under a relative URL]: https://docs.gitlab.com/ee/install/relative_url.html - ## Avoiding N+1 problems In order to avoid N+1 problems that are common when returning collections @@ -146,7 +142,7 @@ data](https://gitlab.com/gitlab-org/gitlab/blob/19f74903240e209736c7668132e6a5a7 for `Todo` _targets_ when returned in the Todos API. For more context and discussion about preloading see -[this merge request](https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/25711) +[this merge request](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/25711) which introduced the scope. ### Verifying with tests diff --git a/doc/development/application_limits.md b/doc/development/application_limits.md index b6e777dee15..b13e2994c52 100644 --- a/doc/development/application_limits.md +++ b/doc/development/application_limits.md @@ -11,7 +11,7 @@ coordinate with others to [document](../administration/instance_limits.md) and communicate those limits. There is a guide about [introducing application -limits](https://about.gitlab.com/handbook/product/#introducing-application-limits). +limits](https://about.gitlab.com/handbook/product/product-management/process/index.html#introducing-application-limits). ## Development @@ -90,7 +90,7 @@ project.actual_limits.exceeded?(:project_hooks, 10) #### `Limitable` concern -The [`Limitable` concern](https://gitlab.com/gitlab-org/gitlab/blob/master/ee/app/models/concerns/limitable.rb) +The [`Limitable` concern](https://gitlab.com/gitlab-org/gitlab/blob/master/app/models/concerns/limitable.rb) can be used to validate that a model does not exceed the limits. It ensures that the count of the records for the current model does not exceed the defined limit. diff --git a/doc/development/architecture.md b/doc/development/architecture.md index bbd5ca3c494..f52a5d30c1f 100644 --- a/doc/development/architecture.md +++ b/doc/development/architecture.md @@ -8,7 +8,7 @@ New versions of GitLab are released in stable branches and the master branch is For information, see the [GitLab Release Process](https://gitlab.com/gitlab-org/release/docs/-/tree/master#gitlab-release-process). -Both EE and CE require some add-on components called GitLab Shell and Gitaly. These components are available from the [GitLab Shell](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/master) and [Gitaly](https://gitlab.com/gitlab-org/gitaly/-/tree/master) repositories respectively. New versions are usually tags but staying on the master branch will give you the latest stable version. New releases are generally around the same time as GitLab CE releases with exception for informal security updates deemed critical. +Both EE and CE require some add-on components called GitLab Shell and Gitaly. These components are available from the [GitLab Shell](https://gitlab.com/gitlab-org/gitlab-shell/-/tree/master) and [Gitaly](https://gitlab.com/gitlab-org/gitaly/-/tree/master) repositories respectively. New versions are usually tags but staying on the master branch will give you the latest stable version. New releases are generally around the same time as GitLab CE releases with the exception of informal security updates deemed critical. ## Components diff --git a/doc/development/auto_devops.md b/doc/development/auto_devops.md index dba68974dd5..7d0c020ef96 100644 --- a/doc/development/auto_devops.md +++ b/doc/development/auto_devops.md @@ -1,7 +1,11 @@ # Auto DevOps development guide This document provides a development guide for contributors to -[Auto DevOps](../topics/autodevops/index.md) +[Auto DevOps](../topics/autodevops/index.md). + + +An [Auto DevOps technical walk-through](https://youtu.be/G7RTLeToz9E) +is also available on YouTube. ## Development diff --git a/doc/development/background_migrations.md b/doc/development/background_migrations.md index c28008c94b8..0747224db30 100644 --- a/doc/development/background_migrations.md +++ b/doc/development/background_migrations.md @@ -157,7 +157,7 @@ roughly be as follows: enough times to be marked as dead. 1. Remove the old column. -This may also require a bump to the [import/export version][import-export], if +This may also require a bump to the [import/export version](../user/project/settings/import_export.md), if importing a project from a prior version of GitLab requires the data to be in the new format. @@ -283,7 +283,7 @@ end The final step runs for any un-migrated rows after all of the jobs have been processed. This is in case a Sidekiq process running the background migrations received SIGKILL, leading to the jobs being lost. (See -[more reliable Sidekiq queue][reliable-sidekiq] for more information.) +[more reliable Sidekiq queue](https://gitlab.com/gitlab-org/gitlab-foss/issues/36791) for more information.) If the application does not depend on the data being 100% migrated (for instance, the data is advisory, and not mission-critical), then this final step @@ -312,7 +312,7 @@ to migrate you database down and up, which can result in other background migrations being called. That means that using `spy` test doubles with `have_received` is encouraged, instead of using regular test doubles, because your expectations defined in a `it` block can conflict with what is being -called in RSpec hooks. See [issue #35351][issue-rspec-hooks] +called in RSpec hooks. See [issue #35351](https://gitlab.com/gitlab-org/gitlab/issues/18839) for more details. ## Best practices @@ -329,8 +329,3 @@ for more details. 1. Make sure to discuss the numbers with a database specialist, the migration may add more pressure on DB than you expect (measure on staging, or ask someone to measure on production). - -[migrations-readme]: https://gitlab.com/gitlab-org/gitlab/blob/master/spec/migrations/README.md -[issue-rspec-hooks]: https://gitlab.com/gitlab-org/gitlab/issues/18839 -[reliable-sidekiq]: https://gitlab.com/gitlab-org/gitlab-foss/issues/36791 -[import-export]: ../user/project/settings/import_export.md diff --git a/doc/development/changelog.md b/doc/development/changelog.md index 2007c26403c..a0e9f9d3be3 100644 --- a/doc/development/changelog.md +++ b/doc/development/changelog.md @@ -101,20 +101,20 @@ automatically. Its simplest usage is to provide the value for `title`: -```text +```plaintext bin/changelog 'Hey DZ, I added a feature to GitLab!' ``` If you want to generate a changelog entry for GitLab EE, you will need to pass the `--ee` option: -```text +```plaintext bin/changelog --ee 'Hey DZ, I added a feature to GitLab!' ``` At this point the script would ask you to select the category of the change (mapped to the `type` field in the entry): -```text +```plaintext >> Please specify the category of your change: 1. New feature 2. Bug fix @@ -132,7 +132,7 @@ the command above on a branch called `feature/hey-dz`, it will generate a The command will output the path of the generated file and its contents: -```text +```plaintext create changelogs/unreleased/my-feature.yml --- title: Hey DZ, I added a feature to GitLab! @@ -162,7 +162,7 @@ If you use **`--amend`** and don't provide a title, it will automatically use the "subject" of the previous commit, which is the first line of the commit message: -```text +```plaintext $ git show --oneline ab88683 Added an awesome new feature to GitLab @@ -180,7 +180,7 @@ type: Use **`--force`** or **`-f`** to overwrite an existing changelog entry if it already exists. -```text +```plaintext $ bin/changelog 'Hey DZ, I added a feature to GitLab!' error changelogs/unreleased/feature-hey-dz.yml already exists! Use `--force` to overwrite. @@ -198,7 +198,7 @@ type: Use the **`--merge-request`** or **`-m`** argument to provide the `merge_request` value: -```text +```plaintext $ bin/changelog 'Hey DZ, I added a feature to GitLab!' -m 1983 create changelogs/unreleased/feature-hey-dz.yml --- @@ -213,7 +213,7 @@ type: Use the **`--dry-run`** or **`-n`** argument to prevent actually writing or committing anything: -```text +```plaintext $ bin/changelog --amend --dry-run create changelogs/unreleased/feature-hey-dz.yml --- @@ -230,7 +230,7 @@ $ ls changelogs/unreleased/ Use the **`--git-username`** or **`-u`** argument to automatically fill in the `author` value with your configured Git `user.name` value: -```text +```plaintext $ git config user.name Jane Doe @@ -247,7 +247,7 @@ type: Use the **`--type`** or **`-t`** argument to provide the `type` value: -```text +```plaintext $ bin/changelog 'Hey DZ, I added a feature to GitLab!' -t added create changelogs/unreleased/feature-hey-dz.yml --- diff --git a/doc/development/cicd/img/ci_architecture.png b/doc/development/cicd/img/ci_architecture.png new file mode 100644 index 00000000000..b888f2f07aa Binary files /dev/null and b/doc/development/cicd/img/ci_architecture.png differ diff --git a/doc/development/cicd/index.md b/doc/development/cicd/index.md index ed33eb01308..db3f58d1d22 100644 --- a/doc/development/cicd/index.md +++ b/doc/development/cicd/index.md @@ -2,6 +2,81 @@ Development guides that are specific to CI/CD are listed here. +## CI Architecture overview + +The following is a simplified diagram of the CI architecture. Some details are left out in order to focus on +the main components. + +![CI software architecture](img/ci_architecture.png) + + +On the left side we have the events that can trigger a pipeline based on various events (trigged by a user or automation): + +- A `git push` is the most common event that triggers a pipeline. +- The [Web API](../../api/pipelines.md#create-a-new-pipeline). +- A user clicking the "Run Pipeline" button in the UI. +- When a [merge request is created or updated](../../ci/merge_request_pipelines/index.md#pipelines-for-merge-requests). +- When an MR is added to a [Merge Train](../../ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md#merge-trains-premium). +- A [scheduled pipeline](../../ci/pipelines/schedules.md#pipeline-schedules). +- When project is [subscribed to an upstream project](../../ci/multi_project_pipelines.md#trigger-a-pipeline-when-an-upstream-project-is-rebuilt). +- When [Auto DevOps](../../topics/autodevops/index.md) is enabled. +- When GitHub integration is used with [external pull requests](../../ci/ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests). +- When an upstream pipeline contains a [bridge job](../../ci/yaml/README.md#trigger) which triggers a downstream pipeline. + +Triggering any of these events will invoke the [`CreatePipelineService`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/services/ci/create_pipeline_service.rb) +which takes as input event data and the user triggering it, then will attempt to create a pipeline. + +The `CreatePipelineService` relies heavily on the [`YAML Processor`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/yaml_processor.rb) +component, which is responsible for taking in a YAML blob as input and returns the abstract data structure of a +pipeline (including stages and all jobs). This component also validates the structure of the YAML while +processing it, and returns any syntax or semantic errors. The `YAML Processor` component is where we define +[all the keywords](../../ci/yaml/README.md) available to structure a pipeline. + +The `CreatePipelineService` receives the abstract data structure returned by the `YAML Processor`, +which then converts it to persisted models (pipeline, stages, jobs, etc.). After that, the pipeline is ready +to be processed. Processing a pipeline means running the jobs in order of execution (stage or DAG) +until either one of the following: + +- All expected jobs have been executed. +- Failures interrupt the pipeline execution. + +The component that processes a pipeline is [`ProcessPipelineService`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/services/ci/process_pipeline_service.rb), +which is responsible for moving all the pipeline's jobs to a completed state. When a pipeline is created, all its +jobs are initially in `created` state. This services looks at what jobs in `created` stage are eligible +to be processed based on the pipeline structure. Then it moves them into the `pending` state, which means +they can now [be picked up by a Runner](#job-scheduling). After a job has been executed it can complete +successfully or fail. Each status transition for job within a pipeline triggers this service again, which +looks for the next jobs to be transitioned towards completion. While doing that, `ProcessPipelineService` +updates the status of jobs, stages and the overall pipeline. + +On the right side of the diagram we have a list of [Runners](../../ci/runners/README.md#configuring-gitlab-runners) +connected to the GitLab instance. These can be Shared Runners, Group Runners or Project-specific Runners. +The communication between Runners and the Rails server occurs through a set of API endpoints, grouped as +the `Runner API Gateway`. + +We can register, delete and verify Runners, which also causes read/write queries to the database. After a Runner is connected, +it keeps asking for the next job to execute. This invokes the [`RegisterJobService`](https://gitlab.com/gitlab-org/gitlab/blob/master/app/services/ci/register_job_service.rb) +which will pick the next job and assign it to the Runner. At this point the job will transition to a +`running` state, which again triggers `ProcessPipelineService` due to the status change. +For more details read [Job scheduling](#job-scheduling)). + +While a job is being executed, the Runner sends logs back to the server as well any possible artifacts +that need to be stored. Also, a job may depend on artifacts from previous jobs in order to run. In this +case the Runner will download them using a dedicated API endpoint. + +Artifacts are stored in object storage, while metadata is kept in the database. An important example of artifacts +is reports (JUnit, SAST, DAST, etc.) which are parsed and rendered in the merge request. + +Job status transitions are not all automated. A user may run [manual jobs](../../ci/yaml/README.md#whenmanual), cancel a pipeline, retry +specific failed jobs or the entire pipeline. Anything that +causes a job to change status will trigger `ProcessPipelineService`, as it's responsible for +tracking the status of the entire pipeline. + +A special type of job is the [bridge job](../../ci/yaml/README.md#trigger) which is executed server-side +when transitioning to the `pending` state. This job is responsible for creating a downstream pipeline, such as +a multi-project or child pipeline. The workflow loop starts again +from the `CreatePipelineService` every time a downstream pipeline is triggered. + ## Job scheduling When a Pipeline is created all its jobs are created at once for all stages, with an initial state of `created`. This makes it possible to visualize the full content of a pipeline. diff --git a/doc/development/code_review.md b/doc/development/code_review.md index 5220f29bd60..a5ad7dc0f46 100644 --- a/doc/development/code_review.md +++ b/doc/development/code_review.md @@ -64,7 +64,7 @@ It picks reviewers and maintainers from the list at the page, with these behaviors: 1. It will not pick people whose [GitLab status](../user/profile/index.md#current-status) - contains the string 'OOO'. + contains the string 'OOO', or the emoji is `:palm_tree:` or `:beach:`. 1. [Trainee maintainers](https://about.gitlab.com/handbook/engineering/workflow/code-review/#trainee-maintainer) are three times as likely to be picked as other reviewers. 1. It always picks the same reviewers and maintainers for the same @@ -76,26 +76,36 @@ page, with these behaviors: As described in the section on the responsibility of the maintainer below, you are recommended to get your merge request approved and merged by maintainer(s) - with [domain expertise](#domain-experts). +with [domain expertise](#domain-experts). -1. If your merge request includes backend changes [^1], it must be +1. If your merge request includes backend changes (*1*), it must be **approved by a [backend maintainer](https://about.gitlab.com/handbook/engineering/projects/#gitlab_maintainers_backend)**. -1. If your merge request includes database migrations or changes to expensive queries [^2], it must be +1. If your merge request includes database migrations or changes to expensive queries (*2*), it must be **approved by a [database maintainer](https://about.gitlab.com/handbook/engineering/projects/#gitlab_maintainers_database)**. Read the [database review guidelines](database_review.md) for more details. -1. If your merge request includes frontend changes [^1], it must be +1. If your merge request includes frontend changes (*1*), it must be **approved by a [frontend maintainer](https://about.gitlab.com/handbook/engineering/projects/#gitlab_maintainers_frontend)**. -1. If your merge request includes UX changes [^1], it must be +1. If your merge request includes UX changes (*1*), it must be **approved by a [UX team member](https://about.gitlab.com/company/team/)**. -1. If your merge request includes adding a new JavaScript library [^1], it must be +1. If your merge request includes adding a new JavaScript library (*1*), it must be **approved by a [frontend lead](https://about.gitlab.com/company/team/)**. -1. If your merge request includes adding a new UI/UX paradigm [^1], it must be +1. If your merge request includes adding a new UI/UX paradigm (*1*), it must be **approved by a [UX lead](https://about.gitlab.com/company/team/)**. 1. If your merge request includes a new dependency or a filesystem 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. 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/#designated-technical-writers)**, based on the appropriate [product category](https://about.gitlab.com/handbook/product/categories/). +1. If your merge request includes Quality and non-Quality-related changes (*3*), it must be **approved + by a [Software Engineer in Test](https://about.gitlab.com/handbook/engineering/quality/#individual-contributors)**. +1. If your merge request includes _only_ Quality-related changes (*3*), it must be **approved + by a [Quality maintainer](https://about.gitlab.com/handbook/engineering/projects/#gitlab_maintainers_qa)**. + +- (*1*): Please note that specs other than JavaScript specs are considered backend code. +- (*2*): We encourage you to seek guidance from a database maintainer if your merge + request is potentially introducing expensive queries. It is most efficient to comment + on the line of code in question with the SQL queries so they can give their advice. +- (*3*): Quality-related changes include all files within the `qa` directory. #### Security requirements @@ -314,7 +324,25 @@ Before taking the decision to merge: - Set the milestone. - Consider warnings and errors from danger bot, code quality, and other reports. Unless a strong case can be made for the violation, these should be resolved - before merge. A comment must to be posted if the MR is merged with any failed job. + before merging. A comment must to be posted if the MR is merged with any failed job. +- If the MR contains both Quality and non-Quality-related changes, the MR should be merged by the relevant maintainer for user-facing changes (backend, frontend, or database) after the Quality related changes are approved by a Software Engineer in Test. + +If a merge request is fundamentally ready, but needs only trivial fixes (such as +typos), consider demonstrating a [bias for +action](https://about.gitlab.com/handbook/values/#bias-for-action) by making +those changes directly without going back to the author. You can do this by +using the [suggest changes](../user/discussions/index.md#suggest-changes) feature to apply +your own suggestions to the merge request. Note that: + +- If the changes are not straightforward, please prefer assigning the merge request back + to the author. +- **Before applying suggestions**, edit the merge request to make sure + [squash and + merge](../user/project/merge_requests/squash_and_merge.md#squash-and-merge) + is enabled, otherwise, the pipeline's Danger job will fail. + - If a merge request does not have squash and merge enabled, and it + has more than one commit, then see the note below about rewriting + commit history. When ready to merge: @@ -463,6 +491,21 @@ When a merge request author has been blocked for longer than the `Review-response` SLO, they are free to remind the reviewer through Slack or assign another reviewer. +### Customer critical merge requests + +A merge request may benefit from being considered a customer critical priority because there is a significant benefit to the business in doing so. + +Properties of customer critical merge requests: + +- The [Senior Director of Development](https://about.gitlab.com/job-families/engineering/engineering-management/#senior-director-engineering) ([@clefelhocz1](https://gitlab.com/clefelhocz1)) is the DRI for deciding if a merge request will be customer critical. +- The DRI will assign the `customer-critical-merge-request` label to the merge request. +- It is required that the reviewer(s) and maintainer(s) involved with a customer critical merge request are engaged as soon as this decision is made. +- It is required to prioritize work for those involved on a customer critical merge request so that they have the time available necessary to focus on it. +- It is required to adhere to GitLab [values](https://about.gitlab.com/handbook/values.md) and processes when working on customer critical merge requests, taking particular note of family and friends first/work second, definition of done, iteration, and release when it's ready. +- Customer critical merge requests are required to not reduce security, introduce data-loss risk, reduce availability, nor break existing functionality per the process for [prioritizing technical decisions](https://about.gitlab.com/handbook/engineering/#prioritizing-technical-decisions.md). +- On customer critical requests, it is _recommended_ that those involved _consider_ coordinating synchronously (Zoom, Slack) in addition to asynchronously (merge requests comments) if they believe this will reduce elapsed time to merge even though this _may_ sacrifice [efficiency](https://about.gitlab.com/company/culture/all-remote/asynchronous/#evaluating-efficiency.md). +- After a customer critical merge request is merged, a retrospective must be completed with the intention of reducing the frequency of future customer critical merge requests. + ## Examples How code reviews are conducted can surprise new contributors. Here are some examples of code reviews that should help to orient you as to what to expect. @@ -495,6 +538,3 @@ Largely based on the [thoughtbot code review guide](https://github.com/thoughtbo --- [Return to Development documentation](README.md) - -[^1]: Please note that specs other than JavaScript specs are considered backend code. -[^2]: We encourage you to seek guidance from a database maintainer if your merge request is potentially introducing expensive queries. It is most efficient to comment on the line of code in question with the SQL queries so they can give their advice. diff --git a/doc/development/contributing/index.md b/doc/development/contributing/index.md index 8270e52e0ab..aebff633f58 100644 --- a/doc/development/contributing/index.md +++ b/doc/development/contributing/index.md @@ -3,35 +3,40 @@ Thank you for your interest in contributing to GitLab. This guide details how to contribute to GitLab in a way that is easy for everyone. -For a first-time step-by-step guide to the contribution process, please see -["Contributing to GitLab"](https://about.gitlab.com/community/contribute/). +For a first-time step-by-step guide to the contribution process, see our +[Contributing to GitLab](https://about.gitlab.com/community/contribute/) page. -Looking for something to work on? Look for issues with the label [`Accepting merge requests`](#i-want-to-contribute). +Looking for something to work on? Look for issues with the label +[`~Accepting merge requests`](#how-to-contribute). -GitLab comes in two flavors, GitLab Community Edition (CE) our free and open -source edition, and GitLab Enterprise Edition (EE) which is our commercial -edition. Throughout this guide you will see references to CE and EE for -abbreviation. +GitLab comes in two flavors: -To get an overview of GitLab community membership including those that would be reviewing or merging your contributions, please visit [the community roles page](community_roles.md). +- GitLab Community Edition (CE), our free and open source edition. +- GitLab Enterprise Edition (EE), which is our commercial edition. + +Throughout this guide you will see references to CE and EE for abbreviation. + +To get an overview of GitLab community membership, including those that would review or merge +your contributions, visit [the community roles page](community_roles.md). If you want to know how the GitLab [core team](https://about.gitlab.com/community/core-team/) -operates please see [the GitLab contributing process](https://gitlab.com/gitlab-org/gitlab/blob/master/PROCESS.md). +operates, see [the GitLab contributing process](https://gitlab.com/gitlab-org/gitlab/blob/master/PROCESS.md). -[GitLab Inc engineers should refer to the engineering workflow document](https://about.gitlab.com/handbook/engineering/workflow/) +GitLab Inc engineers should refer to the [engineering workflow document](https://about.gitlab.com/handbook/engineering/workflow/). ## Security vulnerability disclosure -Please report suspected security vulnerabilities in private to +Report suspected security vulnerabilities in private to `support@gitlab.com`, also see the [disclosure section on the GitLab.com website](https://about.gitlab.com/security/disclosure/). -Please do **NOT** create publicly viewable issues for suspected security -vulnerabilities. + +DANGER: **Danger:** +Do **NOT** create publicly viewable issues for suspected security vulnerabilities. ## Code of conduct We want to create a welcoming environment for everyone who is interested in contributing. -Please visit our [Code of Conduct page](https://about.gitlab.com/community/contribute/code-of-conduct/) to learn more about our commitment to an open and welcoming environment. +Visit our [Code of Conduct page](https://about.gitlab.com/community/contribute/code-of-conduct/) to learn more about our commitment to an open and welcoming environment. ## Closing policy for issues and merge requests @@ -40,39 +45,56 @@ and merge requests is limited. Out of respect for our volunteers, issues and merge requests not in line with the guidelines listed in this document may be closed without notice. -Please treat our volunteers with courtesy and respect, it will go a long way +Treat our volunteers with courtesy and respect, it will go a long way towards getting your issue resolved. Issues and merge requests should be in English and contain appropriate language for audiences of all ages. -If a contributor is no longer actively working on a submitted merge request -we can decide that the merge request will be finished by one of our -[Merge request coaches](https://about.gitlab.com/company/team/) or close the merge request. We make this decision -based on how important the change is for our product vision. If a merge request -coach is going to finish the merge request we assign the -~"coach will finish" label. When a team member picks up a community contribution, +If a contributor is no longer actively working on a submitted merge request, +we can: + +- Decide that the merge request will be finished by one of our + [Merge request coaches](https://about.gitlab.com/company/team/). +- Close the merge request. + +We make this decision based on how important the change is for our product vision. If a merge +request coach is going to finish the merge request, we assign the +`~coach will finish` label. + +When a team member picks up a community contribution, we credit the original author by adding a changelog entry crediting the author and optionally include the original author on at least one of the commits within the MR. ## Helping others -Please help other GitLab users when you can. -The methods people will use to seek help can be found on the [getting help page](https://about.gitlab.com/get-help/). +Help other GitLab users when you can. +The methods people use to seek help can be found on the [getting help page](https://about.gitlab.com/get-help/). -Sign up for the mailing list, answer GitLab questions on StackOverflow or -respond in the IRC channel. +Sign up for the mailing list, answer GitLab questions on StackOverflow or respond in the IRC channel. -## I want to contribute +## How to contribute If you want to contribute to GitLab, -[issues with the `Accepting merge requests` label](issue_workflow.md#label-for-community-contributors) +[issues with the `~Accepting merge requests` label](issue_workflow.md#label-for-community-contributors) are a great place to start. + If you have any questions or need help visit [Getting Help](https://about.gitlab.com/get-help/) to -learn how to communicate with GitLab. If you're looking for a Gitter or Slack channel -please consider we favor -[asynchronous communication](https://about.gitlab.com/handbook/communication/#internal-communication) over real time communication. Thanks for your contribution! +learn how to communicate with GitLab. We have a [Gitter channel for contributors](https://gitter.im/gitlab/contributors), +however we favor +[asynchronous communication](https://about.gitlab.com/handbook/communication/#internal-communication) over real time communication. + +Thanks for your contribution! + +### GitLab Development Kit + +The GitLab Development Kit (GDK) helps contributors run a local GitLab instance with all the +required dependencies. It can be used to test changes to GitLab and related projects before raising +a Merge Request. + +For more information, see the [`gitlab-development-kit`](https://gitlab.com/gitlab-org/gitlab-development-kit) +project. ## Contribution Flow @@ -92,7 +114,7 @@ When submitting code to GitLab, you may feel that your contribution requires the When your code contains more than 500 changes, any major breaking changes, or an external library, `@mention` a maintainer in the merge request. If you are not sure who to mention, the reviewer will add one early in the merge request process. -## Issues workflow +### Issues workflow This [documentation](issue_workflow.md) outlines the current issue workflow: @@ -105,7 +127,7 @@ This [documentation](issue_workflow.md) outlines the current issue workflow: - [Technical and UX debt](issue_workflow.md#technical-and-ux-debt) - [Technical debt in follow-up issues](issue_workflow.md#technical-debt-in-follow-up-issues) -## Merge requests workflow +### Merge requests workflow This [documentation](merge_request_workflow.md) outlines the current merge request process. @@ -120,13 +142,15 @@ This [documentation](style_guides.md) outlines the current style guidelines. ## Implement design & UI elements -This [design documentation](design.md) outlines the current process for implementing -design & UI elements. +This [design documentation](design.md) outlines the current process for implementing design and UI +elements. -## Getting an Enterprise Edition License +## Contribute documentation -If you need a license for contributing to an EE-feature, please [follow these instructions](https://about.gitlab.com/handbook/marketing/community-relations/code-contributor-program/#for-contributors-to-the-gitlab-enterprise-edition-ee). +For information on how to contribute documentation, see GitLab +[documentation guidelines](../documentation/index.md). ---- +## Getting an Enterprise Edition License -[Return to Development documentation](../README.md) +If you need a license for contributing to an EE-feature, see +[relevant information](https://about.gitlab.com/handbook/marketing/community-relations/code-contributor-program/#for-contributors-to-the-gitlab-enterprise-edition-ee). diff --git a/doc/development/contributing/issue_workflow.md b/doc/development/contributing/issue_workflow.md index 13ff35ed65c..be416bf636e 100644 --- a/doc/development/contributing/issue_workflow.md +++ b/doc/development/contributing/issue_workflow.md @@ -36,7 +36,7 @@ project. To allow for asynchronous issue handling, we use [milestones](https://gitlab.com/groups/gitlab-org/-/milestones) and [labels](https://gitlab.com/gitlab-org/gitlab/-/labels). Leads and product managers handle most of the -scheduling into milestones. Labelling is a task for everyone. +scheduling into milestones. Labeling is a task for everyone. Most issues will have labels for at least one of the following: @@ -156,9 +156,9 @@ As a team needs some way to collect the work their members are planning to be as Normally there is a 1:1 relationship between Stage labels and Group labels. In the spirit of "Everyone can contribute", any issue can be picked up by any group, depending on current priorities. When picking up an issue belonging to a different -group, it should be relabelled. For example, if an issue labelled `~"devops::create"` +group, it should be relabeled. For example, if an issue labeled `~"devops::create"` and `~"group::knowledge"` is picked up by someone in the Access group of the Plan stage, -the issue should be relabelled as `~"group::access"` while keeping the original +the issue should be relabeled as `~"group::access"` while keeping the original `~"devops::create"` unchanged. We also use stage and group labels to help quantify our [throughput](https://about.gitlab.com/handbook/engineering/management/throughput/). @@ -264,7 +264,7 @@ release. There are three levels of Release Scoping labels: milestone. If these issues are not done in the current release, they will strongly be considered for the next release. - ~"Next Patch Release": Issues to put in the next patch release. Work on these - first, and add the "Pick Into X" label to the merge request, along with the + first, and add the `~"Pick into X.Y"` label to the merge request, along with the appropriate milestone. Each issue scheduled for the current milestone should be labeled ~Deliverable @@ -347,7 +347,7 @@ there is the ~"stewardship" label. This label is to be used for issues in which the stewardship of GitLab is a topic of discussion. For instance if GitLab Inc. is planning to add -features from GitLab EE to GitLab CE, related issues would be labelled with +features from GitLab EE to GitLab CE, related issues would be labeled with ~"stewardship". A recent example of this was the issue for @@ -461,7 +461,7 @@ fixing in the same MR, but not worth creating a follow-up issue for. Renaming a method that is used in many places to make its intent slightly clearer may be worth fixing, but it should not happen in the same MR, and is generally not worth the overhead of having an issue of its own. These issues would invariably -be labelled `~P4 ~S4` if we were to create them. +be labeled `~P4 ~S4` if we were to create them. More severe technical debt can have implications for development velocity. If it isn't addressed in a timely manner, the codebase becomes needlessly difficult diff --git a/doc/development/contributing/merge_request_workflow.md b/doc/development/contributing/merge_request_workflow.md index 0ac08ec2eae..a70fadfe8a9 100644 --- a/doc/development/contributing/merge_request_workflow.md +++ b/doc/development/contributing/merge_request_workflow.md @@ -17,10 +17,10 @@ wireframes of the proposed feature if it will also change the UI. Merge requests should be submitted to the appropriate project at GitLab.com, for example [GitLab](https://gitlab.com/gitlab-org/gitlab/-/merge_requests), [GitLab Runner](https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests), -[GitLab Omnibus](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests), etc. +[Omnibus GitLab](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests), etc. If you are new to GitLab development (or web development in general), see the -[I want to contribute!](index.md#i-want-to-contribute) section to get started with +[how to contribute](index.md#how-to-contribute) section to get started with some potentially easy issues. To start developing GitLab, download the [GitLab Development Kit](https://gitlab.com/gitlab-org/gitlab-development-kit) @@ -138,7 +138,7 @@ For more information see [How to Write a Git Commit Message](https://chris.beams Example commit message template that can be used on your machine that embodies the above (guide for [how to apply template](https://codeinthehole.com/tips/a-useful-template-for-commit-messages/)): -```text +```plaintext # (If applied, this commit will...) (Max 50 char) # |<---- Using a Maximum Of 50 Characters ---->| @@ -244,7 +244,7 @@ request: 1. The [CI environment preparation](https://gitlab.com/gitlab-org/gitlab/blob/master/scripts/prepare_build.sh). 1. The [Omnibus package creator](https://gitlab.com/gitlab-org/omnibus-gitlab). -### Incremental improvements +## Incremental improvements We allow engineering time to fix small problems (with or without an issue) that are incremental improvements, such as: diff --git a/doc/development/contributing/style_guides.md b/doc/development/contributing/style_guides.md index 9a0b654f47f..9e4870eadc4 100644 --- a/doc/development/contributing/style_guides.md +++ b/doc/development/contributing/style_guides.md @@ -53,7 +53,7 @@ should enable all RuboCop rules to avoid style-related discussions/nitpicking/back-and-forth in reviews. Additionally, we have a dedicated -[newlines styleguide](../newlines_styleguide.md), as well as dedicated +[newlines style guide](../newlines_styleguide.md), as well as dedicated [test-specific style guides and best practices](../testing_guide/index.md). ## Database migrations diff --git a/doc/development/creating_enums.md b/doc/development/creating_enums.md index 79ed465b121..e2ebad538d9 100644 --- a/doc/development/creating_enums.md +++ b/doc/development/creating_enums.md @@ -13,3 +13,92 @@ def change add_column :ci_job_artifacts, :file_format, :integer, limit: 2 end ``` + +## All of the key/value pairs should be defined in FOSS + +**Summary:** All enums needs to be defined in FOSS, if a model is also part of the FOSS. + +```ruby +class Model < ApplicationRecord + enum platform: { + aws: 0, + gcp: 1 # EE-only + } +end +``` + +When you add a new key/value pair to a `enum` and if it's EE-specific, you might be +tempted to organize the `enum` as the following: + +```ruby +# Define `failure_reason` enum in `Pipeline` model: +class Pipeline < ApplicationRecord + enum failure_reason: ::PipelineEnums.failure_reasons +end +``` + +```ruby +# Define key/value pairs that used in FOSS and EE: +module PipelineEnums + def self.failure_reasons + { unknown_failure: 0, config_error: 1 } + end +end + +PipelineEnums.prepend_if_ee('EE::PipelineEnums') +``` + +```ruby +# Define key/value pairs that used in EE only: +module EE + module PipelineEnums + override :failure_reasons + def failure_reasons + super.merge(activity_limit_exceeded: 2) + end + end +end +``` + +This works as-is, however, it has a couple of downside that: + +- Someone could define a key/value pair in EE that is **conflicted** with a value defined in FOSS. + e.g. Define `activity_limit_exceeded: 1` in `EE::PipelineEnums`. +- When it happens, the feature works totally different. + e.g. We cannot figure out `failure_reason` is either `config_error` or `activity_limit_exceeded`. +- When it happens, we have to ship a database migration to fix the data integrity, + which might be impossible if you cannot recover the original value. + +Also, you might observe a workaround for this concern by setting an offset in EE's values. +For example, this example sets `1000` as the offset: + +```ruby +module EE + module PipelineEnums + override :failure_reasons + def failure_reasons + super.merge(activity_limit_exceeded: 1_000, size_limit_exceeded: 1_001) + end + end +end +``` + +This looks working as a workaround, however, this approach has some donwside that: + +- Features could move from EE to FOSS or vice versa. Therefore, the offset might be mixed between FOSS and EE in the future. + e.g. When you move `activity_limit_exceeded` to FOSS, you'll see `{ unknown_failure: 0, config_error: 1, activity_limit_exceeded: 1_000 }`. +- The integer column for the `enum` is likely created [as `SMALLINT`](#creating-enums). + Therefore, you need to be careful of that the offset doesn't exceed the maximum value of 2 bytes integer. + +As a conclusion, you should define all of the key/value pairs in FOSS. +For example, you can simply write the following code in the above case: + +```ruby +class Pipeline < ApplicationRecord + enum failure_reason: { + unknown_failure: 0, + config_error: 1, + activity_limit_exceeded: 2 + } +end +``` diff --git a/doc/development/dangerbot.md b/doc/development/dangerbot.md index e090281f2bf..eda9e1e21cc 100644 --- a/doc/development/dangerbot.md +++ b/doc/development/dangerbot.md @@ -65,7 +65,7 @@ First, be aware of GitLab's [commitment to dogfooding](https://about.gitlab.com/ The code we write for Danger is GitLab-specific, and it **may not** be most appropriate place to implement functionality that addresses a need we encounter. Our users, customers, and even our own satellite projects, such as [Gitaly](https://gitlab.com/gitlab-org/gitaly), -often face similar challenges, after all. Think about how you could fulfil the +often face similar challenges, after all. Think about how you could fulfill the same need while ensuring everyone can benefit from the work, and do that instead if you can. @@ -145,7 +145,7 @@ at GitLab so far: fork. That way the danger comments will be made from CI using that API token instead. Making the variable - [masked](../ci/variables/README.md#masked-variables) will make sure + [masked](../ci/variables/README.md#mask-a-custom-variable) will make sure it doesn't show up in the job logs. The variable cannot be - [protected](../ci/variables/README.md#protected-environment-variables), + [protected](../ci/variables/README.md#protect-a-custom-variable), as it needs to be present for all feature branches. diff --git a/doc/development/database/add_foreign_key_to_existing_column.md b/doc/development/database/add_foreign_key_to_existing_column.md index e08f0a3bd1e..b8817eddeec 100644 --- a/doc/development/database/add_foreign_key_to_existing_column.md +++ b/doc/development/database/add_foreign_key_to_existing_column.md @@ -64,7 +64,7 @@ class AddNotValidForeignKeyToEmailsUser < ActiveRecord::Migration[5.2] def up # safe to use: it requires short lock on the table since we don't validate the foreign key - add_foreign_key :emails, :users, on_delete: :cascade, validate: false # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :emails, :users, on_delete: :cascade, validate: false end def down diff --git a/doc/development/database_debugging.md b/doc/development/database_debugging.md index 46cb869fea3..3753baa3c63 100644 --- a/doc/development/database_debugging.md +++ b/doc/development/database_debugging.md @@ -5,27 +5,33 @@ run into some head-banging database problems. An easy first step is to search for your error in Slack, or search for `GitLab ` with Google. ---- +Available `RAILS_ENV`: -Available `RAILS_ENV` - -- `production` (generally not for your main GDK db, but you may need this for e.g. Omnibus) -- `development` (this is your main GDK db) -- `test` (used for tests like rspec) +- `production` (generally not for your main GDK database, but you may need this for other installations such as Omnibus). +- `development` (this is your main GDK db). +- `test` (used for tests like RSpec). ## Nuke everything and start over -If you just want to delete everything and start over with an empty DB (~1 minute): +If you just want to delete everything and start over with an empty DB (approximately 1 minute): -- `bundle exec rake db:reset RAILS_ENV=development` +```shell +bundle exec rake db:reset RAILS_ENV=development +``` -If you just want to delete everything and start over with dummy data (~4 minutes). This also does `db:reset` and runs DB-specific migrations: +If you just want to delete everything and start over with dummy data (approximately 4 minutes). This +also does `db:reset` and runs DB-specific migrations: -- `bundle exec rake dev:setup RAILS_ENV=development` +```shell +bundle exec rake dev:setup RAILS_ENV=development +``` -If your test DB is giving you problems, it is safe to nuke it because it doesn't contain important data: +If your test DB is giving you problems, it is safe to nuke it because it doesn't contain important +data: -- `bundle exec rake db:reset RAILS_ENV=test` +```shell +bundle exec rake db:reset RAILS_ENV=test +``` ## Migration wrangling diff --git a/doc/development/database_review.md b/doc/development/database_review.md index f2db0ab4fd5..aa7ebb3756f 100644 --- a/doc/development/database_review.md +++ b/doc/development/database_review.md @@ -74,12 +74,12 @@ the following preparations into account. #### Preparation when adding migrations -- Ensure `db/structure.sql` is updated. +- Ensure `db/structure.sql` is updated as [documented](migration_style_guide.md#schema-changes). - Make migrations reversible by using the `change` method or include a `down` method when using `up`. - Include either a rollback procedure or describe how to rollback changes. -- Add the output of both migrating and rolling back for all migrations into the MR description - - Ensure the down method reverts the changes in `db/structure.sql` - - Update the migration output whenever you modify the migrations during the review process +- Add the output of both migrating and rolling back for all migrations into the MR description. + - Ensure the down method reverts the changes in `db/structure.sql`. + - Update the migration output whenever you modify the migrations during the review process. - Add tests for the migration in `spec/migrations` if necessary. See [Testing Rails migrations at GitLab](testing_guide/testing_migrations_guide.md) for more details. - When [high-traffic](https://gitlab.com/gitlab-org/gitlab/-/blob/master/rubocop/migration_helpers.rb#L12) tables are involved in the migration, use the [`with_lock_retries`](migration_style_guide.md#retry-mechanism-when-acquiring-database-locks) helper method. Review the relevant [examples in our documentation](migration_style_guide.md#examples) for use cases and solutions. - Ensure RuboCop checks are not disabled unless there's a valid reason to. diff --git a/doc/development/diffs.md b/doc/development/diffs.md index 3f855d90756..e065e0acc6f 100644 --- a/doc/development/diffs.md +++ b/doc/development/diffs.md @@ -8,12 +8,7 @@ Currently we rely on different sources to present diffs, these include: ## Deep Dive -In January 2019, Oswaldo Ferreira hosted a [Deep Dive] on GitLab's Diffs and Commenting on Diffs functionality to share his domain specific knowledge with anyone who may work in this part of the code base in the future. You can find the [recording on YouTube], and the slides on [Google Slides] and in [PDF]. Everything covered in this deep dive was accurate as of GitLab 11.7, and while specific details may have changed since then, it should still serve as a good introduction. - -[Deep Dive]: https://gitlab.com/gitlab-org/create-stage/issues/1 -[recording on YouTube]: https://www.youtube.com/watch?v=K6G3gMcFyek -[Google Slides]: https://docs.google.com/presentation/d/1bGutFH2AT3bxOPZuLMGl1ANWHqFnrxwQwjiwAZkF-TU/edit -[PDF]: https://gitlab.com/gitlab-org/create-stage/uploads/b5ad2f336e0afcfe0f99db0af0ccc71a/Create_Deep_Dive__Diffs_and_commenting_on_diffs.pdf +In January 2019, Oswaldo Ferreira hosted a Deep Dive (GitLab team members only: `https://gitlab.com/gitlab-org/create-stage/issues/1`) on GitLab's Diffs and Commenting on Diffs functionality to share his domain specific knowledge with anyone who may work in this part of the code base in the future. You can find the [recording on YouTube](https://www.youtube.com/watch?v=K6G3gMcFyek), and the slides on [Google Slides](https://docs.google.com/presentation/d/1bGutFH2AT3bxOPZuLMGl1ANWHqFnrxwQwjiwAZkF-TU/edit) and in [PDF](https://gitlab.com/gitlab-org/create-stage/uploads/b5ad2f336e0afcfe0f99db0af0ccc71a/). Everything covered in this deep dive was accurate as of GitLab 11.7, and while specific details may have changed since then, it should still serve as a good introduction. ## Architecture overview diff --git a/doc/development/documentation/feature_flags.md b/doc/development/documentation/feature_flags.md new file mode 100644 index 00000000000..373c5a4ee7d --- /dev/null +++ b/doc/development/documentation/feature_flags.md @@ -0,0 +1,188 @@ +--- +type: reference +description: "GitLab development - how to document features deployed behind feature flags" +--- + +# Document features deployed behind feature flags + +GitLab uses [Feature Flags](../feature_flags/index.md) to strategically roll +out the deployment of its own features. The way we document a feature behind a +feature flag depends on its state (enabled or disabled). When the state +changes, the developer who made the change **must update the documentation** +accordingly. + +## Criteria + +According to the process of [deploying GitLab features behind feature flags](../feature_flags/process.md): + +> - _By default, feature flags should be off._ +> - _Feature flags should remain in the codebase for a short period as possible to reduce the need for feature flag accounting._ +> - _In order to build a final release and present the feature for self-managed users, the feature flag should be at least defaulted to on._ + +See how to document them below, according to the state of the flag: + +- [Features disabled by default](#features-disabled-by-default). +- [Features that became enabled by default](#features-that-became-enabled-by-default). +- [Features directly enabled by default](#features-directly-enabled-by-default). +- [Features with the feature flag removed](#features-with-flag-removed). + +NOTE: **Note:** +The [`**(CORE ONLY)**`](styleguide.md#product-badges) badge or equivalent for +the feature's tier should be added to the line and heading that refers to +enabling/disabling feature flags as Admin access is required to do so, +therefore, it indicates that it cannot be done by regular users of GitLab.com. + +### Features disabled by default + +For features disabled by default, if they cannot be used yet due to lack of +completeness, or if they're still under internal evaluation (for example, for +performance implications) do **not document them**: add (or merge) the docs +only when the feature is safe and ready to use and test by end users. + +For feature flags disabled by default, if they can be used by end users: + +- Say that it's disabled by default. +- Say whether it's enabled on GitLab.com. +- Say whether it's recommended for production use. +- Document how to enable and disable it. + +For example, for a feature disabled by default, disabled on GitLab.com, and +not ready for production use: + +````markdown +# Feature Name + +> - [Introduced](link-to-issue) in GitLab 12.0. +> - It's deployed behind a feature flag, disabled by default. +> - It's disabled on GitLab.com. +> - It's not recommended for production use. +> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#anchor-to-section). **(CORE ONLY)** + +(...) + +### Enable or disable **(CORE ONLY)** + + is under development and not ready for production use. It is +deployed behind a feature flag that is **disabled by default**. +[GitLab administrators with access to the GitLab Rails console](../path/to/administration/feature_flags.md) +can enable it for your instance. + +To enable it: + +```ruby +Feature.enable(:) +``` + +To disable it: + +```ruby +Feature.disable(:) +``` +```` + +Adjust the blurb according to the state of the feature you're documenting. + +### Features that became enabled by default + +For features that became enabled by default: + +- Say that it became enabled by default. +- Say whether it's enabled on GitLab.com. +- Say whether it's recommended for production use. +- Document how to disable and enable it. + +For example, for a feature initially deployed disabled by default, that became enabled by default, that is enabled on GitLab.com, and ready for production use: + +````markdown +# Feature Name + +> - [Introduced](link-to-issue) in GitLab 12.0. +> - It was deployed behind a feature flag, disabled by default. +> - [Became enabled by default](link-to-issue) on GitLab 12.1. +> - It's enabled on GitLab.com. +> - It's recommended for production use. +> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#anchor-to-section). **(CORE ONLY)** + +(...) + +### Enable or disable **(CORE ONLY)** + + is under development but ready for production use. +It is deployed behind a feature flag that is **enabled by default**. +[GitLab administrators with access to the GitLab Rails console](..path/to/administration/feature_flags.md) +can opt to disable it for your instance. + +To disable it: + +```ruby +Feature.disable(:) +``` + +To enable it: + +```ruby +Feature.enable(:) +``` +```` + +Adjust the blurb according to the state of the feature you're documenting. + +### Features directly enabled by default + +For features enabled by default: + +- Say it's enabled by default. +- Say whether it's enabled on GitLab.com. +- Say whether it's recommended for production use. +- Document how to disable and enable it. + +For example, for a feature enabled by default, enabled on GitLab.com, and ready for production use: + +````markdown +# Feature Name + +> - [Introduced](link-to-issue) in GitLab 12.0. +> - It's deployed behind a feature flag, enabled by default. +> - It's enabled on GitLab.com. +> - It's recommended for production use. +> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#anchor-to-section). **(CORE ONLY)** + +(...) + +### Enable or disable **(CORE ONLY)** + + is under development but ready for production use. +It is deployed behind a feature flag that is **enabled by default**. +[GitLab administrators with access to the GitLab Rails console](..path/to/administration/feature_flags.md) +can opt to disable it for your instance. + +To disable it: + +```ruby +Feature.disable(:) +``` + +To enable it: + +```ruby +Feature.enable(:) +``` +```` + +Adjust the blurb according to the state of the feature you're documenting. + +### Features with flag removed + +Once the feature is ready and the flag has been removed, clean up the +documentation. Remove the feature flag mention keeping only a note that +mentions the flag in the version history notes: + +````markdown +# Feature Name + +> - [Introduced](link-to-issue) in GitLab 12.0. +> - [Feature flag removed](link-to-issue) in GitLab 12.2. + +(...) + +```` diff --git a/doc/development/documentation/index.md b/doc/development/documentation/index.md index 7a0e187b70a..256d3f5d86c 100644 --- a/doc/development/documentation/index.md +++ b/doc/development/documentation/index.md @@ -6,13 +6,14 @@ description: Learn how to contribute to GitLab Documentation. GitLab's documentation is [intended as the single source of truth (SSOT)](https://about.gitlab.com/handbook/documentation/) for information about how to configure, use, and troubleshoot GitLab. The documentation contains use cases and usage instructions for every GitLab feature, organized by product area and subject. This includes topics and workflows that span multiple GitLab features, and the use of GitLab with other applications. -In addition to this page, the following resources can help you craft and contribute documentation: +In addition to this page, the following resources can help you craft and contribute to documentation: - [Style Guide](styleguide.md) - What belongs in the docs, language guidelines, Markdown standards to follow, links, and more. - [Structure and template](structure.md) - Learn the typical parts of a doc page and how to write each one. - [Documentation process](workflow.md). - [Markdown Guide](../../user/markdown.md) - A reference for all Markdown syntax supported by GitLab. - [Site architecture](site_architecture/index.md) - How is built. +- [Documentation for feature flags](feature_flags.md) - How to write and update documentation for GitLab features deployed behind feature flags. ## Source files and rendered web locations @@ -51,7 +52,7 @@ docs-only merge requests using the following guide: [Contributions to GitLab docs](workflow.md) are welcome from the entire GitLab community. -To ensure that GitLab docs are current, there are special processes and responsibilities for all [feature changes](feature-change-workflow.md)—i.e. development work that impacts the appearance, usage, or administration of a feature. +To ensure that GitLab docs are current, there are special processes and responsibilities for all [feature changes](feature-change-workflow.md), that is development work that impacts the appearance, usage, or administration of a feature. However, anyone can contribute [documentation improvements](improvement-workflow.md) that are not associated with a feature change. For example, adding a new doc on how to accomplish a use case that's already possible with GitLab or with third-party tools and GitLab. @@ -76,13 +77,24 @@ whether the move is necessary), and ensure that a technical writer reviews this change prior to merging. If you indeed need to change a document's location, do not remove the old -document, but instead replace all of its content with a new line: +document, but instead replace all of its content with the following: -```md -This document was moved to [another location](path/to/new_doc.md). +```markdown +--- +redirect_to: '../path/to/file/index.md' +--- + +This document was moved to [another location](../path/to/file/index.md). ``` -where `path/to/new_doc.md` is the relative path to the root directory `doc/`. +Where `../path/to/file/index.md` is usually the relative path to the old document. + +The `redirect_to` variable supports both full and relative URLs, for example +`https://docs.gitlab.com/ee/path/to/file.html`, `../path/to/file.html`, `path/to/file.md`. +It ensures that the redirect will work for and any `*.md` paths +will be compiled to `*.html`. +The new line underneath the front matter informs the user that the document +changed location and is useful for someone that browses that file from the repository. For example, if you move `doc/workflow/lfs/index.md` to `doc/administration/lfs.md`, then the steps would be: @@ -90,13 +102,17 @@ For example, if you move `doc/workflow/lfs/index.md` to 1. Copy `doc/workflow/lfs/index.md` to `doc/administration/lfs.md` 1. Replace the contents of `doc/workflow/lfs/index.md` with: - ```md + ```markdown + --- + redirect_to: '../../administration/lfs.md' + --- + This document was moved to [another location](../../administration/lfs.md). ``` 1. Find and replace any occurrences of the old location with the new one. - A quick way to find them is to use `git grep`. First go to the root directory - where you cloned the `gitlab` repository and then do: + A quick way to find them is to use `git grep` on the repository you changed + the file from: ```shell git grep -n "workflow/lfs/lfs_administration" @@ -123,24 +139,6 @@ Things to note: built-in help page, that's why we omit it in `git grep`. - Use the checklist on the "Change documentation location" MR description template. -### Alternative redirection method - -You can also replace the content -of the old file with a frontmatter containing a redirect link: - -```yaml ---- -redirect_to: '../path/to/file/README.md' ---- -``` - -It supports both full and relative URLs, e.g. `https://docs.gitlab.com/ee/path/to/file.html`, `../path/to/file.html`, `path/to/file.md`. Note that any `*.md` paths will be compiled to `*.html`. - -NOTE: **Note:** -This redirection method will not provide a redirect fallback on GitLab `/help`. When using -it, make sure to add a link to the new page on the doc, otherwise it's a dead end for users that -land on the doc via `/help`. - ### Redirections for pages with Disqus comments If the documentation page being relocated already has Disqus comments, @@ -150,12 +148,12 @@ Disqus uses an identifier per page, and for , the page is configured to be the page URL. Therefore, when we change the document location, we need to preserve the old URL as the same Disqus identifier. -To do that, add to the frontmatter the variable `disqus_identifier`, -using the old URL as value. For example, let's say I moved the document +To do that, add to the front matter the variable `disqus_identifier`, +using the old URL as value. For example, let's say we moved the document available under `https://docs.gitlab.com/my-old-location/README.html` to a new location, `https://docs.gitlab.com/my-new-location/index.html`. -Into the **new document** frontmatter add the following: +Into the **new document** front matter, we add the following: ```yaml --- @@ -173,8 +171,8 @@ Before getting started, make sure you read the introductory section [documentation workflow](workflow.md). - Use the current [merge request description template](https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab/merge_request_templates/Documentation.md) -- Label the MR `Documentation` -- Assign the correct milestone (see note below) +- Label the MR `Documentation` (can only be done by people with `developer` access, for example, GitLab team members) +- Assign the correct milestone per note below (can only be done by people with `developer` access, for example, GitLab team members) Documentation will be merged if it is an improvement on existing content, represents a good-faith effort to follow the template and style standards, @@ -185,7 +183,7 @@ in a follow-up MR or issue. NOTE: **Note:** If the release version you want to add the documentation to has already been -frozen or released, use the label `Pick into X.Y` to get it merged into +frozen or released, use the label `~"Pick into X.Y"` to get it merged into the correct release. Avoid picking into a past release as much as you can, as it increases the work of the release managers. @@ -205,7 +203,7 @@ to the MR. For example, let's say your merge request has a milestone set to 11.3, which will be released on 2018-09-22. If it gets merged on 2018-09-15, it will be available online on 2018-09-15, but, as the feature freeze date has passed, if -the MR does not have a "pick into 11.3" label, the milestone has to be changed +the MR does not have a `~"Pick into 11.3"` label, the milestone has to be changed to 11.4 and it will be shipped with all GitLab packages only on 2018-10-22, with GitLab 11.4. Meaning, it will only be available under `/help` from GitLab 11.4 onward, but available on on the same day it was merged. @@ -277,7 +275,7 @@ You can combine one or more of the following: ### GitLab `/help` tests -Several [rspec tests](https://gitlab.com/gitlab-org/gitlab/blob/master/spec/features/help_pages_spec.rb) +Several [RSpec tests](https://gitlab.com/gitlab-org/gitlab/blob/master/spec/features/help_pages_spec.rb) are run to ensure GitLab documentation renders and works correctly. In particular, that [main docs landing page](../../README.md) will work correctly from `/help`. For example, [GitLab.com's `/help`](https://gitlab.com/help). @@ -300,8 +298,8 @@ To preview your changes to documentation locally, follow this The live preview is currently enabled for the following projects: -- -- +- [`gitlab`](https://gitlab.com/gitlab-org/gitlab) +- [`gitlab-runner`](https://gitlab.com/gitlab-org/gitlab-runner) If your merge request has docs changes, you can use the manual `review-docs-deploy` job to deploy the docs review app for your merge request. @@ -407,8 +405,6 @@ merge request with new or changed docs is submitted, are: - [`internal_anchors`](https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab/ci/docs.gitlab-ci.yml#L69) checks that all internal anchors (ex: `[link](../index.md#internal_anchor)`) are valid. -- If any code or the `doc/README.md` file is changed, a full pipeline will run, which - runs tests for [`/help`](#gitlab-help-tests). ### Running tests @@ -489,14 +485,14 @@ markdownlint can be used [on the command line](https://github.com/igorshubovych/ either on a single Markdown file or on all Markdown files in a project. For example, to run markdownlint on all documentation in the [`gitlab` project](https://gitlab.com/gitlab-org/gitlab), run the following commands from within your `gitlab` project root directory, which will -automatically detect the [`.markdownlint.json`](#markdownlint-configuration) config +automatically detect the [`.markdownlint.json`](#markdownlint-configuration) configuration file in the root of the project, and test all files in `/doc` and its subdirectories: ```shell markdownlint 'doc/**/*.md' ``` -If you wish to use a different config file, use the `-c` flag: +If you wish to use a different configuration file, use the `-c` flag: ```shell markdownlint -c 'doc/**/*.md' @@ -510,7 +506,7 @@ such as: - [Atom](https://atom.io/packages/linter-node-markdownlint) It is best to use the [same configuration file](#markdownlint-configuration) as what -is in use in the four repos that are the sources for . Each +is in use in the four repositories that are the sources for . Each plugin/extension has different requirements regarding the configuration file, which is explained in each editor's docs. @@ -519,12 +515,12 @@ is explained in each editor's docs. Each formatting issue that markdownlint checks has an associated [rule](https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md#rules). These rules are configured in the `.markdownlint.json` files located in the root of -four repos that are the sources for : +four repositories that are the sources for : -- -- -- -- +- [`gitlab`](https://gitlab.com/gitlab-org/gitlab/blob/master/.markdownlint.json) +- [`gitlab-runner`](https://gitlab.com/gitlab-org/gitlab-runner/blob/master/.markdownlint.json) +- [`omnibus-gitlab`](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/.markdownlint.json) +- [`charts`](https://gitlab.com/charts/gitlab/blob/master/.markdownlint.json) By default all rules are enabled, so the configuration file is used to disable unwanted rules, and also to configure optional parameters for enabled rules as needed. You can @@ -534,7 +530,7 @@ on or off when markdownlint was enabled on the docs. #### Vale -[Vale](https://errata-ai.github.io/vale/) is a grammar, style, and word usage linter +[Vale](https://errata-ai.gitbook.io/vale/) 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 the [GitLab repository](https://gitlab.com/gitlab-org/gitlab). @@ -554,10 +550,28 @@ You can also [configure the text editor of your choice](https://errata-ai.github.io/vale/#local-use-by-a-single-writer) to display the results. +Vale's test results [are displayed](#testing) in CI pipelines. + +##### Disable a Vale test + +You can disable a specific Vale linting rule or all Vale linting rules for any portion of a document: + +- To disable a specific rule, add a `` tag + before the text, and a `` tag after the text, + replacing `rulename` with the filename of a test in the [GitLab styles](https://gitlab.com/gitlab-org/gitlab/-/tree/master/doc/.linting/vale/styles/gitlab) directory. +- To disable all Vale linting rules, add a `` tag before the text, + and a `` tag after the text. + +Whenever possible, exclude only the problematic rule and line(s). +In some cases, such as list items, you may need to disable linting for the entire +list until ["Ignore comments are not honored in a Markdown file"](https://github.com/errata-ai/vale/issues/175) is resolved. + +For more information, see [Vale's documentation](https://errata-ai.gitbook.io/vale/getting-started/markup#markup-based-configuration). + ## Danger Bot GitLab uses [Danger](https://github.com/danger/danger) for some elements in code review. For docs changes in merge requests, whenever a change to files under `/doc` is made, Danger Bot leaves a comment with further instructions about the documentation -process. This is configured in the Dangerfile in the GitLab repo under +process. This is configured in the `Dangerfile` in the GitLab repository under [/danger/documentation/](https://gitlab.com/gitlab-org/gitlab/tree/master/danger/documentation). diff --git a/doc/development/documentation/site_architecture/release_process.md b/doc/development/documentation/site_architecture/release_process.md index a8da565124b..13d6540fa35 100644 --- a/doc/development/documentation/site_architecture/release_process.md +++ b/doc/development/documentation/site_architecture/release_process.md @@ -20,7 +20,7 @@ Although build images are built automatically via GitLab CI/CD, you can build and tag all tooling images locally: 1. Make sure you have [Docker installed](https://docs.docker.com/install/). -1. Make sure you're on the `dockerfiles/` directory of the `gitlab-docs` repo. +1. Make sure you're in the `dockerfiles/` directory of the `gitlab-docs` repository. 1. Build the images: ```shell @@ -46,7 +46,7 @@ products, we need to add a 1. Check that there is a [stable branch created](https://gitlab.com/gitlab-org/charts/gitlab/-/branches) for the new chart version. If you're unsure or can't find it, drop a line in the `#g_delivery` channel. -1. Make sure you're on the root path of the `gitlab-docs` repo. +1. Make sure you're in the root path of the `gitlab-docs` repository. 1. Open `content/_data/chart_versions.yaml` and add the new stable branch version using the version mapping. Note that only the `major.minor` version is needed. 1. Create a new merge request and merge it. @@ -61,14 +61,14 @@ this first step. The single docs version must be created before the release merge request, but this needs to happen when the stable branches for all products have been created. -1. Make sure you're on the root path of the `gitlab-docs` repo. +1. Make sure you're in the root path of the `gitlab-docs` repository. 1. Make sure your `master` is updated: ```shell git pull origin master ``` -1. Run the raketask to create the single version: +1. Run the Rake task to create the single version: ```shell ./bin/rake "release:single[12.0]" @@ -109,7 +109,7 @@ Visit `http://localhost:4000/12.0/` to see if everything works correctly. Now it's time to create the monthly release merge request that adds the new version and rotates the old one: -1. Make sure you're on the root path of the `gitlab-docs` repo. +1. Make sure you're in the root path of the `gitlab-docs` repository. 1. Create a branch `release-X-Y`: ```shell @@ -158,10 +158,10 @@ the dropdown are included in the unmerged `release-X-Y` branch. The content of `content/_data/versions.yaml` needs to change for all online versions: -1. Run the raketask that will create all the respective merge requests needed to +1. Run the Rake task that will create all the respective merge requests needed to update the dropdowns and will be set to automatically be merged when their pipelines succeed. The `release-X-Y` branch needs to be present locally, - otherwise the raketask will fail: + otherwise the Rake task will fail: ```shell ./bin/rake release:dropdowns diff --git a/doc/development/documentation/structure.md b/doc/development/documentation/structure.md index 84ba47eba78..d19383bee27 100644 --- a/doc/development/documentation/structure.md +++ b/doc/development/documentation/structure.md @@ -20,7 +20,7 @@ Every feature or use case document should include the following content in the f with exceptions and details noted below and in the template included on this page. - **Title**: Top-level heading with the feature name, or a use case name, which would start with - a verb, like Configuring, Enabling, etc. + a verb, like Configuring, Enabling, and so on. - **Introduction**: A couple sentences about the subject matter and what's to be found on this page. Describe what the feature or topic is, what it does, and in what context it should be used. There is no need to add a title called "Introduction" or "Overview," because people rarely @@ -41,7 +41,7 @@ and other logical divisions such as pre- and post-deployment steps. To start a new document, respect the file tree and file name guidelines, as well as the style guidelines. Use the following template: -```md +```markdown @@ -130,7 +130,7 @@ Notes: ## Help and feedback section The "help and feedback" section (introduced by [!319](https://gitlab.com/gitlab-org/gitlab-docs/-/merge_requests/319)) displayed at the end of each document -can be omitted from the doc by adding a key into the its frontmatter: +can be omitted from the doc by adding a key into the its front matter: ```yaml --- @@ -148,7 +148,7 @@ We also have integrated the docs site with Disqus (introduced by allowing our users to post comments. To omit only the comments from the feedback section, use the following -key on the frontmatter: +key on the front matter: ```yaml --- @@ -159,7 +159,7 @@ comments: false We are only hiding comments in main index pages, such as [the main documentation index](../../README.md), since its content is too broad to comment on. Before omitting Disqus, you must check with a technical writer. -Note that once `feedback: false` is added to the frontmatter, it will automatically omit +Note that once `feedback: false` is added to the front matter, it will automatically omit Disqus, therefore, don't add both keys to the same document. The click events in the feedback section are tracked with Google Tag Manager. The diff --git a/doc/development/documentation/styleguide.md b/doc/development/documentation/styleguide.md index 0007f6d6e2f..6d146051e13 100644 --- a/doc/development/documentation/styleguide.md +++ b/doc/development/documentation/styleguide.md @@ -17,9 +17,9 @@ that apply to all GitLab content, not just documentation. ### Why a single source of truth -The documentation of GitLab products and features is the SSOT for all information related to implementation, usage, and troubleshooting. It evolves continually, in keeping with new products and features, and with improvements for clarity, accuracy, and completeness. +The documentation of GitLab products and features is the SSOT for all information related to implementation, usage, and troubleshooting. It evolves continuously, in keeping with new products and features, and with improvements for clarity, accuracy, and completeness. -This policy prevents information silos, ensuring that it remains easy to find information about GitLab products. +This policy prevents information silos, making it easier to find information about GitLab products. It also informs decisions about the kinds of content we include in our documentation. @@ -46,12 +46,12 @@ In the software industry, it is a best practice to organize documentation in dif 1. Explanation 1. Reference (for example, a glossary) -At GitLab, we have so many product changes in our monthly releases that we can't afford to continually update multiple types of information. +At GitLab, we have so many product changes in our monthly releases that we can't afford to continuously update multiple types of information. If we have multiple types, the information will become outdated. Therefore, we have a [single template](structure.md) for documentation. We currently do not distinguish specific document types, although we are open to reconsidering this policy once the documentation has reached a future stage of maturity and quality. If you are reading this, then despite our -continual improvement efforts, that point hasn't been reached. +continuous improvement efforts, that point hasn't been reached. ### Link instead of summarize @@ -61,7 +61,7 @@ Instead, link to the SSOT and explain why it is important to consume the informa ### Organize by topic, not by type -Beyond top-level audience-type folders (for example, `administration`), we organize content by topic, not by type, so that it can be located as easily as possible within the single-source-of-truth (SSOT) section for the subject matter. +Beyond top-level audience-type folders (for example, `administration`), we organize content by topic, not by type, so it can be located as easily as possible within the single-source-of-truth (SSOT) section for the subject matter. For example, do not create groupings of similar media types. For example: @@ -76,7 +76,7 @@ and cross-link between any related content. ### Docs-first methodology -We employ a **docs-first methodology** to help ensure that the docs remain a complete and trusted resource, and to make communicating about the use of GitLab more efficient. +We employ a **docs-first methodology** to help ensure the docs remain a complete and trusted resource, and to make communicating about the use of GitLab more efficient. - If the answer to a question exists in documentation, share the link to the docs instead of rephrasing the information. - When you encounter new information not available in GitLab’s documentation (for example, when working on a support case or testing a feature), your first step should be to create a merge request (MR) to add this information to the docs. You can then share the MR in order to communicate this information. @@ -129,13 +129,13 @@ correctly, but is not the current standard for GitLab documentation). A rule that could cause confusion is `MD044/proper-names`, as it might not be immediately clear what caused markdownlint to fail, or how to correct the failure. This rule checks a list of known words, listed in the `.markdownlint.json` file in each project, -to verify that proper capitalization and backticks are used. Words in backticks will +to verify proper use of capitalization and backticks. Words in backticks will be ignored by markdownlint. In general, product names should follow the exact capitalization of the official names of the products, protocols, and so on. -Some examples that will fail if incorrect capitalization is used: +Some examples fail if incorrect capitalization is used: - MinIO (needs capital `IO`) - NGINX (needs all capitals) @@ -248,10 +248,6 @@ GitLab documentation should be clear and easy to understand. - Be clear, concise, and stick to the goal of the documentation. - Write in US English with US grammar. - Use inclusive language. -- Avoid jargon. -- Avoid uncommon words. -- Don't write in the first person singular. - - Instead of "I" or "me," use "we," "you," "us," or "one." ### Point of view @@ -285,21 +281,53 @@ because it’s friendly and easy to understand. Some features are also objects. For example, "GitLab's Merge Requests support X" and "Create a new merge request for Z." +### Language to avoid + +When creating documentation, limit or avoid the use of the following verb +tenses, words, and phrases: + +- Avoid jargon. +- Avoid uncommon words. +- Don't write in the first person singular. + - Instead of "I" or "me," use "we," "you," "us," or "one." + - When possible, stay user focused by writing in the second person ("you" or + the imperative). +- Don't overuse "that". In many cases, you can remove "that" from a sentence + and improve readability. - Avoid use of the future tense: - - Instead of "after you execute this command, GitLab will display the result", use "after you execute this command, GitLab displays the result". - - Only use the future tense to convey when the action or result will actually occur at a future time. -- Do not use slashes to clump different words together or as a replacement for the word "or": - - Instead of "and/or," consider using "or," or use another sensible construction. - - Other examples include "clone/fetch," author/assignee," and "namespace/repository name." Break apart any such instances in an appropriate way. - - Exceptions to this rule include commonly accepted technical terms such as CI/CD, TCP/IP, and so on. -- Do not use "may" and "might" interchangeably: - - Use "might" to indicate the probability of something occurring. "If you skip this step, the import process might fail." - - Use "may" to indicate giving permission for someone to do something, or consider using "can" instead. "You may select either option on this screen." Or, "you can select either option on this screen." -- We discourage use of Latin abbreviations, such as "e.g.," "i.e.," or "etc.," -as even native users of English might misunderstand them. + - Instead of "after you execute this command, GitLab will display the + result", use "after you execute this command, GitLab displays the result". + - Only use the future tense to convey when the action or result will actually + occur at a future time. +- Don't use slashes to clump different words together or as a replacement for + the word "or": + - Instead of "and/or," consider using "or," or use another sensible + construction. + - Other examples include "clone/fetch," author/assignee," and + "namespace/repository name." Break apart any such instances in an + appropriate way. + - Exceptions to this rule include commonly accepted technical terms, such as + CI/CD and TCP/IP. +- + We discourage use of Latin abbreviations, such as "e.g.," "i.e.," or "etc.," + as even native users of English might misunderstand them. - Instead of "i.e.," use "that is." - Instead of "e.g.," use "for example," "such as," "for instance," or "like." - - Instead of "etc.," either use "and so on" or consider editing it out, since it can be vague. + - Instead of "etc.," either use "and so on" or consider editing it out, since + it can be vague. + +- Avoid using the word *currently* when talking about the product or its + features. The documentation describes the product as it is, and not as it + will be at some indeterminate point in the future. + +### Word usage clarifications + +- Don't use "may" and "might" interchangeably: + - Use "might" to indicate the probability of something occurring. "If you + skip this step, the import process might fail." + - Use "may" to indicate giving permission for someone to do something, or + consider using "can" instead. "You may select either option on this + screen." Or, "You can select either option on this screen." ### Contractions @@ -353,6 +381,8 @@ as even native users of English might misunderstand them. | Requests to localhost are not allowed | Requests to localhost aren't allowed | | Specified URL cannot be used | Specified URL can't be used | + + ## Text - [Write in Markdown](#markdown). @@ -360,7 +390,7 @@ as even native users of English might misunderstand them. - Insert an empty line for new paragraphs. - Insert an empty line between different markups (for example, after every paragraph, header, list, and so on). Example: - ```md + ```markdown ## Header Paragraph. @@ -417,7 +447,7 @@ Only use ordered lists when their items describe a sequence of steps to follow. Do: -```md +```markdown These are the steps to do something: 1. First, do the first step. @@ -427,7 +457,7 @@ These are the steps to do something: Don't: -```md +```markdown This is a list of available features: 1. Feature 1 @@ -453,7 +483,7 @@ This is a list of available features: all with a period. - Separate list items from explanatory text with a colon (`:`). For example: - ```md + ```markdown The list is as follows: - First item: this explains the first item. @@ -511,7 +541,7 @@ In unordered lists (using `-`), this means two spaces for each level of indentat - Unordered list item 3 - ```text + ```plaintext a codeblock that will next inside list item 3 ``` @@ -534,7 +564,7 @@ For ordered lists, use three spaces for each level of indentation: 1. Ordered list item 3 - ```text + ```plaintext a codeblock that will next inside list item 3 ``` @@ -560,9 +590,47 @@ to mix types, that is also possible, as long as you don't mix items at the same - Unordered list item three. ``` +## Tables + +Tables should be used to describe complex information in a straightforward +manner. Note that in many cases, an unordered list is sufficient to describe a +list of items with a single, simple description per item. But, if you have data +that is best described by a matrix, tables are the best choice for use. + +### Creation guidelines + +Due to accessibility and scanability requirements, tables should not have any +empty cells. If there is no otherwise meaningful value for a cell, consider entering +*N/A* (for 'not applicable') or *none*. + +To help tables be easier to maintain, consider adding additional spaces to the +column widths to make them consistent. For example: + +```markdown +| App name | Description | Requirements | +|:---------|:---------------------|:---------------| +| App 1 | Description text 1. | Requirements 1 | +| App 2 | Description text 2. | None | +``` + +Consider installing a plugin or extension in your editor for formatting tables: + +- [Markdown Table Prettifier](https://marketplace.visualstudio.com/items?itemName=darkriszty.markdown-table-prettify) for Visual Studio Code +- [Markdown Table Formatter](https://packagecontrol.io/packages/Markdown%20Table%20Formatter) for Sublime Text +- [Markdown Table Formatter](https://atom.io/packages/markdown-table-formatter) for Atom + +### Feature tables + +When creating tables of lists of features (such as whether or not features are +available to certain roles on the [Permissions](../../user/permissions.md#project-members-permissions) +page), use the following phrases (based on the SVG icons): + +- *No*: **{dotted-circle}** No +- *Yes*: **{check-circle}** Yes + ## Quotes -Valid for Markdown content only, not for frontmatter entries: +Valid for Markdown content only, not for front matter entries: - Standard quotes: double quotes (`"`). Example: "This is wrapped in double quotes". - Quote within a quote: double quotes (`"`) wrap single quotes (`'`). Example: "I am 'quoting' something within a quote". @@ -724,15 +792,17 @@ Instead: Example: -```md +```markdown For more information, see the [confidential issue](../../user/project/issues/confidential_issues.md) `https://gitlab.com/gitlab-org/gitlab-foss/issues/`. ``` ### Link to specific lines of code -When linking to specifics lines within a file, link to a commit instead of to the branch. +When linking to specific lines within a file, link to a commit instead of to the branch. Lines of code change through time, therefore, linking to a line by using the commit link -ensures the user lands on the line you're referring to. +ensures the user lands on the line you're referring to. The **Permalink** button, which is +available when viewing a file within a project, makes it easy to generate a link to the +most recent commit of the given file. - **Do:** `[link to line 3](https://gitlab.com/gitlab-org/gitlab/-/blob/11f17c56d8b7f0b752562d78a4298a3a95b5ce66/.gitlab/issue_templates/Feature%20proposal.md#L3)` - **Don't:** `[link to line 3](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/issue_templates/Feature%20proposal.md#L3).` @@ -801,7 +871,7 @@ known tool is [`pngquant`](https://pngquant.org/), which is cross-platform and open source. Install it by visiting the official website and following the instructions for your OS. -GitLab has a [raketask](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/tasks/pngquant.rake) +GitLab has a [Rake task](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/tasks/pngquant.rake) that you can use to automate the process. In the root directory of your local copy of `https://gitlab.com/gitlab-org/gitlab`, run in a terminal: @@ -838,7 +908,7 @@ Do not upload videos to the product repositories. [Link](#link-to-video) or [emb 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 +```markdown For an overview, see [Video Title](link-to-video). ``` @@ -965,7 +1035,7 @@ of language classes available. | `ruby` | Alias: `rb`. | | `shell` | Aliases: `bash` or `sh`. | | `sql` | | -| `toml` | Runner configuration examples, and other toml formatted configuration files. | +| `toml` | Runner configuration examples, and other TOML-formatted configuration files. | | `typescript` | Alias: `ts`. | | `xml` | | | `yaml` | Alias: `yml`. | @@ -1012,7 +1082,7 @@ This will ensure that the source Markdown remains readable and should help with The following are examples of source Markdown for menu items with their published output: -```md +```markdown 1. Go to **{home}** **Project overview > Details** 1. Go to **{doc-text}** **Repository > Branches** 1. Go to **{issues}** **Issues > List** @@ -1073,7 +1143,7 @@ of users. Weigh the costs of distracting users to whom the content is not relevant against the cost of users missing the content if it were not expressed as a note. -```md +```markdown NOTE: **Note:** This is something to note. ``` @@ -1085,7 +1155,7 @@ This is something to note. ### Tip -```md +```markdown TIP: **Tip:** This is a tip. ``` @@ -1097,7 +1167,7 @@ This is a tip. ### Caution -```md +```markdown CAUTION: **Caution:** This is something to be cautious about. ``` @@ -1109,7 +1179,7 @@ This is something to be cautious about. ### Danger -```md +```markdown DANGER: **Danger:** This is a breaking change, a bug, or something very important to note. ``` @@ -1123,7 +1193,7 @@ This is a breaking change, a bug, or something very important to note. For highlighting a text within a blue blockquote, use this format: -```md +```markdown > This is a blockquote. ``` @@ -1135,7 +1205,7 @@ If the text spans across multiple lines it's OK to split the line. For multiple paragraphs, use the symbol `>` before every line: -```md +```markdown > This is the first paragraph. > > This is the second paragraph. @@ -1216,7 +1286,7 @@ a helpful link back to how the feature was developed. to the following should be added immediately below the heading as a blockquote: - `> Introduced in GitLab 11.3.`. -- Whenever possible, version text should have a link to the issue, merge request, or epic that introduced the feature. +- Whenever possible, version text should have a link to the _completed_ issue, merge request, or epic that introduced the feature. An issue is preferred over a merge request, and a merge request is preferred over an epic. For example: - `> [Introduced]() in GitLab 11.3.`. @@ -1228,21 +1298,35 @@ a helpful link back to how the feature was developed. - If listing information for multiple version as a feature evolves, add the information to a block-quoted bullet list. For example: - ```md + ```markdown > - [Introduced]() in GitLab 11.3. > - Enabled by default in GitLab 11.4. ``` - If a feature is moved to another tier: - ```md + ```markdown > - [Introduced]() in [GitLab Premium](https://about.gitlab.com/pricing/) 11.5. > - [Moved]() to [GitLab Starter](https://about.gitlab.com/pricing/) in 11.8. > - [Moved]() to GitLab Core in 12.0. ``` NOTE: **Note:** -Version text must be on its own line and surounded by blank lines to render correctly. +Version text must be on its own line and surrounded by blank lines to render correctly. + +### Versions in the past or future + +When describing functionality available in past or future versions, use: + +- **Earlier**, and not **older** or **before**. +- **Later**, and not **newer** or **after**. + +For example: + +- Available in GitLab 12.3 and earlier. +- Available in GitLab 12.4 and later. +- If using GitLab 11.4 or earlier, ... +- If using GitLab 10.6 or later, ... ### Importance of referencing GitLab versions and tiers @@ -1333,7 +1417,7 @@ avoid duplication, link to the special document that can be found in [`doc/administration/restart_gitlab.md`](../../administration/restart_gitlab.md). Usually the text will read like: -```md +```markdown Save the file and [reconfigure GitLab](../../administration/restart_gitlab.md) for the changes to take effect. ``` @@ -1369,7 +1453,7 @@ When there is a list of steps to perform, usually that entails editing the configuration file and reconfiguring/restarting GitLab. In such case, follow the style below as a guide: -````md +````markdown **For Omnibus installations** 1. Edit `/etc/gitlab/gitlab.rb`: @@ -1416,38 +1500,8 @@ can facilitate this by making sure the troubleshooting content addresses: ## Feature flags -Sometimes features are shipped with feature flags, either: - -- On by default, but providing the option to turn the feature off. -- Off by default, but providing the option to turn the feature on. - -When documenting feature flags for a feature, include: - -- Why a feature flag is necessary. Some of the reasons are - [outlined in the handbook](https://about.gitlab.com/handbook/product/#alpha-beta-ga). -- That administrative access is required to make a feature flag change. -- What to ask for when requesting a change to a feature flag's state. - -NOTE: **Note:** -The [Product Manager for the relevant group](https://about.gitlab.com/handbook/product/categories/#devops-stages) -must review and approve the addition or removal of any mentions of using feature flags before the doc change is merged. - -The following is sample text for adding feature flag documentation for a feature that is -off by default: - -````md -### Enabling the feature - -This feature comes with the `:feature_flag` feature flag disabled by default. In some cases, -this feature is incompatible with an old configuration. To turn on the feature, -ask a GitLab administrator with Rails console access to run the following command: - -```ruby -Feature.enable(:feature_flag) -``` -```` - -For guidance on developing with feature flags, see +Learn how to [document features deployed behind flags](feature_flags.md). +For guidance on developing GitLab with feature flags, see [Feature flags in development of GitLab](../feature_flags/index.md). ## API @@ -1475,7 +1529,7 @@ The following can be used as a template to get started: One or two sentence description of what endpoint does. -```text +```plaintext METHOD /endpoint ``` @@ -1537,7 +1591,7 @@ You can use the following fake tokens as examples. Use the following table headers to describe the methods. Attributes should always be in code blocks using backticks (`` ` ``). -```md +```markdown | Attribute | Type | Required | Description | |:----------|:-----|:---------|:------------| ``` @@ -1614,7 +1668,7 @@ curl --request POST --header "PRIVATE-TOKEN: " --form "title= ``` The above example is run by and administrator and will add an SSH public key -titled `ssh-key` to user's account which has an id of 25. +titled `ssh-key` to user's account which has an ID of 25. #### Escape special characters diff --git a/doc/development/documentation/workflow.md b/doc/development/documentation/workflow.md index 01f528dcfa4..ab6200155bf 100644 --- a/doc/development/documentation/workflow.md +++ b/doc/development/documentation/workflow.md @@ -1,19 +1,20 @@ # Documentation process -The process for creating and maintaining GitLab product documentation depends on whether the -documentation is associated with: +The process for creating and maintaining GitLab product documentation allows +anyone to contribute a merge request or create an issue for GitLab's +documentation. -- [A new feature or feature enhancement](#for-a-product-change). - - Delivered for a specific milestone and associated with specific code changes. This documentation - has the highest priority. +NOTE: **Note:** +Documentation updates relating to new features or feature enhancements must +use the [feature workflow process](https://about.gitlab.com/handbook/engineering/ux/technical-writing/workflow/#for-a-product-change) described in the GitLab Handbook. -- [Changes outside a specific milestone](#for-all-other-documentation). +## Who updates the docs? - It is usually not associated with a specific code change and has a lower priority. +*Anyone* can contribute! You can create a merge request for documentation when: -Documentation is not usually required when a "backstage feature" is added or changed, and does not -directly affect the way that any user or administrator interacts with GitLab. +- You find errors or other room for improvement in existing documentation. +- You have an idea for all-new documentation that would help a GitLab user or administrator to + accomplish their work with GitLab. ## Documentation labels @@ -32,372 +33,17 @@ The following are also added by members of the Technical Writing team: `docs::` prefix. For example, `~docs::improvement`. - The `~Technical Writing` [team label](../contributing/issue_workflow.md#team-labels). -## For a product change - -This documentation is required for any new or changed feature and is: - -- Created or updated as part of feature development, almost always in the same merge request as the - feature code. Including documentation in the same merge request as the code eliminates the - possibility that code and documentation get out of sync. -- Required with the delivery of a feature for a specific milestone as part of GitLab's - [definition of done](../contributing/merge_request_workflow.md#definition-of-done). -- Often linked from the release post. - -### Roles and responsibilities - -Documentation for specific milestones involves the: - -- Developer of a feature or enhancement. -- Product Manager for the group delivering the new feature or feature enhancement. -- Technical Writer assigned to the group. - -Each role is described below. - -#### Developers - -Developers are the primary author of documentation for a feature or feature enhancement. They are -responsible for: - -- Developing initial content required for a feature. -- Liaising with their Product Manager to understand what documentation must be delivered, and when. -- Requesting technical reviews from other developers within their group. -- Requesting documentation reviews from the Technical Writer - [assigned to the DevOps stage group](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments) - that is delivering the new feature or feature enhancements. - -TIP: **Tip:** -Community Contributors can ask for additional help from GitLab team members. - -##### Authoring - -Because the documentation is an essential part of the product, if a ~feature issue also contains the -~documentation label, you must ship the new or updated documentation with the code of the feature. - -Technical Writers are happy to help, as requested and planned on an issue-by-issue basis. - -For feature issues requiring documentation, follow the process below unless otherwise agreed with -the Product Manager and Technical Writer for a given issue: - -- Include any new and edited documentation, either in: - - The merge request introducing the code. - - A separate merge request raised around the same time. -- Use the [documentation requirements](#documentation-requirements) developed by the Product Manager - in the issue and discuss any further documentation plans or ideas as needed. - - If the new or changed documentation requires extensive collaboration or conversation, a - separate, linked issue can be used for the planning process. - -- Use the [Documentation guidelines](index.md), as well as other resources linked from there, - including: - - Documentation [Structure and template](structure.md) page. - - [Style Guide](styleguide.md). - - [Markdown Guide](https://about.gitlab.com/handbook/engineering/ux/technical-writing/markdown-guide/). -- Contact the Technical Writer for the relevant [DevOps stage](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments) - in your issue or merge request, or within `#docs` on GitLab Slack, if you: - - Need any help to choose the correct place for documentation. - - Want to discuss a documentation idea or outline. - - Want to request any other help. -- If you are working on documentation in a separate merge request, ensure the documentation is - merged as close as possible to the code merge. -- A policy for documenting [feature-flagged](../feature_flags/index.md) issues is forthcoming and you - are welcome to join the [discussion](https://gitlab.com/gitlab-org/gitlab/issues/26347). - -##### Reviews and merging - -Reviewers help ensure: - -- Accuracy. -- Clarity. -- Completeness. -- Adherence to: - - [Documentation requirements](#documentation-requirements) in the issue. - - [Documentation guidelines](index.md). - - [Style guide](styleguide.md). - -Prior to merging, documentation changes committed by the developer must be reviewed by: - -- The code reviewer for the merge request. This is known as a technical review. -- Optionally, others involved in the work such as other developers or the Product Manager. -- The Technical Writer for the DevOps stage group, except in exceptional circumstances where a - [post-merge review](#post-merge-reviews) can be requested. -- A maintainer of the project. - -#### Product Managers - -Product Managers are responsible for the [documentation requirements](#documentation-requirements) -for a feature or feature enhancement. They can also: - -- Liaise with the Technical Writer for discussion and collaboration. -- Review documentation themselves. - -For issues requiring any new or updated documentation, the Product Manager must: - -- Add the ~documentation label. -- Confirm or add the [documentation requirements](#documentation-requirements). -- Ensure the issue contains: - - Any new or updated feature name. - - Overview, description, and use cases when applicable (as required by the - [documentation structure and template](structure.md)). - -Everyone is encouraged to draft the documentation requirements in the issue. However, a Product -Manager will: - -- When the issue is assigned a release milestone, review and update the Documentation details. -- By the kickoff, finalize the documentation details. - -#### Technical Writers - -Technical Writers are responsible for: - -- Participating in issues discussions and reviewing MRs for the upcoming milestone. -- Reviewing documentation requirements in issues when called upon. -- Answering questions, and helping and providing advice throughout the authoring and editing - process. -- Reviewing all significant new and updated documentation content, whether before merge or after it - is merged. -- Assisting the developer and Product Manager with feature documentation delivery. - -##### Planning - -The Technical Writer: - -- Reviews their group's `~feature` issues that are part of the next milestone to get a sense of the - scope of content likely to be authored. -- Recommends the `~documentation` label on issues from that list which don't have it but should, or - inquires with the PM to determine if documentation is truly required. -- For `~direction` issues from that list, reads the full issue and reviews its Documentation - requirements section. Addresses any recommendations or questions with the PMs and others - collaborating on the issue in order to refine or expand the Documentation requirements. - -##### Collaboration - -By default, the developer will work on documentation changes independently, but -the developer, Product Manager, or Technical Writer can propose a broader collaboration for -any given issue. - -Additionally, Technical Writers are available for questions at any time. - -##### Review - -Technical Writers: - -- Provide non-blocking reviews of all documentation changes, before or after the change is merged. -- Confirm that the documentation is: - - Clear. - - Grammatically correct. - - Discoverable. - - Navigable. -- Ensures that the documentation avoids: - - Redundancy. - - Bad file locations. - - Typos. - - Broken links. - -The Technical Writer will review the documentation to check that the developer and -code reviewer have ensured: - -- Clarity. -- Appropriate location, making sure the documentation is in the correct directories (often - reflecting how the product is structured) and has the correct name. -- Syntax, typos, and broken links. -- Improvements to the content. -- Accordance with the: - - [Documentation Style Guide](styleguide.md). - - [Structure and Template](structure.md) doc. - -### When documentation is required - -Documentation [is required](../contributing/merge_request_workflow.md#definition-of-done) for a -milestone when: - -- A new or enhanced feature is shipped that impacts the user or administrator experience. -- There are changes to the UI or API. -- A process, workflow, or previously documented feature is changed. -- A feature is deprecated or removed. - -NOTE: **Note:** -Documentation refactoring unrelated to a feature change is covered in the -[other process](#for-all-other-documentation), so that time-sensitive documentation updates are -prioritized. - -### Documentation requirements - -Requirements for the documentation of a feature should be included as part of the -issue for planning that feature in a **Documentation** section within the issue description. Issues -created using the [**Feature Proposal** template](https://gitlab.com/gitlab-org/gitlab/raw/master/.gitlab/issue_templates/Feature%20proposal.md) -have this section by default. - -Anyone can add these details, but the Product Manager who assigns the issue to a specific release -milestone will ensure these details are present and finalized by the time of that milestone's kickoff. - -Developers, Technical Writers, and others may help further refine this plan at any time on request. - -The following details should be included: - -- What concepts and procedures should the documentation guide and enable the user to understand or - accomplish? -- To this end, what new page(s) are needed, if any? What pages or subsections need updates? - Consider changes and additions to user, admin, and API documentation. -- For any guide or instruction set, should it help address a single use case, or be flexible to - address a certain range of use cases? -- Do we need to update a previously recommended workflow? Should we link the new feature from - various relevant locations? Consider all ways documentation should be affected. -- Are there any key terms or task descriptions that should be included so that the documentation is - found in relevant searches? -- Include suggested titles of any pages or subsection headings, if applicable. -- List any documentation that should be cross-linked, if applicable. - -### Including docs with code - -Currently, the Technical Writing team strongly encourages including documentation in -the same merge request as the code that it relates to, but this is not strictly mandatory. -It's still common for documentation to be added in an MR separate from the feature MR. - -Engineering teams may elect to adopt a workflow where it is **mandatory** that docs -are included in the code MR, as part of their [definition of done](../contributing/merge_request_workflow.md#definition-of-done). -When a team adopts this workflow, that team's engineers must include their docs in the **same** -MR as their feature code, at all times. - -#### Downsides of separate docs MRs - -A workflow that has documentation separated into its own MR has many downsides. - -If the documentation merges **before** the feature: - -- GitLab.com users might try to use the feature before it's released, driving support tickets. -- If the feature is delayed, the documentation might not be pulled/reverted in time and could be - accidentally included in the self-managed package for that release. - -If the documentation merges **after** the feature: - -- The feature might be included in the self-managed package, but without any documentation - if the docs MR misses the cutoff. -- A feature might show up in the GitLab.com UI before any documentation exists for it. - Users surprised by this feature will search for documentation and won't find it, possibly driving - support tickets. - -Having two separate MRs means: - -- Two different people might be responsible for merging one feature, which is not workable - with an asynchronous work style. The feature might merge while the technical writer is asleep, - creating a potentially lengthy delay between the two merges. -- If the docs MR is assigned to the same maintainer as responsible for the feature - code MR, they will have to review and juggle two MRs instead of dealing with just one. - -Documentation quality might be lower, because: - -- Having docs in a separate MR will mean far fewer people will see and verify them, - increasing the likelihood that issues will be missed. -- In a "split" workflow, engineers might only create the documentation MR once the - feature MR is ready, or almost ready. This gives the technical writer little time - to learn about the feature in order to do a good review. It also increases pressure - on them to review and merge faster than desired, letting problems slip in due to haste. - -#### Benefits of always including docs with code - -Including docs with code (and doing it early in the development process) has many benefits: - -- There are no timing issues connected to releases: - - If a feature slips to the next release, the documentation slips too. - - If the feature *just* makes it into a release, the docs *just* make it in too. - - If a feature makes it to GitLab.com early, the documentation will be ready for - our early adopters. -- Only a single person will be responsible for merging the feature (the code maintainer). -- The technical writer will have more time to gain an understanding of the feature - and will be better able to verify the content of the docs in the Review App or GDK. - They will also be able to offer advice for improving the UI text or offer additional use cases. -- The documentation will have increased visibility: - - Everyone involved in the merge request will see the docs. This could include product - managers, multiple engineers with deep domain knowledge, as well as the code reviewers - and maintainer. They will be more likely to catch issues with examples, as well - as background or concepts that the technical writer may not be aware of. - - Increasing visibility of the documentation also has the side effect of improving - *other* engineers' documentation. By reviewing each other's MRs, each engineer's - own documentation skills will improve. -- Thinking about the documentation early can help engineers generate better examples, - as they will need to think about what examples a user will want, and will need to - make sure the code they write implements that example properly. - -#### Docs with code as a workflow - -In order to have docs included with code as a mandatory workflow, some changes might -need to happen to a team's current workflow: - -- The engineers must strive to include the docs early in the development process, - to give ample time for review, not just from the technical writer, but also the - code reviewer and maintainer. -- Reviewers and maintainers must also review the docs during code reviews, to make - sure the described processes match the expected use of the feature, and that examples - are correct. They do *not* need to worry about style, grammar, and so on. -- The technical writer must be assigned the MR directly and not only pinged. Thanks - to the ability to have [multiple assignees for any MR](../../user/project/merge_requests/getting_started.md#multiple-assignees-starter), - this can be done at any time, but must be before the code maintainer review. It's - common to have both the docs and code reviews happening at the same time, with the - author, reviewer and technical writer discussing the docs together. -- When the docs are ready, the technical writer will click **Approve** and usually - will no longer be involved in the MR. If the feature changes during code review and - the docs are updated, the technical writer must be reassigned the MR to verify the - update. -- Maintainers are allowed to merge features with the docs "as-is", even if the technical - writer has not given final approval yet. The **docs reviews must not be blockers**. Therefore - it's important to get the docs included and assigned to the technical writers early. - If the feature is merged before final docs approval, the maintainer must create - a [post-merge follow-up issue](#post-merge-reviews), and assign it to both the engineer - and technical writer. - -Maintainers are allowed to merge features with the docs "as-is" even if the -technical writer has not given final approval yet but the merge request has -all other required approvals. - -You can visualize the parallel workflow for code and docs reviews as: - -```mermaid -graph TD - A("Feature MR Created (Engineer)") --> |Assign| B("Code Review (reviewer)") - B --> |"Approve / Reassign"| C("Code Review (maintainer)") - C --> |Approve| F("Merge (maintainer)") - A --> D("Docs Added (Engineer)") - D --> |Assign| E("Docs Review (Tech Writer)") - E --> |Approve| F -``` - -For complex features split over multiple merge requests: - -- If a merge request is implementing components for a future feature, but the components - are not accessible to users yet, then no documentation should be included. -- If a merge request will expose a feature to users in any way, such as an enabled - UI element, an API endpoint, or anything similar, then that MR **must** have docs. - Note that this may mean multiple docs additions could happen in the buildup to the - implementation of a single large feature, for example API docs and feature usage docs. -- If it's unclear which engineer should add the feature documentation into their - MR, the engineering manager should decide during planning, and tie the documentation - to the last MR that must be merged before a feature is considered released. - This is often, but not always, a frontend MR. - -## For all other documentation - Documentation changes that are not associated with the release of a new or updated feature do not take the `~feature` label, but still need the `~documentation` label. They may include: - Documentation created or updated to improve accuracy, completeness, ease of use, or any reason - other than a [feature change](#for-a-product-change). + other than a [feature change](https://about.gitlab.com/handbook/engineering/ux/technical-writing/workflow/#for-a-product-change). - Addressing gaps in existing documentation, or making improvements to existing documentation. - Work on special projects related to the documentation. -TIP: **Tip:** -Anyone can contribute a merge request or create an issue for GitLab's documentation. - -### Who updates the docs - -Anyone can contribute! You can create a merge request for documentation when: - -- You find errors or other room for improvement in existing documentation. -- You have an idea for all-new documentation that would help a GitLab user or administrator to - accomplish their work with GitLab. - -### How to update the docs +## How to update the docs To update GitLab documentation: @@ -464,7 +110,7 @@ The process involves the following: The process is reflected in the **Documentation** [merge request template](https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab/merge_request_templates/Documentation.md). -### Other ways to help +## Other ways to help If you have ideas for further documentation resources please [create an issue](https://gitlab.com/gitlab-org/gitlab/issues/new?issuable_template=Documentation) diff --git a/doc/development/ee_features.md b/doc/development/ee_features.md index bd70d5b87ba..3951b0516e8 100644 --- a/doc/development/ee_features.md +++ b/doc/development/ee_features.md @@ -3,7 +3,8 @@ - **Write the code and the tests.**: As with any code, EE features should have good test coverage to prevent regressions. - **Write documentation.**: Add documentation to the `doc/` directory. Describe - the feature and include screenshots, if applicable. + the feature and include screenshots, if applicable. Indicate [what editions](documentation/styleguide.md#product-badges) + the feature applies to. - **Submit a MR to the `www-gitlab-com` project.**: Add the new feature to the [EE features list](https://about.gitlab.com/features/). @@ -111,7 +112,7 @@ There are a few gotchas with it: smaller methods. Or create a "hook" method that is empty in CE, and with the EE-specific implementation in EE. - when the original implementation contains a guard clause (e.g. - `return unless condition`), we cannot easily extend the behaviour by + `return unless condition`), we cannot easily extend the behavior by overriding the method, because we can't know when the overridden method (i.e. calling `super` in the overriding method) would want to stop early. In this case, we shouldn't just override it, but update the original method @@ -131,7 +132,7 @@ There are a few gotchas with it: ``` Instead of just overriding `Base#execute`, we should update it and extract - the behaviour into another method: + the behavior into another method: ```ruby class Base @@ -513,7 +514,7 @@ do that, so we'll follow regular object-oriented practices that we define the interface first here. For example, suppose we have a few more optional parameters for EE. We can move the -paramters out of the `Grape::API` class to a helper module, so we can inject it +parameters out of the `Grape::API` class to a helper module, so we can inject it before it would be used in the class. ```ruby @@ -613,9 +614,9 @@ module EE end ``` -#### EE-specific behaviour +#### EE-specific behavior -Sometimes we need EE-specific behaviour in some of the APIs. Normally we could +Sometimes we need EE-specific behavior in some of the APIs. Normally we could use EE methods to override CE methods, however API routes are not methods and therefore can't be simply overridden. We need to extract them into a standalone method, or introduce some "hooks" where we could inject behavior in the CE diff --git a/doc/development/elasticsearch.md b/doc/development/elasticsearch.md index 758cecce315..185f536fc01 100644 --- a/doc/development/elasticsearch.md +++ b/doc/development/elasticsearch.md @@ -7,7 +7,7 @@ the [Elasticsearch integration documentation](../integration/elasticsearch.md#en ## Deep Dive -In June 2019, Mario de la Ossa hosted a [Deep Dive](https://gitlab.com/gitlab-org/create-stage/issues/1) on GitLab's [Elasticsearch integration](../integration/elasticsearch.md) to share his domain specific knowledge with anyone who may work in this part of the code base in the future. You can find the [recording on YouTube](https://www.youtube.com/watch?v=vrvl-tN2EaA), and the slides on [Google Slides](https://docs.google.com/presentation/d/1H-pCzI_LNrgrL5pJAIQgvLX8Ji0-jIKOg1QeJQzChug/edit) and in [PDF](https://gitlab.com/gitlab-org/create-stage/uploads/c5aa32b6b07476fa8b597004899ec538/Elasticsearch_Deep_Dive.pdf). Everything covered in this deep dive was accurate as of GitLab 12.0, and while specific details may have changed since then, it should still serve as a good introduction. +In June 2019, Mario de la Ossa hosted a Deep Dive (GitLab team members only: `https://gitlab.com/gitlab-org/create-stage/issues/1`) on GitLab's [Elasticsearch integration](../integration/elasticsearch.md) to share his domain specific knowledge with anyone who may work in this part of the code base in the future. You can find the [recording on YouTube](https://www.youtube.com/watch?v=vrvl-tN2EaA), and the slides on [Google Slides](https://docs.google.com/presentation/d/1H-pCzI_LNrgrL5pJAIQgvLX8Ji0-jIKOg1QeJQzChug/edit) and in [PDF](https://gitlab.com/gitlab-org/create-stage/uploads/c5aa32b6b07476fa8b597004899ec538/Elasticsearch_Deep_Dive.pdf). Everything covered in this deep dive was accurate as of GitLab 12.0, and while specific details may have changed since then, it should still serve as a good introduction. ## Supported Versions diff --git a/doc/development/emails.md b/doc/development/emails.md index a84895eef5b..e6e2ea8aae7 100644 --- a/doc/development/emails.md +++ b/doc/development/emails.md @@ -14,13 +14,11 @@ Please note that [S/MIME signed](../administration/smime_signing_email.md) email Rails provides a way to preview our mailer templates in HTML and plaintext using dummy data. -The previews live in [`app/mailers/previews`][previews] and can be viewed at +The previews live in [`app/mailers/previews`](https://gitlab.com/gitlab-org/gitlab-foss/tree/master/app/mailers/previews) and can be viewed at [`/rails/mailers`](http://localhost:3000/rails/mailers). See the [Rails guides](https://guides.rubyonrails.org/action_mailer_basics.html#previewing-emails) for more information. -[previews]: https://gitlab.com/gitlab-org/gitlab-foss/tree/master/app/mailers/previews - ## Incoming email 1. Go to the GitLab installation directory. @@ -59,6 +57,9 @@ See the [Rails guides](https://guides.rubyonrails.org/action_mailer_basics.html# mailbox: "inbox" # The IDLE command timeout. idle_timeout: 60 + + # Whether to expunge (permanently remove) messages from the mailbox when they are deleted after delivery + expunge_deleted: false ``` As mentioned, the part after `+` is ignored, and this will end up in the mailbox for `gitlab-incoming@gmail.com`. @@ -87,7 +88,7 @@ for the format of the email key: - Actions are always at the end, separated by `-`. For example `-issue` or `-merge-request` - If your feature is related to a project, the key begins with the project identifiers (project path slug - and project id), separated by `-`. For example, `gitlab-org-gitlab-foss-20` + and project ID), separated by `-`. For example, `gitlab-org-gitlab-foss-20` - Additional information, such as an author's token, can be added between the project identifiers and the action, separated by `-`. For example, `gitlab-org-gitlab-foss-20-Author_Token12345678-issue` - You register your handlers in `lib/gitlab/email/handler.rb` diff --git a/doc/development/event_tracking/backend.md b/doc/development/event_tracking/backend.md index dc4d7279671..93e135772ef 100644 --- a/doc/development/event_tracking/backend.md +++ b/doc/development/event_tracking/backend.md @@ -1,5 +1,5 @@ --- -redirect_to: '../../telemetry/backend.md' +redirect_to: '../telemetry/index.md' --- -This document was moved to [another location](../../telemetry/backend.md). +This document was moved to [another location](../telemetry/index.md). diff --git a/doc/development/event_tracking/frontend.md b/doc/development/event_tracking/frontend.md index 0e98daf15bb..93e135772ef 100644 --- a/doc/development/event_tracking/frontend.md +++ b/doc/development/event_tracking/frontend.md @@ -1,5 +1,5 @@ --- -redirect_to: '../../telemetry/frontend.md' +redirect_to: '../telemetry/index.md' --- -This document was moved to [another location](../../telemetry/frontend.md). +This document was moved to [another location](../telemetry/index.md). diff --git a/doc/development/event_tracking/index.md b/doc/development/event_tracking/index.md index ae555e99c6b..93e135772ef 100644 --- a/doc/development/event_tracking/index.md +++ b/doc/development/event_tracking/index.md @@ -1,5 +1,5 @@ --- -redirect_to: '../../telemetry/index.md' +redirect_to: '../telemetry/index.md' --- -This document was moved to [another location](../../telemetry/index.md). +This document was moved to [another location](../telemetry/index.md). diff --git a/doc/development/experiment_guide/index.md b/doc/development/experiment_guide/index.md index ffa95d86876..f0e05139cba 100644 --- a/doc/development/experiment_guide/index.md +++ b/doc/development/experiment_guide/index.md @@ -32,10 +32,9 @@ The author then adds a comment to this piece of code and adds a link to the issu #... }, # Add your experiment here: - sign_up_flow: { - feature_toggle: :experimental_sign_up_flow, # Feature flag that will be used - environment: ::Gitlab.dev_env_or_com?, # Target environment - enabled_ratio: 0.1 # Percentage of users that will be part of the experiment. 10% of the users would be part of this experiments. + signup_flow: { + environment: ::Gitlab.dev_env_or_com?, # Target environment, defaults to enabled for development and GitLab.com + tracking_category: 'Growth::Acquisition::Experiment::SignUpFlow' # Used for providing the category when setting up tracking data } }.freeze ``` @@ -46,7 +45,7 @@ The author then adds a comment to this piece of code and adds a link to the issu class RegistrationController < Applicationcontroller def show # experiment_enabled?(:feature_name) is also available in views and helpers - if experiment_enabled?(:sign_up_flow) + if experiment_enabled?(:signup_flow) # render the experiment else # render the original version @@ -55,13 +54,18 @@ The author then adds a comment to this piece of code and adds a link to the issu end ``` -- Track necessary events. See the [telemetry guide](../../telemetry/index.md) for details. +- Track necessary events. See the [telemetry guide](../telemetry/index.md) for details. - After the merge request is merged, use [`chatops`](../../ci/chatops/README.md) in the -[appropriate channel](../feature_flags/controls.md#where-to-run-commands) to enable the feature flag and start the experiment. +[appropriate channel](../feature_flags/controls.md#communicate-the-change) to start the experiment for 10% of the users. +The feature flag should have the name of the experiment with the `_experiment_percentage` suffix appended. For visibility, please also share any commands run against production in the `#s_growth` channel: ```shell - /chatops run feature set --project=gitlab-org/gitlab experimental_sign_up_flow true + /chatops run feature set signup_flow_experiment_percentage 10 ``` - If you notice issues with the experiment, you can disable the experiment by setting the feature flag to `false` again. + If you notice issues with the experiment, you can disable the experiment by removing the feature flag: + + ```shell + /chatops run feature delete signup_flow_experiment_percentage + ``` diff --git a/doc/development/fe_guide/accessibility.md b/doc/development/fe_guide/accessibility.md index 4fd9a4fed60..998c71135fb 100644 --- a/doc/development/fe_guide/accessibility.md +++ b/doc/development/fe_guide/accessibility.md @@ -2,19 +2,12 @@ ## Resources -[Chrome Accessibility Developer Tools][chrome-accessibility-developer-tools] +[Chrome Accessibility Developer Tools](https://github.com/GoogleChrome/accessibility-developer-tools) are useful for testing for potential accessibility problems in GitLab. -The [axe][axe-website] browser extension (available for [Firefox][axe-firefox-extension] and [Chrome][axe-chrome-extension]) is +The [axe](https://www.deque.com/axe/) browser extension (available for [Firefox](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/) and [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd)) 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 +[the Audit Rules page](https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules) for the Chrome Accessibility Developer Tools. The [Awesome Accessibility](https://github.com/brunopulis/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-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd -[awesome-a11y]: https://github.com/brunopulis/awesome-a11y diff --git a/doc/development/fe_guide/axios.md b/doc/development/fe_guide/axios.md index 6e7cf523f36..f8d301dac5e 100644 --- a/doc/development/fe_guide/axios.md +++ b/doc/development/fe_guide/axios.md @@ -1,13 +1,13 @@ # Axios -We use [axios][axios] to communicate with the server in Vue applications and most new code. +We use [axios](https://github.com/axios/axios) to communicate with the server in Vue applications and most new code. In order to guarantee all defaults are set you *should not use `axios` directly*, you should import `axios` from `axios_utils`. ## CSRF token All our request require a CSRF token. -To guarantee this token is set, we are importing [axios][axios], setting the token, and exporting `axios` . +To guarantee this token is set, we are importing [axios](https://github.com/axios/axios), setting the token, and exporting `axios` . This exported module should be used instead of directly using `axios` to ensure the token is set. @@ -32,19 +32,16 @@ This exported module should be used instead of directly using `axios` to ensure ## Mock axios response in tests -To help us mock the responses we are using [axios-mock-adapter][axios-mock-adapter]. +To help us mock the responses we are using [axios-mock-adapter](https://github.com/ctimmerm/axios-mock-adapter). -Advantages over [`spyOn()`]: +Advantages over [`spyOn()`](https://jasmine.github.io/api/edge/global.html#spyOn): - no need to create response objects - does not allow call through (which we want to avoid) - simple API to test error cases - provides `replyOnce()` to allow for different responses -We have also decided against using [axios interceptors] because they are not suitable for mocking. - -[axios interceptors]: https://github.com/axios/axios#interceptors -[`spyOn()`]: https://jasmine.github.io/api/edge/global.html#spyOn +We have also decided against using [axios interceptors](https://github.com/axios/axios#interceptors) because they are not suitable for mocking. ### Example @@ -77,8 +74,3 @@ Because polling function requires a header object, we need to always include an ```javascript mock.onGet('/users').reply(200, { foo: 'bar' }, {}); ``` - -[axios]: https://github.com/axios/axios -[axios-instance]: #creating-an-instance -[axios-interceptors]: https://github.com/axios/axios#interceptors -[axios-mock-adapter]: https://github.com/ctimmerm/axios-mock-adapter diff --git a/doc/development/fe_guide/design_patterns.md b/doc/development/fe_guide/design_patterns.md index 72a7861ffcb..5b7b16a9a8a 100644 --- a/doc/development/fe_guide/design_patterns.md +++ b/doc/development/fe_guide/design_patterns.md @@ -75,6 +75,4 @@ class Foo { new Foo({ container: '.my-element' }); ``` -You can find an example of the above in this [class][container-class-example]; - -[container-class-example]: https://gitlab.com/gitlab-org/gitlab/blob/master/app/assets/javascripts/mini_pipeline_graph_dropdown.js +You can find an example of the above in this [class](https://gitlab.com/gitlab-org/gitlab/blob/master/app/assets/javascripts/mini_pipeline_graph_dropdown.js); diff --git a/doc/development/fe_guide/droplab/droplab.md b/doc/development/fe_guide/droplab/droplab.md index 4d7c882dc09..83bc4216403 100644 --- a/doc/development/fe_guide/droplab/droplab.md +++ b/doc/development/fe_guide/droplab/droplab.md @@ -26,7 +26,7 @@ If you do not provide any arguments, it will globally query and instantiate all
    ``` -```js +```javascript const droplab = new DropLab(); droplab.init(); ``` @@ -47,7 +47,7 @@ You can add static list items.
      ``` -```js +```javascript const droplab = new DropLab(); droplab.init(); ``` @@ -65,7 +65,7 @@ a non-global instance of DropLab using the `DropLab.prototype.init` method.
        ``` -```js +```javascript const trigger = document.getElementById('trigger'); const list = document.getElementById('list'); @@ -83,7 +83,7 @@ You can also add hooks to an existing DropLab instance using `DropLab.prototype.
            ``` -```js +```javascript const droplab = new DropLab(); droplab.init(); @@ -114,7 +114,7 @@ for all `data-dynamic` dropdown lists tracked by that DropLab instance.
          ``` -```js +```javascript const droplab = new DropLab(); droplab.init().addData([{ @@ -137,7 +137,7 @@ the data as the second argument and the `id` of the trigger element as the first
        ``` -```js +```javascript const droplab = new DropLab(); droplab.init().addData('trigger', [{ @@ -167,7 +167,7 @@ dropdown lists, one of which is dynamic. ``` -```js +```javascript const droplab = new DropLab(); droplab.init().addData('trigger', [{ @@ -224,7 +224,7 @@ Some plugins require configuration values, the config object can be passed as th
            ``` -```js +```javascript const droplab = new DropLab(); const trigger = document.getElementById('trigger'); @@ -249,7 +249,7 @@ droplab.init(trigger, list, [droplabAjax], { When plugins are initialised for a droplab trigger+dropdown, DropLab will call the plugins `init` function, so this must be implemented in the plugin. -```js +```javascript class MyPlugin { static init() { this.someProp = 'someProp'; diff --git a/doc/development/fe_guide/droplab/plugins/ajax.md b/doc/development/fe_guide/droplab/plugins/ajax.md index 77ba6f739e6..abc208e7568 100644 --- a/doc/development/fe_guide/droplab/plugins/ajax.md +++ b/doc/development/fe_guide/droplab/plugins/ajax.md @@ -18,7 +18,7 @@ Add the `Ajax` object to the plugins array of a `DropLab.prototype.init` or `Dro
                ``` -```js +```javascript const droplab = new DropLab(); const trigger = document.getElementById('trigger'); diff --git a/doc/development/fe_guide/droplab/plugins/filter.md b/doc/development/fe_guide/droplab/plugins/filter.md index b867394a241..876149e4872 100644 --- a/doc/development/fe_guide/droplab/plugins/filter.md +++ b/doc/development/fe_guide/droplab/plugins/filter.md @@ -18,7 +18,7 @@ Add the `Filter` object to the plugins array of a `DropLab.prototype.init` or `D
                  ``` -```js +```javascript const droplab = new DropLab(); const trigger = document.getElementById('trigger'); diff --git a/doc/development/fe_guide/droplab/plugins/input_setter.md b/doc/development/fe_guide/droplab/plugins/input_setter.md index db492da478a..9b2e1e8faab 100644 --- a/doc/development/fe_guide/droplab/plugins/input_setter.md +++ b/doc/development/fe_guide/droplab/plugins/input_setter.md @@ -23,7 +23,7 @@ You can also set the `InputSetter` config to an array of objects, which will all
                    ``` -```js +```javascript const droplab = new DropLab(); const trigger = document.getElementById('trigger'); diff --git a/doc/development/fe_guide/event_tracking.md b/doc/development/fe_guide/event_tracking.md index ae555e99c6b..93e135772ef 100644 --- a/doc/development/fe_guide/event_tracking.md +++ b/doc/development/fe_guide/event_tracking.md @@ -1,5 +1,5 @@ --- -redirect_to: '../../telemetry/index.md' +redirect_to: '../telemetry/index.md' --- -This document was moved to [another location](../../telemetry/index.md). +This document was moved to [another location](../telemetry/index.md). diff --git a/doc/development/fe_guide/frontend_faq.md b/doc/development/fe_guide/frontend_faq.md index 3b0b1d8f0da..8f8f162609a 100644 --- a/doc/development/fe_guide/frontend_faq.md +++ b/doc/development/fe_guide/frontend_faq.md @@ -39,7 +39,7 @@ bundle exec rake routes | grep "issues" ### 2. `modal_copy_button` vs `clipboard_button` -The `clipboard_button` uses the `copy_to_clipboard.js` behaviour, which is +The `clipboard_button` uses the `copy_to_clipboard.js` behavior, which is initialized on page load, so if there are vue-based clipboard buttons that don't exist at page load (such as ones in a `GlModal`), they do not have the click handlers associated with the clipboard package. diff --git a/doc/development/fe_guide/graphql.md b/doc/development/fe_guide/graphql.md index 8ccc734ee35..caf84d04490 100644 --- a/doc/development/fe_guide/graphql.md +++ b/doc/development/fe_guide/graphql.md @@ -10,13 +10,13 @@ their execution by clicking **Execute query** button on the top left: ![GraphiQL interface](img/graphiql_explorer_v12_4.png) -We use [Apollo] and [Vue Apollo][vue-apollo] for working with GraphQL +We use [Apollo](https://www.apollographql.com/) and [Vue Apollo](https://github.com/vuejs/vue-apollo) for working with GraphQL on the frontend. ## Apollo Client To save duplicated clients getting created in different apps, we have a -[default client][default-client] that should be used. This setups the +[default client](https://gitlab.com/gitlab-org/gitlab/blob/master/app/assets/javascripts/lib/graphql.js) that should be used. This setups the Apollo client with the correct URL and also sets the CSRF headers. Default client accepts two parameters: `resolvers` and `config`. @@ -73,7 +73,7 @@ More about fragments: ## Usage in Vue -To use Vue Apollo, import the [Vue Apollo][vue-apollo] plugin as well +To use Vue Apollo, import the [Vue Apollo](https://github.com/vuejs/vue-apollo) plugin as well as the default client. This should be created at the same point the Vue application is mounted. @@ -94,7 +94,7 @@ new Vue({ }); ``` -Read more about [Vue Apollo][vue-apollo] in the [Vue Apollo documentation](https://vue-apollo.netlify.com/guide/). +Read more about [Vue Apollo](https://github.com/vuejs/vue-apollo) in the [Vue Apollo documentation](https://vue-apollo.netlify.com/guide/). ### Local state with Apollo @@ -212,7 +212,7 @@ Read more about local state management with Apollo in the [Vue Apollo documentat When Apollo Client is used within Vuex and fetched data is stored in the Vuex store, there is no need in keeping Apollo Client cache enabled. Otherwise we would have data from the API stored in two places - Vuex store and Apollo Client cache. More to say, with Apollo default settings, a subsequent fetch from the GraphQL API could result in fetching data from Apollo cache (in the case where we have the same query and variables). To prevent this behavior, we need to disable Apollo Client cache passing a valid `fetchPolicy` option to its constructor: -```js +```javascript import fetchPolicies from '~/graphql_shared/fetch_policy_constants'; export const gqClient = createGqClient( @@ -298,7 +298,8 @@ handleClick() { GitLab's GraphQL API uses [Relay-style cursor pagination](https://www.apollographql.com/docs/react/data/pagination/#cursor-based) for connection types. This means a "cursor" is used to keep track of where in the data -set the next items should be fetched from. +set the next items should be fetched from. [GraphQL Ruby Connection Concepts](https://graphql-ruby.org/pagination/connection_concepts.html) +is a good overview and introduction to connections. Every connection type (for example, `DesignConnection` and `DiscussionConnection`) has a field `pageInfo` that contains an information required for pagination: @@ -426,7 +427,7 @@ This should be resolved in the scope of the issue #### Mocking response as component data -With [Vue test utils][vue-test-utils] it is easy to quickly test components that +With [Vue test utils](https://vue-test-utils.vuejs.org/) it is easy to quickly test components that fetch GraphQL queries. The simplest way is to use `shallowMount` and then set the data on the component @@ -598,11 +599,4 @@ defaultClient.query({ query }) .then(result => console.log(result)); ``` -Read more about the [Apollo] client in the [Apollo documentation](https://www.apollographql.com/docs/tutorial/client/). - -[Apollo]: https://www.apollographql.com/ -[vue-apollo]: https://github.com/vuejs/vue-apollo -[feature-flags]: ../feature_flags.md -[default-client]: https://gitlab.com/gitlab-org/gitlab/blob/master/app/assets/javascripts/lib/graphql.js -[vue-test-utils]: https://vue-test-utils.vuejs.org/ -[apollo-link-state]: https://www.apollographql.com/docs/link/links/state.html +Read more about the [Apollo](https://www.apollographql.com/) client in the [Apollo documentation](https://www.apollographql.com/docs/tutorial/client/). diff --git a/doc/development/fe_guide/icons.md b/doc/development/fe_guide/icons.md index ea321330c41..4fb738f5466 100644 --- a/doc/development/fe_guide/icons.md +++ b/doc/development/fe_guide/icons.md @@ -1,8 +1,8 @@ # Icons and SVG Illustrations -We manage our own Icon and Illustration library in the [`gitlab-svgs`][gitlab-svgs] repository. -This repository is published on [npm][npm] and managed as a dependency via yarn. -You can browse all available Icons and Illustrations [here][svg-preview]. +We manage our own Icon and Illustration library in the [`gitlab-svgs`](https://gitlab.com/gitlab-org/gitlab-svgs) repository. +This repository is published on [npm](https://www.npmjs.com/package/@gitlab/svgs) and managed as a dependency via yarn. +You can browse all available Icons and Illustrations [here](https://gitlab-org.gitlab.io/gitlab-svgs). To upgrade to a new version run `yarn upgrade @gitlab/svgs`. ## Icons @@ -22,7 +22,7 @@ sprite_icon(icon_name, size: nil, css_class: '') ``` - **icon_name** Use the icon_name that you can find in the SVG Sprite - ([Overview is available here][svg-preview]). + ([Overview is available here](https://gitlab-org.gitlab.io/gitlab-svgs)). - **size (optional)** Use one of the following sizes : 16, 24, 32, 48, 72 (this will be translated into a `s16` class) - **css_class (optional)** If you want to add additional css classes @@ -42,7 +42,7 @@ sprite_icon(icon_name, size: nil, css_class: '') ### Usage in Vue -[GitLab UI][gitlab-ui], our components library, provides a component to display sprite icons. +[GitLab UI](https://gitlab-org.gitlab.io/gitlab-ui/), our components library, provides a component to display sprite icons. Sample usage : @@ -65,7 +65,7 @@ export default { ``` -- **name** Name of the Icon in the SVG Sprite ([Overview is available here][svg-preview]). +- **name** Name of the Icon in the SVG Sprite ([Overview is available here](https://gitlab-org.gitlab.io/gitlab-svgs)). - **size (optional)** Number value for the size which is then mapped to a specific CSS class (Available Sizes: 8, 12, 16, 18, 24, 32, 48, 72 are mapped to `sXX` css classes) - **css-classes (optional)** Additional CSS Classes to add to the svg tag. @@ -111,8 +111,3 @@ export default { ``` - -[npm]: https://www.npmjs.com/package/@gitlab/svgs -[gitlab-svgs]: https://gitlab.com/gitlab-org/gitlab-svgs -[svg-preview]: https://gitlab-org.gitlab.io/gitlab-svgs -[gitlab-ui]: https://gitlab-org.gitlab.io/gitlab-ui/ diff --git a/doc/development/fe_guide/index.md b/doc/development/fe_guide/index.md index 790cd94cec4..8fd6ba459b9 100644 --- a/doc/development/fe_guide/index.md +++ b/doc/development/fe_guide/index.md @@ -5,17 +5,17 @@ across GitLab's frontend team. ## Overview -GitLab is built on top of [Ruby on Rails](https://rubyonrails.org) using [Haml][haml] and also a JavaScript based Frontend with [Vue.js](https://vuejs.org). -Be wary of [the limitations that come with using Hamlit][hamlit-limits]. We also use [SCSS](https://sass-lang.com) and plain JavaScript with -modern ECMAScript standards supported through [Babel][babel] and ES module support through [webpack][webpack]. +GitLab is built on top of [Ruby on Rails](https://rubyonrails.org) using [Haml](http://haml.info/) and also a JavaScript based Frontend with [Vue.js](https://vuejs.org). +Be wary of [the limitations that come with using Hamlit](https://github.com/k0kubun/hamlit/blob/master/REFERENCE.md#limitations). We also use [SCSS](https://sass-lang.com) and plain JavaScript with +modern ECMAScript standards supported through [Babel](https://babeljs.io/) and ES module support through [webpack](https://webpack.js.org/). Working with our frontend assets requires Node (v10.13.0 or greater) and Yarn (v1.10.0 or greater). You can find information on how to install these on our -[installation guide][install]. +[installation guide](../../install/installation.md#4-node). ### Browser Support -For our currently-supported browsers, see our [requirements][requirements]. +For our currently-supported browsers, see our [requirements](../../install/requirements.md#supported-web-browsers). Use [BrowserStack](https://www.browserstack.com/) to test with our supported browsers. Login to BrowserStack with the credentials saved in GitLab's [shared 1Password account](https://about.gitlab.com/handbook/security/#1password-for-teams). @@ -83,7 +83,7 @@ Read the [frontend's FAQ](frontend_faq.md) for common small pieces of helpful in See the relevant style guides for our guidelines and for information on linting: - [JavaScript](style/javascript.md). Our guide is based on -the excellent [Airbnb][airbnb-js-style-guide] style guide with a few small +the excellent [Airbnb](https://github.com/airbnb/javascript) style guide with a few small changes. - [SCSS](style/scss.md): our SCSS conventions which are enforced through [`scss-lint`](https://github.com/sds/scss-lint). - [HTML](style/html.md). Guidelines for writing HTML code consistent with the rest of the codebase. @@ -109,14 +109,3 @@ Our accessibility standards and resources. Frontend internationalization support is described in [this document](../i18n/). The [externalization part of the guide](../i18n/externalization.md) explains the helpers/methods available. - -[haml]: http://haml.info/ -[hamlit]: https://github.com/k0kubun/hamlit -[hamlit-limits]: https://github.com/k0kubun/hamlit/blob/master/REFERENCE.md#limitations -[babel]: https://babeljs.io/ -[webpack]: https://webpack.js.org/ -[jquery]: https://jquery.com/ -[axios]: https://github.com/axios/axios -[airbnb-js-style-guide]: https://github.com/airbnb/javascript -[install]: ../../install/installation.md#4-node -[requirements]: ../../install/requirements.md#supported-web-browsers diff --git a/doc/development/fe_guide/performance.md b/doc/development/fe_guide/performance.md index fcba8758c2f..aaa6bb16fab 100644 --- a/doc/development/fe_guide/performance.md +++ b/doc/development/fe_guide/performance.md @@ -41,9 +41,9 @@ But in general it should be handled automatically through a `MutationObserver` i Only animate `opacity` & `transform` properties. Other properties (such as `top`, `left`, `margin`, and `padding`) all cause Layout to be recalculated, which is much more expensive. For details on this, see "Styles that Affect Layout" in -[High Performance Animations][high-perf-animations]. +[High Performance Animations](https://www.html5rocks.com/en/tutorials/speed/high-performance-animations/). -If you _do_ need to change layout (e.g. a sidebar that pushes main content over), prefer [FLIP][flip] to change expensive +If you _do_ need to change layout (e.g. a sidebar that pushes main content over), prefer [FLIP](https://aerotwist.com/blog/flip-your-animations/) to change expensive properties once, and handle the actual animation with transforms. ## Reducing Asset Footprint @@ -160,18 +160,13 @@ General tips: - If some functionality can reasonably be achieved without adding extra libraries, avoid them. - Use page-specific JavaScript as described above to load libraries that are only needed on certain pages. - Use code-splitting dynamic imports wherever possible to lazy-load code that is not needed initially. -- [High Performance Animations][high-perf-animations] +- [High Performance Animations](https://www.html5rocks.com/en/tutorials/speed/high-performance-animations/) --- ## Additional Resources - [WebPage Test](https://www.webpagetest.org) for testing site loading time and size. -- [Google PageSpeed Insights][pagespeed-insights] grades web pages and provides feedback to improve the page. +- [Google PageSpeed Insights](https://developers.google.com/speed/pagespeed/insights/) grades web pages and provides feedback to improve the page. - [Profiling with Chrome DevTools](https://developers.google.com/web/tools/chrome-devtools/) -- [Browser Diet][browser-diet] is a community-built guide that catalogues practical tips for improving web page performance. - -[pagespeed-insights]: https://developers.google.com/speed/pagespeed/insights/ -[browser-diet]: https://browserdiet.com/ -[high-perf-animations]: https://www.html5rocks.com/en/tutorials/speed/high-performance-animations/ -[flip]: https://aerotwist.com/blog/flip-your-animations/ +- [Browser Diet](https://browserdiet.com/) is a community-built guide that catalogues practical tips for improving web page performance. diff --git a/doc/development/fe_guide/security.md b/doc/development/fe_guide/security.md index 7dba61d6b45..a001dd83ab7 100644 --- a/doc/development/fe_guide/security.md +++ b/doc/development/fe_guide/security.md @@ -2,8 +2,8 @@ ## Resources -[Mozilla’s HTTP Observatory CLI][observatory-cli] and the -[Qualys SSL Labs Server Test][qualys-ssl] are good resources for finding +[Mozilla’s HTTP Observatory CLI](https://github.com/mozilla/http-observatory-cli) and the +[Qualys SSL Labs Server Test](https://www.ssllabs.com/ssltest/analyze.html) are good resources for finding potential problems and ensuring compliance with security best practices. @@ -67,7 +67,7 @@ such as with reCAPTCHA, which cannot be used without an `iframe`. ## Avoiding inline scripts and styles -In order to protect users from [XSS vulnerabilities][xss], we will disable +In order to protect users from [XSS vulnerabilities](https://en.wikipedia.org/wiki/Cross-site_scripting), we will disable inline scripts in the future using Content Security Policy. While inline scripts can be useful, they're also a security concern. If @@ -77,16 +77,3 @@ inject scripts into the web app. Inline styles should be avoided in almost all cases, they should only be used when no alternatives can be found. This allows reusability of styles as well as readability. - -[observatory-cli]: https://github.com/mozilla/http-observatory-cli -[qualys-ssl]: https://www.ssllabs.com/ssltest/analyze.html -[secure_headers]: https://github.com/twitter/secureheaders -[mdn-csp]: https://developer.mozilla.org/en-US/docs/Web/Security/CSP -[github-eng-csp]: http://githubengineering.com/githubs-csp-journey/ -[dropbox-csp-1]: https://blogs.dropbox.com/tech/2015/09/on-csp-reporting-and-filtering/ -[dropbox-csp-2]: https://blogs.dropbox.com/tech/2015/09/unsafe-inline-and-nonce-deployment/ -[dropbox-csp-3]: https://blogs.dropbox.com/tech/2015/09/csp-the-unexpected-eval/ -[dropbox-csp-4]: https://blogs.dropbox.com/tech/2015/09/csp-third-party-integrations-and-privilege-separation/ -[mdn-sri]: https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity -[github-eng-sri]: http://githubengineering.com/subresource-integrity/ -[xss]: https://en.wikipedia.org/wiki/Cross-site_scripting diff --git a/doc/development/fe_guide/style/javascript.md b/doc/development/fe_guide/style/javascript.md index 7951c702601..b69a6f1941c 100644 --- a/doc/development/fe_guide/style/javascript.md +++ b/doc/development/fe_guide/style/javascript.md @@ -184,6 +184,9 @@ This can help to quickly understand the control flow. // bad if (isThingNull) return ''; +if (isThingNull) + return ''; + // good if (isThingNull) { return ''; @@ -192,7 +195,7 @@ if (isThingNull) { ## ESLint -ESLint behaviour can be found in our [tooling guide](../tooling.md). +ESLint behavior can be found in our [tooling guide](../tooling.md). ## IIFEs diff --git a/doc/development/fe_guide/style/scss.md b/doc/development/fe_guide/style/scss.md index 6c0247ad00c..336c9b8ca35 100644 --- a/doc/development/fe_guide/style/scss.md +++ b/doc/development/fe_guide/style/scss.md @@ -9,30 +9,25 @@ easy to maintain, and performant for the end-user. ## Rules +Our CSS is a mixture of current and legacy approaches. That means sometimes it may be difficult to follow this guide to the letter; it means you will definitely run into exceptions, where following the guide is difficult to impossible without outsized effort. In those cases, you may work with your reviewers and maintainers to identify an approach that does not fit these rules. Please endeavor to limit these cases. + ### Utility Classes -As part of the effort for [cleaning up our CSS and moving our components into `gitlab-ui`](https://gitlab.com/groups/gitlab-org/-/epics/950) -led by the [GitLab UI WG](https://gitlab.com/gitlab-com/www-gitlab-com/-/merge_requests/20623) we prefer the use of utility classes over adding new CSS. However, complex CSS can be addressed by adding component classes. +In order to reduce the generation of more CSS as our site grows, prefer the use of utility classes over adding new CSS. In complex cases, CSS can be addressed by adding component classes. #### Where are utility classes defined? -- [Bootstrap's Utility Classes](https://getbootstrap.com/docs/4.3/utilities/) -- [`common.scss`](https://gitlab.com/gitlab-org/gitlab/blob/master/app/assets/stylesheets/framework/common.scss) (old) -- [`utilities.scss`](https://gitlab.com/gitlab-org/gitlab/blob/master/app/assets/stylesheets/utilities.scss) (new) +Prefer the use of [utility classes defined in GitLab UI](https://gitlab.com/gitlab-org/gitlab-ui/-/blob/master/doc/css.md#utilities). An easy list of classes can also be [seen on Unpkg](https://unpkg.com/browse/@gitlab/ui/src/scss/utilities.scss). -#### Where should I put new utility classes? +Classes in [`utilities.scss`](https://gitlab.com/gitlab-org/gitlab/blob/master/app/assets/stylesheets/utilities.scss) and [`common.scss`](https://gitlab.com/gitlab-org/gitlab/blob/master/app/assets/stylesheets/framework/common.scss) are being deprecated. Classes in [`common.scss`](https://gitlab.com/gitlab-org/gitlab/blob/master/app/assets/stylesheets/framework/common.scss) that use non-design system values should be avoided in favor of conformant values. -New utility classes should be added to [`utilities.scss`](https://gitlab.com/gitlab-org/gitlab/blob/master/app/assets/stylesheets/utilities.scss). Existing classes include: +Avoid [Bootstrap's Utility Classes](https://getbootstrap.com/docs/4.3/utilities/). -| Name | Pattern | Example | -|------|---------|---------| -| Background color | `.bg-{variant}-{shade}` | `.bg-warning-400` | -| Text color | `.text-{variant}-{shade}` | `.text-success-500` | -| Font size | `.text-{size}` | `.text-2` | +#### Where should I put new utility classes? -- `{variant}` is one of 'primary', 'secondary', 'success', 'warning', 'error' -- `{shade}` is one of the shades listed on [colors](https://design.gitlab.com/product-foundations/colors/) -- `{size}` is a number from 1-6 from our [Type scale](https://design.gitlab.com/product-foundations/typography/) +If a class you need has not been added to GitLab UI, you get to add it! Follow the naming patterns documented in the [utility files](https://gitlab.com/gitlab-org/gitlab-ui/-/tree/master/src/scss/utility-mixins) and refer to [GitLab UI's CSS documentation](https://gitlab.com/gitlab-org/gitlab-ui/-/blob/master/doc/contributing/adding_css.md#adding-utility-mixins) for more details, especially about adding responsive and stateful rules. + +If it is not possible to wait for a GitLab UI update (generally one day), add the class to [`utilities.scss`](https://gitlab.com/gitlab-org/gitlab/blob/master/app/assets/stylesheets/utilities.scss) following the same naming conventions documented in GitLab UI. A follow—up issue to backport the class to GitLab UI and delete it from GitLab should be opened. #### When should I create component classes? @@ -77,6 +72,24 @@ CSS classes should use the `lowercase-hyphenated` format rather than } ``` +Class names should be used instead of tag name selectors. +Using tag name selectors are discouraged in CSS because +they can affect unintended elements in the hierarchy. +Also, since they are not meaningful names, they do not +add meaning to the code. + +```scss +// Bad +ul { + color: #fff; +} + +// Good +.class-name { + color: #fff; +} +``` + ### Formatting You should always use a space before a brace, braces should be on the same @@ -254,8 +267,8 @@ documentation includes [a full list of their linters](https://github.com/sds/scs ### Fixing issues If you want to automate changing a large portion of the codebase to conform to -the SCSS style guide, you can use [CSSComb][csscomb]. First install -[Node][node] and [NPM][npm], then run `npm install csscomb -g` to install +the SCSS style guide, you can use [CSSComb](https://github.com/csscomb/csscomb.js). First install +[Node](https://github.com/nodejs/node) and [NPM](https://www.npmjs.com/), then run `npm install csscomb -g` to install CSSComb globally (system-wide). Run it in the GitLab directory with `csscomb app/assets/stylesheets` to automatically fix issues with CSS/SCSS. @@ -279,7 +292,3 @@ Make sure a comment is added on the line above the `disable` rule, otherwise the linter will throw a warning. `DisableLinterReason` is enabled to make sure the style guide isn't being ignored, and to communicate to others why the style guide is ignored in this instance. - -[csscomb]: https://github.com/csscomb/csscomb.js -[node]: https://github.com/nodejs/node -[npm]: https://www.npmjs.com/ diff --git a/doc/development/fe_guide/style/vue.md b/doc/development/fe_guide/style/vue.md index a7d8fc61752..46305cc7217 100644 --- a/doc/development/fe_guide/style/vue.md +++ b/doc/development/fe_guide/style/vue.md @@ -53,7 +53,7 @@ Please check this [rules](https://github.com/vuejs/eslint-plugin-vue#bulb-rules) ## Naming -1. **Extensions**: Use `.vue` extension for Vue components. Do not use `.js` as file extension ([#34371]). +1. **Extensions**: Use `.vue` extension for Vue components. Do not use `.js` as file extension ([#34371](https://gitlab.com/gitlab-org/gitlab-foss/issues/34371)). 1. **Reference Naming**: Use PascalCase for their instances: ```javascript @@ -89,8 +89,6 @@ Please check this [rules](https://github.com/vuejs/eslint-plugin-vue#bulb-rules) ``` -[#34371]: https://gitlab.com/gitlab-org/gitlab-foss/issues/34371 - ## Alignment 1. Follow these alignment styles for the template method: @@ -327,7 +325,7 @@ When using `v-for` you need to provide a *unique* `:key` attribute for each item ``` -1. When the elements being iterated don't have a unique id, you can use the array index as the `:key` attribute +1. When the elements being iterated don't have a unique ID, you can use the array index as the `:key` attribute ```html
                    { - let vm; +describe('~/todos/app.vue', () => { + let wrapper; let mock; beforeEach(() => { - // Create a mock adapter for stubbing axios API requests + // IMPORTANT: Use axios-mock-adapter for stubbing axios API requests mock = new MockAdapter(axios); - - const Component = Vue.extend(component); - - // Mount the Component - vm = new Component().$mount(); + mock.onGet(TEST_TODO_PATH).reply(200, TEST_TODOS); + mock.onPost(TEST_TODO_PATH).reply(200); }); afterEach(() => { - // Reset the mock adapter - mock.restore(); - // Destroy the mounted component - vm.$destroy(); - }); + // IMPORTANT: Clean up the component instance and axios mock adapter + wrapper.destroy(); + wrapper = null; - it('should render the loading state while the request is being made', () => { - expect(vm.$el.querySelector('i.fa-spin')).toBeDefined(); + mock.restore(); }); - it('should render todos returned by the endpoint', done => { - // Mock the get request on the API endpoint to return data - mock.onGet('/todos').replyOnce(200, [ - { - title: 'This is a todo', - text: 'This is the text', + // NOTE: It is very helpful to separate setting up the component from + // its collaborators (i.e. Vuex, axios, etc.) + const createWrapper = (props = {}) => { + wrapper = shallowMount(App, { + propsData: { + path: TEST_TODO_PATH, + ...props, }, - ]); + }); + }; + // NOTE: Helper methods greatly help test maintainability and readability. + const findLoader = () => wrapper.find(GlLoadingIcon); + const findAddButton = () => wrapper.find('[data-testid="add-button"]'); + const findTextInput = () => wrapper.find('[data-testid="text-input"]'); + const findTodoData = () => wrapper.findAll('[data-testid="todo-item"]').wrappers.map(wrapper => ({ text: wrapper.text() })); + + describe('when mounted and loading', () => { + beforeEach(() => { + // Create request which will never resolve + mock.onGet(TEST_TODO_PATH).reply(() => new Promise(() => {})); + createWrapper(); + }); - Vue.nextTick(() => { - const items = vm.$el.querySelectorAll('.js-todo-list div') - expect(items.length).toBe(1); - expect(items[0].textContent).toContain('This is the text'); - done(); + it('should render the loading state', () => { + expect(findLoader().exists()).toBe(true); }); }); - it('should add a todos on button click', (done) => { + describe('when todos are loaded', () => { + beforeEach(() => { + createWrapper(); + // IMPORTANT: This component fetches data asynchronously on mount, so let's wait for the Vue template to update + return wrapper.vm.$nextTick(); + }); - // Mock the put request and check that the sent data object is correct - mock.onPut('/todos').replyOnce((req) => { - expect(req.data).toContain('text'); - expect(req.data).toContain('title'); + it('should not show loading', () => { + expect(findLoader().exists()).toBe(false); + }); - return [201, {}]; + it('should render todos', () => { + expect(findTodoData()).toEqual(TEST_TODOS); }); - vm.$el.querySelector('.js-add-todo').click(); + it('when todo is added, should post new todo', () => { + findTextInput().vm.$emit('update', TEST_NEW_TODO) + findAddButton().vm.$emit('click'); - // Add a new interceptor to mock the add Todo request - Vue.nextTick(() => { - expect(vm.$el.querySelectorAll('.js-todo-list div').length).toBe(2); - done(); + return wrapper.vm.$nextTick() + .then(() => { + expect(mock.history.post.map(x => JSON.parse(x.data))).toEqual([{ text: TEST_NEW_TODO }]); + }); }); }); }); ``` -### `mountComponent` helper +### Test the component's output -There is a helper in `spec/javascripts/helpers/vue_mount_component_helper.js` that allows you to mount a component with the given props: +The main return value of a Vue component is the rendered output. In order to test the component we +need to test the rendered output. [Vue](https://vuejs.org/v2/guide/unit-testing.html) guide's to unit test show us exactly that: + +### Events + +We should test for events emitted in response to an action within our component, this is useful to verify the correct events are being fired with the correct arguments. + +For any DOM events we should use [`trigger`](https://vue-test-utils.vuejs.org/api/wrapper/#trigger) to fire out event. ```javascript -import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper' -import component from 'component.vue' +// Assuming SomeButton renders: +wrapper = mount(SomeButton); -const Component = Vue.extend(component); -const data = {prop: 'foo'}; -const vm = mountComponent(Component, data); +... +it('should fire the click event', () => { + const btn = wrapper.find('button') + + btn.trigger('click'); + ... +}) ``` -### Test the component's output +When we need to fire a Vue event, we should use [`emit`](https://vuejs.org/v2/guide/components-custom-events.html) to fire our event. -The main return value of a Vue component is the rendered output. In order to test the component we -need to test the rendered output. [Vue][vue-test] guide's to unit test show us exactly that: +```javascript +wrapper = shallowMount(DropdownItem); + +... + +it('should fire the itemClicked event', () => { + DropdownItem.vm.$emit('itemClicked'); + ... +}) +``` + +We should verify an event has been fired by asserting against the result of the [`emitted()`](https://vue-test-utils.vuejs.org/api/wrapper/#emitted) method ## Vue.js Expert Role @@ -287,15 +326,50 @@ One should apply to be a Vue.js expert by opening an MR when the Merge Request's - Deep understanding of Vue and Vuex reactivity - Vue and Vuex code are structured according to both official and our guidelines - Full understanding of testing a Vue and Vuex application -- Vuex code follows the [documented pattern](vuex.md#actions-pattern-request-and-receive-namespaces) +- Vuex code follows the [documented pattern](vuex.md#naming-pattern-request-and-receive-namespaces) - Knowledge about the existing Vue and Vuex applications and existing reusable components -[issue-boards]: https://gitlab.com/gitlab-org/gitlab-foss/tree/master/app/assets/javascripts/boards -[environments-table]: https://gitlab.com/gitlab-org/gitlab-foss/tree/master/app/assets/javascripts/environments -[page_specific_javascript]: ./performance.md#page-specific-javascript -[component-system]: https://vuejs.org/v2/guide/#Composing-with-Components -[state-management]: https://vuejs.org/v2/guide/state-management.html#Simple-State-Management-from-Scratch -[one-way-data-flow]: https://vuejs.org/v2/guide/components.html#One-Way-Data-Flow -[vue-test]: https://vuejs.org/v2/guide/unit-testing.html -[flux]: https://facebook.github.io/flux/ -[axios]: https://github.com/axios/axios +## Vue 2 -> Vue 3 Migration + +> This section is added temporarily to support the efforts to migrate the codebase from Vue 2.x to Vue 3.x + +Currently, we recommend to minimize adding certain features to the codebase to prevent increasing the tech debt for the eventual migration: + +- filters; +- event buses; +- functional templated +- `slot` attributes + +You can find more details on [Migration to Vue 3](vue3_migration.md) + +## Appendix - Vue component subject under test + +This is the template for the example component which is tested in the [Testing Vue components](#testing-vue-components) section: + +```html + +``` diff --git a/doc/development/fe_guide/vue3_migration.md b/doc/development/fe_guide/vue3_migration.md new file mode 100644 index 00000000000..7ab48db7f76 --- /dev/null +++ b/doc/development/fe_guide/vue3_migration.md @@ -0,0 +1,124 @@ +# Migration to Vue 3 + +In order to prepare for the eventual migration to Vue 3.x, we should be wary about adding the following features to the codebase: + +## Vue filters + +**Why?** + +Filters [are removed](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0015-remove-filters.md) from the Vue 3 API completely. + +**What to use instead** + +Component's computed properties / methods or external helpers. + +## Event hub + +**Why?** + +`$on`, `$once`, and `$off` methods [are removed](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0020-events-api-change.md) from the Vue instance, so in Vue 3 it can't be used to create an event hub. + +**What to use instead** + +Vue docs recommend using [mitt](https://github.com/developit/mitt) library. It's relatively small (200 bytes gzipped) and has a simple API: + +```javascript +import mitt from 'mitt' + +const emitter = mitt() + +// listen to an event +emitter.on('foo', e => console.log('foo', e) ) + +// listen to all events +emitter.on('*', (type, e) => console.log(type, e) ) + +// fire an event +emitter.emit('foo', { a: 'b' }) + +// working with handler references: +function onFoo() {} + +emitter.on('foo', onFoo) // listen +emitter.off('foo', onFoo) // unlisten +``` + +**Event hub factory** + +To make it easier for you to migrate existing event hubs to the new recommended approach, or simply +to create new ones, we have created a factory that you can use to instantiate a new mitt-based +event hub. + +```javascript +import createEventHub from '~/helpers/event_hub_factory'; + +export default createEventHub(); +``` + +Event hubs created with the factory expose the same methods as Vue 2 event hubs (`$on`, `$once`, `$off` and +`$emit`), making them backward compatible with our previous approach. + +## \