Single docs codebase
**Table of Contents** - [Important Background](#important-background) - [Description](#description) - [Why](#why) - [Needs](#needs) - [Potential solutions](#potential-solutions) - [Roadblocks](#roadblocks) - [API](#api) - [Images](#images) - [Split the work](#split-the-work) - [Pretty diff](#pretty-diff) - [MR workflow](#mr-workflow) - [EE specific lines check](#ee-specific-lines-check) ## Important Background Path to single codebase: - https://about.gitlab.com/handbook/engineering/infrastructure/blueprint/ce-ee-codebases/ - https://about.gitlab.com/handbook/engineering/infrastructure/design/merge-ce-ee-codebases/ --- This was previously discussed here https://gitlab.com/gitlab-org/gitlab-ce/issues/22617 however, this was before https://gitlab.com/gitlab-org/gitlab-ee/issues/2952 in which the [decision was made](https://gitlab.com/gitlab-org/gitlab-ee/issues/2952#note_41016454) to attempt to move to a single codebase. There were efforts made to [isolate EE-specific code](https://gitlab.com/gitlab-org/gitlab-ee/issues/3107) in preparation for this change. DZ suggested we make the CE repo read-only and generate it by running a rake task that removes EE code. People would be recommended to create issues and merge requests to the EE repo. The conversation culminated in a [draft blog post](https://gitlab.com/gitlab-org/gitlab-ee/issues/2952#note_61075265) by Sid in order to discuss this with the community, but I believe it was not posted and there has been no further progress. Since that conversation, Axil created this https://gitlab.com/gitlab-org/gitlab-ce/issues/46476 but it doesn't cover everything we need to discuss and consider, so I've created this new issue. **Note:** If the above suggestion by DZ occurs, we may need to switch the 'editable' set of docs to being stored in EE; this would either happen at the same time as the rest of the codebase does this, *or* we can do this right off the bat (in advance of the rest of the codebase), given that the docs have a separate license in CE and EE vs the rest of the code. ## Description We currently maintain two sets of docs: one in the [gitlab-ce repo](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc) and one in [gitlab-ee](https://gitlab.com/gitlab-org/gitlab-ee/tree/master/doc). They are similar, and some pages are identical, but they are different. Each set is published to our site, while also packaged with its respective version of GitLab (CE vs EE) and displayed under /help (which we [plan to remove](https://gitlab.com/groups/gitlab-org/-/epics/693), in favor of exclusively hosting docs on our site). See examples of: - [EE-only content](https://docs.gitlab.com/ee/administration/geo/replication/index.html). - [EE-only content also in CE](https://docs.gitlab.com/ce/workflow/repository_mirroring.html#pulling-from-a-remote-repository). While docs.gitlab.com now 'hides' the /ce path by preventing indexing and avoiding links to it, this only resolved some user confusion; it does not solve the problem that developers and technical writers frequently need to resolve conflicts between the two copies of the doc and the docs are generally more difficult to update. Simultaneously, we want to work on removing the documentation in the Help section from the Rails app - a.k.a. /help - so that all users will use docs.gitlab.com. ## Why Regardless of the single codebase effort, having different docs in CE and EE, causes the following problems: 1. Merge conflicts in the automatic ce-to-ee merge 1. Merge conflicts when you submit an MR to CE (the `ee_compat_check` job will check it) 1. Additional overhead for the tech writing group having to submit two MRs most of the time (since we add more and more features in EE and conflicts are unavoidable) 1. Confusion for contributors and team members where to put the docs (people are [contributing to EE for CE features](https://gitlab.com/gitlab-org/gitlab-ce/issues/22617#note_40258892)) Most importantly, people use the "Edit page" link if they want to know the source markdown file in order to make a contribution. That leads them to the EE project and they submit MRs there which in turn means missing docs in CE, as we only merge CE>EE and not vice versa. List of wrongly submitted MRs: <details> Here's a list of docs submitted to EE whereas all or parts of them should be in CE: 1. https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/1890 1. https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/2867 1. https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/2892 1. https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/2901 1. https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/2967 1. https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/3177#note_43900631 1. https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/3852#note_52199834 1. https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/4824 1. https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/5597 1. https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/6231 1. https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/6300 1. https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/6312 1. https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/6400 1. https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/6402 1. https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/6431 1. https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/6503 1. https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/6622 </details> ## Needs 1. [x] Inventory of all /ce docs and see if they differ from /ee 1. [x] Add new CI test regarding this change + that docs are being posted only to CE 1. [ ] Update our fixed MR templates 1. [ ] Make sure that all EE docs/headings have the EE tiers assigned to them https://gitlab.com/gitlab-org/gitlab-ce/issues/46475 1. [x] A diff of the docs (CE to EE) to determine how much work is involved in merging them => https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/21089 1. [x] A process to bring both sets of docs into alignment, while ensuring that all features are properly labeled with tiers. We can cross-check against features.yml. Can be done one path at a time, with work shared among the tech writers. (See further notes in [TW weekly agenda > 2018-08-08](https://docs.google.com/document/d/11Ekol_0tqt11aL_vbLWdFwS0x3Qlgn3dACJuMLagYjw/edit#heading=h.k0jpjfduzp6i)) 1. [x] Confirmation that the license of the docs is acceptable. All the product docs (CE/EE/Omnibus/Runner) are licensed under CC by SA 4.0 (https://gitlab.com/gitlab-org/gitlab-ce/issues/42891) to facilitate contributions from the community. 1. [ ] Plan for the API, for example, leave API content alone while working on a new Open API spec-based system that can differentiate CE and EE (see further notes in [TW weekly agenda > 2018-08-08](https://docs.google.com/document/d/11Ekol_0tqt11aL_vbLWdFwS0x3Qlgn3dACJuMLagYjw/edit#heading=h.k0jpjfduzp6i)) ## Solution In order to ensure a good experience by CE users, while mitigating the current problem: 1. Merge both sets, and build the docs from a single codebase (CE)*. Ensure that each doc and subsection specifies the tiers it applies to. We can further improve the user experience by: * Producing a new set of icons to place next to links, inline, when we link to an individual feature that's only available in some tiers, indicating availability. These could be hidden based on the user's tier selection. * Including front-matter metadata that indicates whether the page contains EE-only features, so that we can have a search option to exclude them. ## Roadblocks Below are some roadblocks, that we need to figure out before or during the merge. ### API The main concern is the API docs. Some EE API endpoints have more parameters than the CE counterparts, and this is an issue when we display the example response. For example: - [EE API for projects](https://docs.gitlab.com/ee/api/projects.html#list-all-projects): has the `"approvals_before_merge": 0,` line in the response. - [CE API for projects](https://docs.gitlab.com/ce/api/projects.html#list-all-projects): doesn't have the above line. If we merge EE into CE, then the example response for CE will be wrong. While we can add the tier badges next to words, there's no way to add this inside a json example. We'd need to do either one of the following (with ordering preference): - Use OpenAPI (swagger) to serve the CE/EE API with each GitLab version. There's a stale open MR about this https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/2397. All open issues about OpenAPI https://gitlab.com/gitlab-org/gitlab-ce/issues?scope=all&utf8=%E2%9C%93&state=opened&label_name[]=openapi. - Find a way to build this in the docs site. - Merge everything except the API docs. That would mean we would need to maintain two separate (almost identical) directories, and I'm not sure how we would serve this to the users under docs.gitlab.com. ### Images For features that include specific EE parts, like issue boards, a screenshot in EE might contain EE-specific features that the CE counterpart might not have. ## Split the work - [Issue board](https://gitlab.com/groups/gitlab-org/-/boards/981090?&label_name[]=Documentation&label_name[]=single%20codebase) - @axil is creating issues for each group here https://docs.google.com/spreadsheets/d/1tjsXAyiv9L32gJDYcNqB1KvgoyV0Ec3Lsb-mD3tuDCg/ and adding them to this epic and assigning them to technical writers and Mike roughly based on their applicable DevOps stages (but not a 1:1) <details> From the diff in https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/21089, I briefly checked what changed and how difficult that diff would be. In the table below, I added the most important docs dirs sorting them from easiest to most difficult. | Docs diffs | Comments | Issue | | ------ | ------ | ---- | | `doc/update/` | The easiest to merge. It mostly contains `doc/update/*-ce-to-ee.md` files. | https://gitlab.com/gitlab-org/gitlab-ce/issues/59150 | | `doc/workflow/` | Not much content, easy diff. Most of it, is either redirected, or EE-only. | https://gitlab.com/gitlab-org/gitlab-ce/issues/59151 | | `doc/integration/` | Easy diff. Most of the content is EE-only. | https://gitlab.com/gitlab-org/gitlab-ce/issues/59152 | | `doc/user/group` | Easy diff, mostly EE-only content. | https://gitlab.com/gitlab-org/gitlab-ce/issues/59153 | | `doc/user/admin_area` | Easy diff. Most of the content is EE-only. | https://gitlab.com/gitlab-org/gitlab-ce/issues/59155 | | `doc/administration/` | Much content, but most of it is EE-only. `doc/administration/high_availability/` is the trickiest part of it. | https://gitlab.com/gitlab-org/gitlab-ce/issues/59156 | | `doc/ci` | Average diff. EE-only files as well as mixed content of CE and EE. | https://gitlab.com/gitlab-org/gitlab-ce/issues/59157 | | `doc/user/project` | Much mixed content, will probably need to split into subsections. | https://gitlab.com/gitlab-org/gitlab-ce/issues/59159 | | `doc/install/installation.md` | When cloning the source, we'll need to have both options for the time being (gitlab-ce and gitlab-ee). Currently, both docs are the same, defaulting to CE! | | | `doc/api` | Difficult diff. The example responses are sometimes crucial to developers, and having EE content in CE API calls will be confusing. Let's leave this last. | https://gitlab.com/gitlab-org/gitlab-ce/issues/59160 | Some extra information in the table below. Note that some directories are a little worse than they seem, as some folders with multiple files are only counted once. | Dir | EE Only Files/Dirs | CE and EE files that differ | |-----|--------------------|-----------------------------| | `doc` | (see below) | 1 | | `doc/update/` | 67 | 82 | | `doc/workflow/` | 9 | 4 | | `doc/integration/` | 6 | 2 | | `doc/user/admin_area` | 5 | 5 | | `doc/user/group` | 6 | 1 | | `doc/user/project` | 33 | 20 | | `doc/user` (other) | 3 | 7 | | `doc/administration/` | 21 | 18 | | `doc/ci` | 8 | 14 | | `doc/install/` | 2 | 1 | | `doc/api` | 10 | 21 | | `doc/articles` | 1 | | | `doc/customization` | 1 | | | `doc/development` | 4 | 5 | | `doc/gitlab-basics` | | 1 | | `doc/legal` | | 2 | | `doc/policy` | | 1 | | `doc/raketasks` | | 1 | | `doc/topics` | | 2 | Directories in EE `doc` only: `analytics`, `git_hooks`, `gitlab-geo`, `license`, `push_rules`, `tools`. ## Pretty diff We can now see the docs diffs in https://leipert-projects.gitlab.io/is-gitlab-pretty-yet/diff/?search=%5Edoc. </details> ## MR workflow The following are stuff we gathered during our MR tests (e.g., https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/21089) (subject to change): 1. Locally copy EE dir to CE 1. Create MR 1. Using our documented EE/CE doc alignment standards: 1. Convert URLs to relative URLs. If a link fails the check because it does not exist yet in CE (from another to-be-merged section) keep absolute URL. We’ll do a find/replace later. 1. If a feature was only in EE and had no tier-specific badge, look up the feature and add one. If any question, ask relevant PM? 1. Create EE equivalent MR Do not redirect stuff at this phase. If there's a `README.md` that is ported to CE, the lint docs test will fail. Just fix the test by increasing the number of CE READMEs in `scripts/lint-doc.sh`. ## EE specific lines check Every time an MR that ports some EE docs to CE is merged, [`ee_specific_check.rb`](https://gitlab.com/gitlab-org/gitlab-ee/blob/master/scripts/ee_specific_check/ee_specific_check.rb) needs to be updated and the relevant paths commented out from the whitelist. That way, the EE specific lines check will run and catch any future EE-only changes. Here's the whole list of the EE doc directories as of 2019-04-26. This is the same list as used in [`ee_specific_check.rb`](https://gitlab.com/gitlab-org/gitlab-ee/blob/master/scripts/ee_specific_check/ee_specific_check.rb). Mark an item as solved as soon an MR is merged. Remaining: - [x] `doc/api/README.md` - [x] `doc/api/access_requests.md` - [x] `doc/api/applications.md` - [x] `doc/api/avatar.md` - [x] `doc/api/award_emoji.md` - [x] `doc/api/boards.md` - [x] `doc/api/branches.md` - [x] `doc/api/broadcast_messages.md` - [x] `doc/api/build_triggers.md` - [x] `doc/api/builds.md` - [x] `doc/api/commits.md` - [x] `doc/api/container_registry.md` - [x] `doc/api/custom_attributes.md` - [x] `doc/api/deploy_key_multiple_projects.md` - [x] `doc/api/deploy_keys.md` - [x] `doc/api/deployments.md` - [x] `doc/api/discussions.md` - [x] `doc/api/environments.md` - [x] `doc/api/epic_issues.md` - [x] `doc/api/epic_links.md` - [x] `doc/api/epics.md` - [x] `doc/api/events.md` - [x] `doc/api/features.md` - [x] `doc/api/geo_nodes.md` - [x] `doc/api/graphql/index.md` - [x] `doc/api/group_badges.md` - [x] `doc/api/group_boards.md` - [x] `doc/api/group_labels.md` - [x] `doc/api/group_level_variables.md` - [x] `doc/api/group_milestones.md` - [x] `doc/api/groups.md` - [x] `doc/api/import.md` - [x] `doc/api/issue_links.md` - [x] `doc/api/issues.md` - [x] `doc/api/jobs.md` - [x] `doc/api/keys.md` - [x] `doc/api/labels.md` - [x] `doc/api/license.md` - [x] `doc/api/license_templates.md` - [x] `doc/api/lint.md` - [x] `doc/api/managed_licenses.md` - [x] `doc/api/markdown.md` - [x] `doc/api/members.md` - [x] `doc/api/merge_request_approvals.md` - [x] `doc/api/merge_requests.md` - [x] `doc/api/milestones.md` - [x] `doc/api/namespaces.md` - [x] `doc/api/notes.md` - [x] `doc/api/notification_settings.md` - [x] `doc/api/oauth2.md` - [x] `doc/api/packages.md` - [x] `doc/api/pages_domains.md` - [x] `doc/api/pipeline_schedules.md` - [x] `doc/api/pipeline_triggers.md` - [x] `doc/api/pipelines.md` - [x] `doc/api/project_badges.md` - [x] `doc/api/project_clusters.md` - [x] `doc/api/project_import_export.md` - [x] `doc/api/project_level_variables.md` - [x] `doc/api/project_snippets.md` - [x] `doc/api/project_statistics.md` - [x] `doc/api/project_templates.md` - [x] `doc/api/projects.md` - [x] `doc/api/protected_branches.md` - [x] `doc/api/protected_tags.md` - [x] `doc/api/releases/index.md` - [x] `doc/api/releases/links.md` - [x] `doc/api/repositories.md` - [x] `doc/api/repository_files.md` - [x] `doc/api/repository_storage_health.md` - [x] `doc/api/repository_submodules.md` - [x] `doc/api/resource_label_events.md` - [x] `doc/api/runners.md` - [x] `doc/api/scim.md` - [x] `doc/api/search.md` - [x] `doc/api/services.md` - [x] `doc/api/settings.md` - [x] `doc/api/sidekiq_metrics.md` - [x] `doc/api/snippets.md` - [x] `doc/api/suggestions.md` - [x] `doc/api/system_hooks.md` - [x] `doc/api/tags.md` - [x] `doc/api/templates/dockerfiles.md` - [x] `doc/api/templates/gitignores.md` - [x] `doc/api/templates/gitlab_ci_ymls.md` - [x] `doc/api/templates/licenses.md` - [x] `doc/api/todos.md` - [x] `doc/api/users.md` - [x] `doc/api/v3_to_v4.md` - [x] `doc/api/version.md` - [x] `doc/api/vulnerabilities.md` - [x] `doc/api/wikis.md` --- Done: - [x] `doc/` - [x] `doc/administration/` - [x] `doc/administration/auth/` - [x] `doc/administration/auth/how_to_configure_ldap_gitlab_ce/` - [x] `doc/administration/auth/how_to_configure_ldap_gitlab_ee/` - [x] `doc/administration/geo/` - [x] `doc/administration/geo/disaster_recovery/` - [x] `doc/administration/geo/replication/` - [x] `doc/administration/gitaly/` - [x] `doc/administration/high_availability/` - [x] `doc/administration/integration/` - [x] `doc/administration/monitoring/` - [x] `doc/administration/monitoring/performance/` - [x] `doc/administration/monitoring/prometheus/` - [x] `doc/administration/operations/` - [x] `doc/administration/pages/` - [x] `doc/administration/raketasks/` - [x] `doc/administration/raketasks/uploads/` - [x] `doc/administration/troubleshooting/` - [x] `doc/analytics/` - [x] `doc/articles/` - [x] `doc/articles/artifactory_and_gitlab/` - [x] `doc/articles/how_to_configure_ldap_gitlab_ce/` - [x] `doc/articles/how_to_configure_ldap_gitlab_ee/` - [x] `doc/articles/how_to_install_git/` - [x] `doc/articles/laravel_with_gitlab_and_envoy/` - [x] `doc/articles/numerous_undo_possibilities_in_git/` - [x] `doc/articles/openshift_and_gitlab/` - [x] `doc/articles/runner_autoscale_aws/` - [x] `doc/ci/` - [x] `doc/ci/autodeploy/` - [x] `doc/ci/build_artifacts/` - [x] `doc/ci/caching/` - [x] `doc/ci/chatops/` - [x] `doc/ci/ci_cd_for_external_repos/` - [x] `doc/ci/docker/` - [x] `doc/ci/environments/` - [x] `doc/ci/examples/` - [x] `doc/ci/examples/artifactory_and_gitlab/` - [x] `doc/ci/examples/deploy_spring_boot_to_cloud_foundry/` - [x] `doc/ci/examples/deployment/` - [x] `doc/ci/examples/devops_and_game_dev_with_gitlab_ci_cd/` - [x] `doc/ci/examples/end_to_end_testing_webdriverio/` - [x] `doc/ci/examples/laravel_with_gitlab_and_envoy/` - [x] `doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/` - [x] `doc/ci/interactive_web_terminal/` - [x] `doc/ci/introduction/` - [x] `doc/ci/large_repositories/` - [x] `doc/ci/merge_request_pipelines/` - [x] `doc/ci/permissions/` - [x] `doc/ci/quick_start/` - [x] `doc/ci/review_apps/` - [x] `doc/ci/runners/` - [x] `doc/ci/services/` - [x] `doc/ci/ssh_keys/` - [x] `doc/ci/triggers/` - [x] `doc/ci/variables/` - [x] `doc/ci/yaml/` - [x] `doc/container_registry/` - [x] `doc/customization/` - [x] `doc/customization/branded_login_page/` - [x] `doc/customization/branded_page_and_email_header/` - [x] `doc/customization/favicon/` - [x] `doc/customization/help_message/` - [x] `doc/customization/new_project_page/` - [x] `doc/customization/system_header_and_footer_messages/` - [x] `doc/development/` - [x] `doc/development/contributing/` - [x] `doc/development/documentation/` - [x] `doc/development/documentation/site_architecture/` - [x] `doc/development/fe_guide/` - [x] `doc/development/fe_guide/droplab/` - [x] `doc/development/fe_guide/droplab/plugins/` - [x] `doc/development/go_guide/` - [x] `doc/development/i18n/` - [x] `doc/development/integrations/` - [x] `doc/development/new_fe_guide/` - [x] `doc/development/new_fe_guide/development/` - [x] `doc/development/new_fe_guide/modules/` - [x] `doc/development/new_fe_guide/style/` - [x] `doc/development/python_guide/` - [x] `doc/development/testing_guide/` - [x] `doc/development/ux_guide/` - [x] `doc/downgrade_ee_to_ce/` - [x] `doc/getting-started/` - [x] `doc/git_hooks/` - [x] `doc/gitlab-basics/` - [ ] `doc/gitlab-geo/` - [x] `doc/hooks/` - [x] `doc/incoming_email/` - [x] `doc/install/` - [x] `doc/install/aws/` - [x] `doc/install/azure/` - [x] `doc/install/google_cloud_platform/` - [x] `doc/install/kubernetes/` - [x] `doc/install/kubernetes/preparation/` - [x] `doc/install/openshift_and_gitlab/` - [x] `doc/install/pivotal/` - [x] `doc/integration/` - [x] `doc/integration/ldap/` - [x] `doc/intro/` - [x] `doc/legal/` - [x] `doc/license/` - [x] `doc/logs/` - [x] `doc/markdown/` - [x] `doc/migrate_ci_to_ce/` - [x] `doc/monitoring/` - [x] `doc/monitoring/performance/` - [x] `doc/operations/` - [x] `doc/pages/` - [x] `doc/permissions/` - [x] `doc/policy/` - [x] `doc/profile/` - [x] `doc/project_services/` - [x] `doc/public_access/` - [x] `doc/push_rules/` - [x] `doc/raketasks/` - [x] `doc/security/` - [x] `doc/ssh/` - [x] `doc/subscriptions/` - [x] `doc/system_hooks/` - [x] `doc/tools/` - [x] `doc/topics/` - [x] `doc/topics/authentication/` - [x] `doc/topics/autodevops/` - [x] `doc/topics/git/` - [x] `doc/topics/git/how_to_install_git/` - [x] `doc/topics/git/numerous_undo_possibilities_in_git/` - [x] `doc/university/` - [x] `doc/university/bookclub/` - [x] `doc/university/glossary/` - [x] `doc/university/high-availability/` - [x] `doc/university/high-availability/aws/` - [x] `doc/university/process/` - [x] `doc/university/support/` - [x] `doc/university/training/` - [x] `doc/university/training/end-user/` - [x] `doc/university/training/gitlab_flow/` - [x] `doc/university/training/topics/` - [x] `doc/update/` - [x] `doc/user/` - [x] `doc/user/account/` - [x] `doc/user/admin_area/` - [x] `doc/user/admin_area/monitoring/` - [x] `doc/user/admin_area/settings/` - [x] `doc/user/application_security/` - [x] `doc/user/application_security/container_scanning/` - [x] `doc/user/application_security/dast/` - [x] `doc/user/application_security/dependency_scanning/` - [x] `doc/user/application_security/license_management/` - [x] `doc/user/application_security/sast/` - [x] `doc/user/application_security/security_dashboard/` - [x] `doc/user/discussions/` - [x] `doc/user/gitlab_com/` - [x] `doc/user/group/` - [x] `doc/user/group/clusters/` - [x] `doc/user/group/contribution_analytics/` - [x] `doc/user/group/epics/` - [x] `doc/user/group/insights/` - [x] `doc/user/group/issues_analytics/` - [x] `doc/user/group/roadmap/` - [x] `doc/user/group/saml_sso/` - [x] `doc/user/group/security_dashboard/` - [x] `doc/user/group/subgroups/` - [x] `doc/user/instance_statistics/` - [x] `doc/user/operations_dashboard/` - [x] `doc/user/profile/` - [x] `doc/user/profile/account/` - [x] `doc/user/project/` - [x] `doc/user/project/builds/` - [x] `doc/user/project/clusters/` - [x] `doc/user/project/clusters/eks_and_gitlab/` - [x] `doc/user/project/clusters/runbooks/` - [x] `doc/user/project/clusters/serverless/` - [x] `doc/user/project/deploy_tokens/` - [x] `doc/user/project/gpg_signed_commits/` - [x] `doc/user/project/import/` - [x] `doc/user/project/insights/` - [x] `doc/user/project/integrations/` - [x] `doc/user/project/integrations/prometheus_library/` - [x] `doc/user/project/integrations/samples/` - [x] `doc/user/project/issues/` - [x] `doc/user/project/members/` - [x] `doc/user/project/merge_requests/` - [x] `doc/user/project/milestones/` - [x] `doc/user/project/operations/` - [x] `doc/user/project/packages/` - [x] `doc/user/project/pages/` - [x] `doc/user/project/pipelines/` - [x] `doc/user/project/releases/` - [x] `doc/user/project/repository/` - [x] `doc/user/project/repository/branches/` - [x] `doc/user/project/repository/gpg_signed_commits/` - [x] `doc/user/project/settings/` - [x] `doc/user/project/web_ide/` - [x] `doc/user/project/wiki/` - [x] `doc/user/search/` - [x] `doc/web_hooks/` - [x] `doc/workflow/` - [x] `doc/workflow/add-user/` - [x] `doc/workflow/forking/` - [x] `doc/workflow/importing/` - [x] `doc/workflow/issue_weight/` - [x] `doc/workflow/lfs/` - [x] `doc/workflow/lfs/images/` - [x] `doc/workflow/releases/` - [x] `doc/workflow/time-tracking/`
epic