Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-06-20 21:08:32 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-06-20 21:08:32 +0300
commit995bcca3fc5544e5d2d8ee274dc9275d5b4ce375 (patch)
tree370881ef6e9de8f93ce5546b725b2f91b4072a5f /doc
parenta5d7e614fe1d038a7f9e2af76106773b98e2b5e8 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'doc')
-rw-r--r--doc/api/releases/index.md2
-rw-r--r--doc/architecture/blueprints/gitlab_agent_deployments/index.md163
-rw-r--r--doc/development/ai_features.md37
-rw-r--r--doc/development/gems.md4
-rw-r--r--doc/development/testing_guide/best_practices.md134
-rw-r--r--doc/user/packages/composer_repository/index.md6
-rw-r--r--doc/user/project/members/index.md2
-rw-r--r--doc/user/public_access.md14
8 files changed, 192 insertions, 170 deletions
diff --git a/doc/api/releases/index.md b/doc/api/releases/index.md
index 86c23283588..3ec4b77a646 100644
--- a/doc/api/releases/index.md
+++ b/doc/api/releases/index.md
@@ -435,7 +435,7 @@ GET /projects/:id/releases/:tag_name/downloads/:direct_asset_path
Example request:
```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/24/releases/v0.1/downloads/bin/asset.exe"
+curl --location --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/24/releases/v0.1/downloads/bin/asset.exe"
```
### Get the latest release
diff --git a/doc/architecture/blueprints/gitlab_agent_deployments/index.md b/doc/architecture/blueprints/gitlab_agent_deployments/index.md
index d8d26389d7d..09c30da1077 100644
--- a/doc/architecture/blueprints/gitlab_agent_deployments/index.md
+++ b/doc/architecture/blueprints/gitlab_agent_deployments/index.md
@@ -1,11 +1,11 @@
---
-status: proposed
+status: implemented
creation-date: "2022-11-23"
authors: [ "@shinya.maeda" ]
coach: "@DylanGriffith"
approvers: [ "@nagyv-gitlab", "@cbalane", "@hustewart", "@hfyngvason" ]
-owning-stage: "~devops::release"
-participating-stages: [Configure, Release]
+owning-stage: "~devops::deploy"
+participating-stages: [Environments]
---
<!-- vale gitlab.FutureTense = NO -->
@@ -29,8 +29,6 @@ This blueprint describes how the association is established and how these domain
- The cluster resources and events can be visualized per [GitLab Environment](../../../ci/environments/index.md).
An environment-specific view scoped to the resources managed either directly or indirectly by a deployment commit.
- Support both [GitOps mode](../../../user/clusters/agent/gitops.md#gitops-configuration-reference) and [CI Access mode](../../../user/clusters/agent/ci_cd_workflow.md#authorize-the-agent).
- - NOTE: At the moment, we focus on the solution for CI Access mode. GitOps mode will have significant architectural changes _outside of_ this blueprint,
- such as [Flux switching](https://gitlab.com/gitlab-org/gitlab/-/issues/357947) and [Manifest projects outside of the Agent configuration project](https://gitlab.com/groups/gitlab-org/-/epics/7704). In order to derisk potential rework, we'll revisit the GitOps mode after these upstream changes have been settled.
### Non-Goals
@@ -41,22 +39,22 @@ This blueprint describes how the association is established and how these domain
### Overview
-- GitLab Environment and Agent-managed Resource Group have 1-to-1 relationship.
-- Agent-managed Resource Group tracks all resources produced by the connected [agent](../../../user/clusters/agent/index.md). This includes not only resources written in manifest files but also subsequently generated resources (e.g. `Pod`s created by `Deployment` manifest file).
-- Agent-managed Resource Group renders dependency graph, such as `Deployment` => `ReplicaSet` => `Pod`. This is for providing ArgoCD-style resource view.
-- Agent-managed Resource Group has the Resource Health status that represents a summary of resource statuses, such as `Healthy`, `Progressing` or `Degraded`.
+- GitLab Environment and GitLab Agent For Kubernetes have 1-to-1 relationship.
+- GitLab Environment tracks all resources produced by the connected [agent](../../../user/clusters/agent/index.md). This includes not only resources written in manifest files but also subsequently generated resources (for example, `Pod`s created by `Deployment` manifest file).
+- GitLab Environment renders dependency graph, such as `Deployment` => `ReplicaSet` => `Pod`. This is for providing ArgoCD-style resource view.
+- GitLab Environment has the Resource Health status that represents a summary of resource statuses, such as `Healthy`, `Progressing` or `Degraded`.
```mermaid
flowchart LR
subgraph Kubernetes["Kubernetes"]
- subgraph ResourceGroupProduction["ResourceGroup"]
+ subgraph ResourceGroupProduction["Production"]
direction LR
ResourceGroupProductionService(["Service"])
ResourceGroupProductionDeployment(["Deployment"])
ResourceGroupProductionPod1(["Pod1"])
ResourceGroupProductionPod2(["Pod2"])
end
- subgraph ResourceGroupStaging["ResourceGroup"]
+ subgraph ResourceGroupStaging["Staging"]
direction LR
ResourceGroupStagingService(["Service"])
ResourceGroupStagingDeployment(["Deployment"])
@@ -90,26 +88,18 @@ flowchart LR
- GitLab Project and Agent have 1-to-many _direct_ relationship. Only one project can own a specific agent.
- [GitOps mode](../../../user/clusters/agent/gitops.md#gitops-configuration-reference)
- GitLab Project and Agent do _NOT_ have many-to-many _indirect_ relationship yet. This will be supported in [Manifest projects outside of the Agent configuration project](https://gitlab.com/groups/gitlab-org/-/epics/7704).
- - Agent and Agent-managed Resource Group have 1-to-1 relationship. Inventory IDs are used to group Kubernetes resources. This might be changed in [Flux switching](https://gitlab.com/gitlab-org/gitlab/-/issues/357947).
- [CI Access mode](../../../user/clusters/agent/ci_cd_workflow.md#authorize-the-agent)
- GitLab Project and Agent have many-to-many _indirect_ relationship. The project owning the agent can [share the access with the other proejcts](../../../user/clusters/agent/ci_cd_workflow.md#authorize-the-agent-to-access-projects-in-your-groups). (NOTE: Technically, only running jobs inside the project are allowed to access the cluster due to job-token authentication.)
- - Agent and Agent-managed Resource Group do _NOT_ have relationships yet.
### Issues
-- Agent-managed Resource Group should have environment ID as the foreign key, which must be unique across resource groups.
-- Agent-managed Resource Group should have parameters how to group resources in the associated cluster, for example, `namespace`, `lable` and `inventory-id` (GitOps mode only) can passed as parameters.
-- Agent-managed Resource Group should be able to fetch all relevant resources, including both default resource kinds and other [Custom Resources](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/).
-- Agent-managed Resource Group should be aware of dependency graph.
-- Agent-managed Resource Group should be able to compute Resource Health status from the associated resources.
+- GitLab Environment should have ID of GitLab Agent For Kubernetes as the foreign key.
+- GitLab Environment should have parameters how to group resources in the associated cluster, for example, `namespace`, `lable` and `inventory-id` (GitOps mode only) can passed as parameters.
+- GitLab Environment should be able to fetch all relevant resources, including both default resource kinds and other [Custom Resources](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/).
+- GitLab Environment should be aware of dependency graph.
+- GitLab Environment should be able to compute Resource Health status from the associated resources.
-### Example: Pull-based deployment (GitOps mode)
-
-NOTE:
-At the moment, we focus on the solution for CI Access mode. GitOps mode will have significant architectural changes _outside of_ this blueprint,
-such as [Flux switching](https://gitlab.com/gitlab-org/gitlab/-/issues/357947) and [Manifest projects outside of the Agent configuration project](https://gitlab.com/groups/gitlab-org/-/epics/7704). In order to derisk potential rework, we'll revisit the GitOps mode after these upstream changes have been settled.
-
-### Example: Push-based deployment (CI access mode)
+### Example
This is an example of how the architecture works in push-based deployment.
The feature is documented [here](../../../user/clusters/agent/ci_cd_workflow.md) as CI access mode.
@@ -117,21 +107,21 @@ The feature is documented [here](../../../user/clusters/agent/ci_cd_workflow.md)
```mermaid
flowchart LR
subgraph ProductionKubernetes["Production Kubernetes"]
- subgraph ResourceGroupProductionFrontend["ResourceGroup"]
+ subgraph ResourceGroupProductionFrontend["Production"]
direction LR
ResourceGroupProductionFrontendService(["Service"])
ResourceGroupProductionFrontendDeployment(["Deployment"])
ResourceGroupProductionFrontendPod1(["Pod1"])
ResourceGroupProductionFrontendPod2(["Pod2"])
end
- subgraph ResourceGroupProductionBackend["ResourceGroup"]
+ subgraph ResourceGroupProductionBackend["Staging"]
direction LR
ResourceGroupProductionBackendService(["Service"])
ResourceGroupProductionBackendDeployment(["Deployment"])
ResourceGroupProductionBackendPod1(["Pod1"])
ResourceGroupProductionBackendPod2(["Pod2"])
end
- subgraph ResourceGroupProductionPrometheus["ResourceGroup"]
+ subgraph ResourceGroupProductionPrometheus["Monitoring"]
direction LR
ResourceGroupProductionPrometheusService(["Service"])
ResourceGroupProductionPrometheusDeployment(["Deployment"])
@@ -202,21 +192,21 @@ The microservice project setup can be improved by [Multi-Project Deployment Pipe
```mermaid
flowchart LR
subgraph ProductionKubernetes["Production Kubernetes"]
- subgraph ResourceGroupProductionFrontend["ResourceGroup"]
+ subgraph ResourceGroupProductionFrontend["Frontend"]
direction LR
ResourceGroupProductionFrontendService(["Service"])
ResourceGroupProductionFrontendDeployment(["Deployment"])
ResourceGroupProductionFrontendPod1(["Pod1"])
ResourceGroupProductionFrontendPod2(["Pod2"])
end
- subgraph ResourceGroupProductionBackend["ResourceGroup"]
+ subgraph ResourceGroupProductionBackend["Backend"]
direction LR
ResourceGroupProductionBackendService(["Service"])
ResourceGroupProductionBackendDeployment(["Deployment"])
ResourceGroupProductionBackendPod1(["Pod1"])
ResourceGroupProductionBackendPod2(["Pod2"])
end
- subgraph ResourceGroupProductionPrometheus["ResourceGroup"]
+ subgraph ResourceGroupProductionPrometheus["Monitoring"]
direction LR
ResourceGroupProductionPrometheusService(["Service"])
ResourceGroupProductionPrometheusDeployment(["Deployment"])
@@ -266,104 +256,18 @@ flowchart LR
DeploymentPipelines -- "Deploy" --> ResourceGroupProductionBackend
```
-#### View all Agent-managed Resource Groups on production environment
-
-At the group-level, we can accumulate all environments match a specific tier, for example,
-listing all environments with `production` tier from subsequent projects.
-This is useful to see the entire Agent-managed Resource Groups on production environment.
-The following diagram examplifies the relationship between GitLab group and Kubernetes resources:
-
-```mermaid
-flowchart LR
- subgraph Kubernetes["Kubernetes"]
- subgraph ResourceGroupProduction["ResourceGroup"]
- direction LR
- ResourceGroupProductionService(["Service"])
- ResourceGroupProductionDeployment(["Deployment"])
- ResourceGroupProductionPod1(["Pod1"])
- ResourceGroupProductionPod2(["Pod2"])
- end
- subgraph ResourceGroupStaging["ResourceGroup"]
- direction LR
- ResourceGroupStagingService(["Service"])
- ResourceGroupStagingDeployment(["Deployment"])
- ResourceGroupStagingPod1(["Pod1"])
- ResourceGroupStagingPod2(["Pod2"])
- end
- end
-
- subgraph GitLab
- subgraph Organization
- OrganizationProduction["All resources on production"]
- subgraph Frontend project
- FrontendEnvironmentProduction["production environment"]
- end
- subgraph Backend project
- BackendEnvironmentProduction["production environment"]
- end
- end
- end
-
- FrontendEnvironmentProduction --- ResourceGroupProduction
- BackendEnvironmentProduction --- ResourceGroupStaging
- ResourceGroupProductionService -.- ResourceGroupProductionDeployment
- ResourceGroupProductionDeployment -.- ResourceGroupProductionPod1
- ResourceGroupProductionDeployment -.- ResourceGroupProductionPod2
- ResourceGroupStagingService -.- ResourceGroupStagingDeployment
- ResourceGroupStagingDeployment -.- ResourceGroupStagingPod1
- ResourceGroupStagingDeployment -.- ResourceGroupStagingPod2
- OrganizationProduction --- FrontendEnvironmentProduction
- OrganizationProduction --- BackendEnvironmentProduction
-```
-
-A few notes:
-
-- In the future, we'd have more granular filters for resource search.
- For example, there are two environments `production/us-region` and `production/eu-region` in each project
- and show only resources in US region at the group-level.
- This could be achivable by query filtering in PostgreSQL or label/namespace filtering in Kubernetes.
-- Please see [Add dynamically populated organization-level environments page](https://gitlab.com/gitlab-org/gitlab/-/issues/241506) for more information.
-
## Design and implementation details
-NOTE:
-The following solution might be only applicable for CI Access mode. GitOps mode will have significant architectural changes _outside of_ this blueprint,
-such as [Flux switching](https://gitlab.com/gitlab-org/gitlab/-/issues/357947) and [Manifest projects outside of the Agent configuration project](https://gitlab.com/groups/gitlab-org/-/epics/7704). In order to derisk potential rework, we'll revisit the GitOps mode after these upstream changes have been settled.
-
### Associate Environment with Agent
-As a preliminary step, we allow users to explicitly define "which deployment job" uses "which agent" and deploy to "which namespace". The following keywords are supported in `.gitlab-ci.yml`.
-
-- `environment:kubernetes:agent` ... Define which agent the deployment job uses. It can select the appropriate context from the `KUBE_CONFIG`.
-- `environment:kubernetes:namespace` ... Define which namespace the deployment job deploys to. It injects `KUBE_NAMESPACE` predefined variable into the job. This keyword already [exists](../../../ci/yaml/index.md#environmentkubernetes).
-
-Here is an example of `.gitlab-ci.yml`.
-
-```yaml
-deploy-production:
- environment:
- name: production
- kubernetes:
- agent: path/to/agent/repository:agent-name
- namespace: default
- script:
- - helm --context="$KUBE_CONTEXT" --namespace="$KUBE_NAMESPACE" upgrade --install
-```
-
-When a deployment job is created, GitLab persists the relationship of specified agent, namespace and deployment job. If the CI job is NOT authorized to access the agent (Please refer [`Clusters::Agents::FilterAuthorizationsService`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/services/clusters/agents/filter_authorizations_service.rb) for more details), this relationship aren't recorded. This process happens in [`Deployments::CreateForBuildService`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/services/deployments/create_for_build_service.rb). The database table scheme is:
-
-```plaintext
-agent_deployments:
- - deployment_id (bigint/FK/NOT NULL/Unique)
- - agent_id (bigint/FK/NOT NULL)
- - kubernetes_namespace (character varying(255)/NOT NULL)
-```
+Users can explicitly set a GitLab Agent For Kubernetes to a GitLab Environment in setting UI.
+Frontend will use this associated agent for authenticating/authorizing the user access, which is described in a latter section.
-To idenfity an associated agent for a specific environment, `environment.last_deployment.agent` can be used in Rails.
+We need to adjust the `read_cluster_agent` permission in DeclarivePolicy for supporting agents shared by an external project (also known as the Agent management project).
### Fetch resources through `user_access`
-When user visits an environment page, GitLab frontend fetches an environment via GraphQL. Frontend additionally fetches the associated agent-ID and namespace through deployment relationship, which being tracked by the `agent_deployments` table.
+When user visits an environment page, GitLab frontend fetches an environment via GraphQL. Frontend additionally fetches the associated agent-ID and namespace.
Here is an example of GraphQL query:
@@ -373,12 +277,12 @@ Here is an example of GraphQL query:
id
environment(name: "<environment-name>") {
slug
- lastDeployment(status: SUCCESS) {
- agent {
- id
+ kubernetesNamespace
+ clusterAgent {
+ id
+ name
+ project {
name
- project
- kubernetesNamespace
}
}
}
@@ -388,12 +292,9 @@ Here is an example of GraphQL query:
GitLab frontend authenticate/authorize the user access with [browser cookie](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/kubernetes_user_access.md#browser-cookie-on-gitlab-frontend). If the access is forbidden, frontend shows an error message that `You don't have access to an agent that deployed to this environment. Please contact agent administrator if you are allowed in "user_access" in agent config file. See <troubleshooting-doc-link>`.
-After the user gained access to the agent, GitLab frontend fetches available API Resource list in the Kubernetes and fetches the resources with the following parameters:
+After the user gained access to the agent, GitLab frontend fetches specific Resource kinds (for example, `Deployment`, `Pod`) in the Kubernetes with the following parameters:
-- `namespace` ... `#{environment.lastDeployment.agent.kubernetesNamespace}`
-- `labels`
- - `app.gitlab.com/project_id=#{project.id}` _AND_
- - `app.gitlab.com/environment_slug: #{environment.slug}`
+- `namespace` ... `#{environment.kubernetesNamespace}`
If no resources are found, this is likely that the users have not embedded these lables into their resources. In this case, frontend shows an warning message `There are no resources found for the environment. Do resources have GitLab preserved labels? See <troubleshooting-doc-link>`.
diff --git a/doc/development/ai_features.md b/doc/development/ai_features.md
index c46117c4afd..21d5bb97d56 100644
--- a/doc/development/ai_features.md
+++ b/doc/development/ai_features.md
@@ -84,6 +84,43 @@ For features that use the embedding database, additional setup is needed.
1. Run `gdk reconfigure`
1. Run database migrations to create the embedding database
+### Set up GitLab Chat
+
+1. [Enable Anthropic API features](#configure-anthropic-access).
+1. [Enable OpenAI support](#configure-openai-access).
+1. [Ensure the embedding database is configured](#set-up-the-embedding-database).
+1. Enable feature specific feature flag.
+
+ ```ruby
+ Feature.enable(:gitlab_duo)
+ Feature.enable(:tanuki_bot)
+ Feature.enable(:ai_redis_cache)
+ ```
+
+1. Ensure that your current branch is up-to-date with `master`.
+1. To access the GitLab Chat interface, in the lower-left corner of any page, select **Help** and **Ask GitLab Chat**.
+
+#### Tips for local development
+
+1. When responses are taking too long to appear in the user interface, consider restarting Sidekiq by running `gdk restart rails-background-jobs`. If that doesn't work, try `gdk kill` and then `gdk start`.
+1. Alternatively, bypass Sidekiq entirely and run the chat service syncronously. This can help with debugging errors as GraphQL errors are now available in the network inspector instead of the Sidekiq logs.
+
+```diff
+diff --git a/ee/app/services/llm/chat_service.rb b/ee/app/services/llm/chat_service.rb
+index 5fa7ae8a2bc1..5fe996ba0345 100644
+--- a/ee/app/services/llm/chat_service.rb
++++ b/ee/app/services/llm/chat_service.rb
+@@ -5,7 +5,7 @@ class ChatService < BaseService
+ private
+
+ def perform
+- worker_perform(user, resource, :chat, options)
++ worker_perform(user, resource, :chat, options.merge(sync: true))
+ end
+
+ def valid?
+```
+
### Setup for GitLab documentation chat (legacy chat)
To populate the embedding database for GitLab chat:
diff --git a/doc/development/gems.md b/doc/development/gems.md
index d709e4ab223..caff4ea1b03 100644
--- a/doc/development/gems.md
+++ b/doc/development/gems.md
@@ -23,9 +23,9 @@ is the [lib/](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/) folder.
The **lib/** folder is a mix of code that is generic/universal, GitLab-specific, and tightly integrated with the rest of the codebase.
-Ask yourself the question: **can this code also be used in a Ruby project other than the current project?**.
+Ask yourself the question: **is this code generic or universal that can be done as a separate and small project?**.
If the answer is **Yes** you should strongly consider starting with creating a new Gem [in the same repo](#in-the-same-repo)
-and eventually evaluate whether to extract it as a separate repository.
+and eventually evaluate whether to extract it as a separate repository if its meant to be used by other projects.
## Advantages of using Gems
diff --git a/doc/development/testing_guide/best_practices.md b/doc/development/testing_guide/best_practices.md
index 02c8ad44033..01b92f3c33a 100644
--- a/doc/development/testing_guide/best_practices.md
+++ b/doc/development/testing_guide/best_practices.md
@@ -50,6 +50,32 @@ bundle exec guard
When using spring and guard together, use `SPRING=1 bundle exec guard` instead to make use of spring.
+### General guidelines
+
+- Use a single, top-level `RSpec.describe ClassName` block.
+- Use `.method` to describe class methods and `#method` to describe instance
+ methods.
+- Use `context` to test branching logic (`RSpec/AvoidConditionalStatements` Rubocop Cop - [MR](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/117152)).
+- Try to match the ordering of tests to the ordering in the class.
+- Try to follow the [Four-Phase Test](https://thoughtbot.com/blog/four-phase-test) pattern, using newlines
+ to separate phases.
+- Use `Gitlab.config.gitlab.host` rather than hard coding `'localhost'`.
+- Don't assert against the absolute value of a sequence-generated attribute (see
+ [Gotchas](../gotchas.md#do-not-assert-against-the-absolute-value-of-a-sequence-generated-attribute)).
+- Avoid using `expect_any_instance_of` or `allow_any_instance_of` (see
+ [Gotchas](../gotchas.md#avoid-using-expect_any_instance_of-or-allow_any_instance_of-in-rspec)).
+- Don't supply the `:each` argument to hooks because it's the default.
+- On `before` and `after` hooks, prefer it scoped to `:context` over `:all`.
+- When using `evaluate_script("$('.js-foo').testSomething()")` (or `execute_script`) which acts on a given element,
+ use a Capybara matcher beforehand (such as `find('.js-foo')`) to ensure the element actually exists.
+- Use `focus: true` to isolate parts of the specs you want to run.
+- Use [`:aggregate_failures`](https://rspec.info/features/3-12/rspec-core/expectation-framework-integration/aggregating-failures/) when there is more than one expectation in a test.
+- For [empty test description blocks](https://github.com/rubocop-hq/rspec-style-guide#it-and-specify), use `specify` rather than `it do` if the test is self-explanatory.
+- Use `non_existing_record_id`/`non_existing_record_iid`/`non_existing_record_access_level`
+ when you need an ID/IID/access level that doesn't actually exist. Using 123, 1234,
+ or even 999 is brittle as these IDs could actually exist in the database in the
+ context of a CI run.
+
### Eager loading the application code
By default, the application code:
@@ -132,9 +158,44 @@ We should reduce test dependencies, and avoiding
capabilities also reduces the amount of set-up needed.
`:js` is particularly important to avoid. This must only be used if the feature
-test requires JavaScript reactivity in the browser. Using a headless
+test requires JavaScript reactivity in the browser (e.g. clicking a Vue.js component). Using a headless
browser is much slower than parsing the HTML response from the app.
+#### Profiling: see where your test spend its time
+
+[`rspec-stackprof`](https://github.com/dkhroad/rspec-stackprof) can be used to generate a flame graph that shows you where you test spend its time.
+
+The gem generates a JSON report that we can upload to <https://www.speedscope.app> for an interactive visualization.
+
+##### Installation
+
+`stackprof` gem is [already installed with GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/695fcee0c5541b4ead0a90eb9b8bf0b69bee796c/Gemfile#L487), and we also have a script available that generates the JSON report (`bin/rspec-stackprof`).
+
+```shell
+# Optional: install the `speedscope` package to easily upload the JSON report to https://www.speedscope.app
+npm install -g speedscope
+```
+
+##### Generate the JSON report
+
+```shell
+bin/rspec-stackprof --speedscope=true <your_slow_spec>
+# There will be the name of the report displayed when the script ends.
+
+# Upload the JSON report to speedscope.app
+speedscope tmp/<your-json-report>.json
+```
+
+##### How to interpret the flamegraph
+
+Below are some useful tips to interpret and navigate the flamegraph:
+
+- There are [several views available](https://github.com/jlfwong/speedscope#views) for the flamegraph. `Left Heavy` is particularly useful when there are a lot of function calls (e.g. feature specs).
+- You can zoom in or out! See [the navigation documentation](https://github.com/jlfwong/speedscope#navigation)
+- If you are working on a slow feature test, search for `Capybara::DSL#` in the search to see the capybara actions that are made, and how long they take!
+
+See [#414929](https://gitlab.com/gitlab-org/gitlab/-/issues/414929#note_1425239887) or [#375004](https://gitlab.com/gitlab-org/gitlab/-/issues/375004#note_1109867718) for some analysis examples.
+
#### Optimize factory usage
A common cause of slow tests is excessive creation of objects, and thus
@@ -240,9 +301,21 @@ There are various ways to create objects and store them in variables in your tes
- `let` lazily creates the object. It isn't created until the object is called. `let` is generally inefficient as it creates a new object for every example. `let` is fine for simple values. However, more efficient variants of `let` are best when dealing with database models such as factories.
- `let_it_be_with_refind` works similar to `let_it_be_with_reload`, but the [former calls `ActiveRecord::Base#find`](https://github.com/test-prof/test-prof/blob/936b29f87b36f88a134e064aa6d8ade143ae7a13/lib/test_prof/ext/active_record_refind.rb#L15) instead of `ActiveRecord::Base#reload`. `reload` is usually faster than `refind`.
- `let_it_be_with_reload` creates an object one time for all examples in the same context, but after each example, the database changes are rolled back, and `object.reload` will be called to restore the object to its original state. This means you can make changes to the object before or during an example. However, there are cases where [state leaks across other models](https://github.com/test-prof/test-prof/blob/master/docs/recipes/let_it_be.md#state-leakage-detection) can occur. In these cases, `let` may be an easier option, especially if only a few examples exist.
-- `let_it_be` creates an immutable object one time for all of the examples in the same context. This is a great alternative to `let` and `let!` for objects that do not need to change from one example to another. Using `let_it_be` can dramatically speed up tests that create database models. See <https://github.com/test-prof/test-prof/blob/master/docs/recipes/let_it_be.md#let-it-be> for more details and examples.
+- `let_it_be` creates an object one time for all of the examples in the same context. This is a great alternative to `let` and `let!` for objects that do not need to change from one example to another. Using `let_it_be` can dramatically speed up tests that create database models. See <https://github.com/test-prof/test-prof/blob/master/docs/recipes/let_it_be.md#let-it-be> for more details and examples.
-`let_it_be` is the most optimized option since it instantiates an object once and does not change it. If you find yourself needing `let` instead of `let_it_be`, try `let_it_be_with_reload`.
+Pro-tip: When writing tests, it is best to consider the objects inside a `let_it_be` as **immutable**, as there are some important caveats when modifying objects inside a `let_it_be` declaration ([1](https://github.com/test-prof/test-prof/blob/master/docs/recipes/let_it_be.md#database-is-rolled-back-to-a-pristine-state-but-the-objects-are-not), [2](https://github.com/test-prof/test-prof/blob/master/docs/recipes/let_it_be.md#modifiers)). To make your `let_it_be` objects immutable, consider using `.freeze`:
+
+```shell
+# Before
+let_it_be(:namespace) { create_default(:namespace)
+
+# After
+let_it_be(:namespace) { create_default(:namespace).freeze
+```
+
+See <https://github.com/test-prof/test-prof/blob/master/docs/recipes/let_it_be.md#state-leakage-detection> for more information on `let_it_be` freezing.
+
+`let_it_be` is the most optimized option since it instantiates an object once and shares its instance across examples. If you find yourself needing `let` instead of `let_it_be`, try `let_it_be_with_reload`.
```ruby
# Old
@@ -336,6 +409,35 @@ NOTE:
Refrain from using this stub helper if the test code relies on persisting
`project_authorizations` or `Member` records. Use `Project#add_member` or `Group#add_member` instead.
+#### Additional profiling metrics
+
+We can use the `rspec_profiling` gem to diagnose, for instance, the number of SQL queries we're making when running a test.
+
+This could be caused by some application side SQL queries **triggered by a test that could mock parts that are not under test** (e.g. [!123810](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123810)).
+
+[See the instructions in the performance docs](../performance.md#rspec-profiling).
+
+#### Troubleshoot slow feature test
+
+A slow feature test can generally be optimized the same way as any other test. However, there are some specific techniques that can make the troubleshooting session more fruitful.
+
+##### See what the feature test is doing in the UI
+
+```shell
+# Before
+bin/rspec ./spec/features/admin/admin_settings_spec.rb:992
+
+# After
+WEBDRIVER_HEADLESS=0 bin/rspec ./spec/features/admin/admin_settings_spec.rb:992
+```
+
+See [Run `:js` spec in a visible browser](#run-js-spec-in-a-visible-browser) for more info.
+
+##### Search for `Capybara::DSL#` when using profiling
+
+<!-- TODO: Add the search keywords -->
+When using [`stackprof` flamegraphs](#profiling-see-where-your-test-spend-its-time), search for `Capybara::DSL#` in the search to see the capybara actions that are made, and how long they take!
+
#### Identify slow tests
Running a spec with profiling is a good way to start optimizing a spec. This can
@@ -437,32 +539,6 @@ performance gains.
When combining tests, consider using `:aggregate_failures`, so that the full
results are available, and not just the first failure.
-### General guidelines
-
-- Use a single, top-level `RSpec.describe ClassName` block.
-- Use `.method` to describe class methods and `#method` to describe instance
- methods.
-- Use `context` to test branching logic.
-- Try to match the ordering of tests to the ordering in the class.
-- Try to follow the [Four-Phase Test](https://thoughtbot.com/blog/four-phase-test) pattern, using newlines
- to separate phases.
-- Use `Gitlab.config.gitlab.host` rather than hard coding `'localhost'`
-- Don't assert against the absolute value of a sequence-generated attribute (see
- [Gotchas](../gotchas.md#do-not-assert-against-the-absolute-value-of-a-sequence-generated-attribute)).
-- Avoid using `expect_any_instance_of` or `allow_any_instance_of` (see
- [Gotchas](../gotchas.md#avoid-using-expect_any_instance_of-or-allow_any_instance_of-in-rspec)).
-- Don't supply the `:each` argument to hooks because it's the default.
-- On `before` and `after` hooks, prefer it scoped to `:context` over `:all`
-- When using `evaluate_script("$('.js-foo').testSomething()")` (or `execute_script`) which acts on a given element,
- use a Capybara matcher beforehand (such as `find('.js-foo')`) to ensure the element actually exists.
-- Use `focus: true` to isolate parts of the specs you want to run.
-- Use [`:aggregate_failures`](https://rspec.info/features/3-12/rspec-core/expectation-framework-integration/aggregating-failures/) when there is more than one expectation in a test.
-- For [empty test description blocks](https://github.com/rubocop-hq/rspec-style-guide#it-and-specify), use `specify` rather than `it do` if the test is self-explanatory.
-- Use `non_existing_record_id`/`non_existing_record_iid`/`non_existing_record_access_level`
- when you need an ID/IID/access level that doesn't actually exists. Using 123, 1234,
- or even 999 is brittle as these IDs could actually exist in the database in the
- context of a CI run.
-
### Feature category metadata
You must [set feature category metadata for each RSpec example](../feature_categorization/index.md#rspec-examples).
diff --git a/doc/user/packages/composer_repository/index.md b/doc/user/packages/composer_repository/index.md
index b990cf1f09b..c9d09e42532 100644
--- a/doc/user/packages/composer_repository/index.md
+++ b/doc/user/packages/composer_repository/index.md
@@ -142,7 +142,7 @@ To install a package:
- Connect to the Package Registry for your group:
```shell
- composer config repositories.<group_id> composer https://gitlab.example.com/api/v4/group/<group_id>/-/packages/composer/
+ composer config repositories.<group_id> composer https://gitlab.example.com/api/v4/group/<group_id>/-/packages/composer/packages.json
```
- Set the required package version:
@@ -159,7 +159,7 @@ To install a package:
"repositories": {
"<group_id>": {
"type": "composer",
- "url": "https://gitlab.example.com/api/v4/group/<group_id>/-/packages/composer/"
+ "url": "https://gitlab.example.com/api/v4/group/<group_id>/-/packages/composer/packages.json"
},
...
},
@@ -243,7 +243,7 @@ To install a package:
{
...
"repositories": [
- { "type": "composer", "url": "https://gitlab.example.com/api/v4/group/<group_id>/-/packages/composer/" }
+ { "type": "composer", "url": "https://gitlab.example.com/api/v4/group/<group_id>/-/packages/composer/packages.json" }
],
"config": {
...
diff --git a/doc/user/project/members/index.md b/doc/user/project/members/index.md
index 7a1d9d6e6e3..c67e40b75d6 100644
--- a/doc/user/project/members/index.md
+++ b/doc/user/project/members/index.md
@@ -69,7 +69,7 @@ If a user is:
### Membership and visibility rights
-Depending on their membership type, members of groups or projects are granted different visibility levels
+Depending on their membership type, members of groups or projects are granted different [visibility levels](../../../user/public_access.md)
and rights into the group or project.
| Action | Direct group member | Inherited group member | Direct shared group member | Inherited shared group member |
diff --git a/doc/user/public_access.md b/doc/user/public_access.md
index 002cb97dd93..4fdbde1f4f1 100644
--- a/doc/user/public_access.md
+++ b/doc/user/public_access.md
@@ -7,18 +7,24 @@ type: reference
# Project and group visibility **(FREE)**
-A project in GitLab can be private, internal, or public.
+Projects and groups in GitLab can be private, internal, or public.
+
+The visibility level of the group or project has no influence on whether members within the group or project can see each other.
+A group or project is an object to allow collaborative work. This is only possible if all members know about each other.
+
+Group or project members can see all members of the group or project they belong to.
+Group or project owners can see the origin of membership (the original group or project) of all members.
## Private projects and groups
-For private projects, only project members can:
+For private projects, only members of the private project or group can:
- Clone the project.
- View the public access directory (`/public`).
Users with the Guest role cannot clone the project.
-Private groups can have private subgroups only.
+Private groups can have only private subgroups.
## Internal projects and groups **(FREE SELF)**
@@ -27,6 +33,8 @@ For internal projects, **any authenticated user**, including users with the Gues
- Clone the project.
- View the public access directory (`/public`).
+Only internal members can view internal content.
+
[External users](admin_area/external_users.md) cannot clone the project.
Internal groups can have internal or private subgroups.