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
diff options
context:
space:
mode:
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--app/assets/javascripts/clusters_list/components/agent_table.vue15
-rw-r--r--app/assets/javascripts/diffs/components/commit_item.vue10
-rw-r--r--app/assets/javascripts/diffs/components/diff_file_header.vue9
-rw-r--r--doc/administration/pages/index.md319
-rw-r--r--doc/administration/pages/troubleshooting.md304
-rw-r--r--doc/api/graphql/reference/index.md19
-rw-r--r--doc/architecture/blueprints/cells/index.md11
-rw-r--r--doc/ci/testing/accessibility_testing.md9
-rw-r--r--doc/development/fe_guide/vue.md81
-rw-r--r--doc/development/integrations/jira_connect.md34
-rw-r--r--doc/update/package/index.md2
-rw-r--r--doc/user/analytics/value_stream_analytics.md59
-rw-r--r--doc/user/packages/container_registry/reduce_container_registry_storage.md2
-rw-r--r--doc/user/project/pages/custom_domains_ssl_tls_certification/index.md72
-rw-r--r--doc/user/project/remote_development/index.md4
-rw-r--r--doc/user/project/repository/tags/index.md12
-rw-r--r--doc/user/project/web_ide/index.md10
-rw-r--r--doc/user/project/web_ide_beta/index.md5
-rw-r--r--lib/sidebars/concerns/super_sidebar_panel.rb2
-rw-r--r--lib/sidebars/menu.rb9
-rw-r--r--lib/sidebars/projects/menus/analytics_menu.rb15
-rw-r--r--lib/sidebars/projects/menus/repository_menu.rb17
-rw-r--r--lib/sidebars/projects/menus/security_compliance_menu.rb7
-rw-r--r--lib/sidebars/projects/menus/snippets_menu.rb3
-rw-r--r--lib/sidebars/projects/super_sidebar_menus/analyze_menu.rb34
-rw-r--r--lib/sidebars/projects/super_sidebar_menus/build_menu.rb19
-rw-r--r--lib/sidebars/projects/super_sidebar_menus/code_menu.rb33
-rw-r--r--lib/sidebars/projects/super_sidebar_menus/manage_menu.rb19
-rw-r--r--lib/sidebars/projects/super_sidebar_menus/monitor_menu.rb19
-rw-r--r--lib/sidebars/projects/super_sidebar_menus/operations_menu.rb2
-rw-r--r--lib/sidebars/projects/super_sidebar_menus/plan_menu.rb2
-rw-r--r--lib/sidebars/projects/super_sidebar_menus/secure_menu.rb34
-rw-r--r--lib/sidebars/projects/super_sidebar_panel.rb16
-rw-r--r--locale/gitlab.pot48
-rw-r--r--rubocop/cop/rspec/feature_category_on_shared_examples.rb45
-rw-r--r--spec/frontend/clusters_list/components/agent_table_spec.js12
-rw-r--r--spec/frontend/clusters_list/components/mock_data.js18
-rw-r--r--spec/frontend/diffs/components/commit_item_spec.js22
-rw-r--r--spec/lib/sidebars/concerns/super_sidebar_panel_spec.rb10
-rw-r--r--spec/lib/sidebars/menu_spec.rb41
-rw-r--r--spec/lib/sidebars/projects/menus/repository_menu_spec.rb45
-rw-r--r--spec/lib/sidebars/projects/menus/snippets_menu_spec.rb3
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_menus/analyze_menu_spec.rb29
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_menus/build_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_menus/code_menu_spec.rb28
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_menus/manage_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_menus/monitor_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_menus/operations_menu_spec.rb2
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_menus/plan_menu_spec.rb2
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_menus/secure_menu_spec.rb29
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_panel_spec.rb11
-rw-r--r--spec/rubocop/cop/rspec/feature_category_on_shared_examples_spec.rb30
53 files changed, 1117 insertions, 504 deletions
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 2927a9c0482..670f33bc30f 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-82da6c9eb6897bf3bbb7a791ba13a184f5679d24
+d41dacd832cc71860f8e069647b539880263392c
diff --git a/app/assets/javascripts/clusters_list/components/agent_table.vue b/app/assets/javascripts/clusters_list/components/agent_table.vue
index ef228370133..dbe2119fadb 100644
--- a/app/assets/javascripts/clusters_list/components/agent_table.vue
+++ b/app/assets/javascripts/clusters_list/components/agent_table.vue
@@ -14,6 +14,7 @@ import semverPrerelease from 'semver/functions/prerelease';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import timeagoMixin from '~/vue_shared/mixins/timeago';
import { helpPagePath } from '~/helpers/help_page_helper';
+import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { AGENT_STATUSES, I18N_AGENT_TABLE } from '../constants';
import { getAgentConfigPath } from '../clusters_util';
import DeleteAgentButton from './delete_agent_button.vue';
@@ -84,6 +85,11 @@ export default {
tdClass,
},
{
+ key: 'agentID',
+ label: this.$options.i18n.agentIdLabel,
+ tdClass,
+ },
+ {
key: 'configuration',
label: this.$options.i18n.configurationLabel,
tdClass,
@@ -119,6 +125,9 @@ export default {
getPopoverTestId(item) {
return `popover-${item.name}`;
},
+ getAgentId(item) {
+ return getIdFromGraphQLId(item.id);
+ },
getAgentConfigPath,
getAgentVersions(agent) {
const agentConnections = agent.connections?.nodes || [];
@@ -276,6 +285,12 @@ export default {
</gl-popover>
</template>
+ <template #cell(agentID)="{ item }">
+ <span data-testid="cluster-agent-id">
+ {{ getAgentId(item) }}
+ </span>
+ </template>
+
<template #cell(configuration)="{ item }">
<span data-testid="cluster-agent-configuration-link">
<gl-link v-if="item.configFolder" :href="item.configFolder.webPath">
diff --git a/app/assets/javascripts/diffs/components/commit_item.vue b/app/assets/javascripts/diffs/components/commit_item.vue
index 1857ff557e6..d050f2fb9ae 100644
--- a/app/assets/javascripts/diffs/components/commit_item.vue
+++ b/app/assets/javascripts/diffs/components/commit_item.vue
@@ -1,5 +1,5 @@
<script>
-import { GlButtonGroup, GlButton, GlTooltipDirective } from '@gitlab/ui';
+import { GlButtonGroup, GlButton, GlTooltipDirective, GlFormCheckbox } from '@gitlab/ui';
import SafeHtml from '~/vue_shared/directives/safe_html';
import CommitPipelineStatus from '~/projects/tree/components/commit_pipeline_status_component.vue';
@@ -30,6 +30,7 @@ export default {
CommitPipelineStatus,
GlButtonGroup,
GlButton,
+ GlFormCheckbox,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -117,12 +118,11 @@ export default {
</div>
<div>
<div class="d-flex float-left align-items-center align-self-start">
- <input
+ <gl-form-checkbox
v-if="isSelectable"
- class="gl-mr-3"
- type="checkbox"
:checked="checked"
- @change="$emit('handleCheckboxChange', $event.target.checked)"
+ class="gl-mt-3"
+ @change="$emit('handleCheckboxChange', !checked)"
/>
<user-avatar-link
:link-href="authorUrl"
diff --git a/app/assets/javascripts/diffs/components/diff_file_header.vue b/app/assets/javascripts/diffs/components/diff_file_header.vue
index 16f45c3ad6a..7b736b6c668 100644
--- a/app/assets/javascripts/diffs/components/diff_file_header.vue
+++ b/app/assets/javascripts/diffs/components/diff_file_header.vue
@@ -50,6 +50,7 @@ export default {
i18n: {
...DIFF_FILE_HEADER,
compareButtonLabel: __('Compare submodule commit revisions'),
+ fileModeTooltip: __('File permissions'),
},
props: {
discussionPath: {
@@ -342,7 +343,13 @@ export default {
data-track-property="diff_copy_file"
/>
- <small v-if="isModeChanged" ref="fileMode" class="mr-1">
+ <small
+ v-if="isModeChanged"
+ ref="fileMode"
+ v-gl-tooltip.hover
+ class="mr-1"
+ :title="$options.i18n.fileModeTooltip"
+ >
{{ diffFile.a_mode }} → {{ diffFile.b_mode }}
</small>
diff --git a/doc/administration/pages/index.md b/doc/administration/pages/index.md
index a0adc8cbf64..eec7b73f2b3 100644
--- a/doc/administration/pages/index.md
+++ b/doc/administration/pages/index.md
@@ -2,7 +2,6 @@
stage: Plan
group: Knowledge
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
-description: 'Learn how to administer GitLab Pages.'
---
# GitLab Pages administration **(FREE SELF)**
@@ -818,7 +817,7 @@ From [GitLab 13.3 to GitLab 13.12](#domain-source-configuration-before-140) GitL
Starting from [GitLab 14.0](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/5993) GitLab Pages uses API
by default and fails to start if it can't connect to it.
-For common issues, see the [troubleshooting section](#failed-to-connect-to-the-internal-gitlab-api).
+For common issues, see [troubleshooting](troubleshooting.md#failed-to-connect-to-the-internal-gitlab-api).
For more details see this [blog post](https://about.gitlab.com/blog/2020/08/03/how-gitlab-pages-uses-the-gitlab-api-to-serve-content/).
@@ -895,7 +894,7 @@ configuration is tried to be resolved automatically before reporting an error.
> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/5577) in GitLab 13.6.
-[Read more about using object storage with GitLab](../object_storage.md).
+For more information, see [object storage](../object_storage.md).
### Object storage settings
@@ -1100,8 +1099,8 @@ In GitLab 14.0 a number of breaking changes were introduced which may require so
The steps below describe the best way to migrate without causing any downtime for your GitLab instance.
A GitLab instance running on a single server typically upgrades to 14.0 smoothly, and there should be minimal issues after the upgrade is complete.
-Regardless, we recommend everyone follow the migration steps to ensure a successful upgrade.
-If at any point you run into issues, consult the [troubleshooting section](#troubleshooting).
+Regardless, you should follow the migration steps to ensure a successful upgrade.
+For common issues, see [troubleshooting](troubleshooting.md).
If your current GitLab version is lower than 13.12, then you must first update to 13.12.
Updating directly to 14.0 is [not supported](../../update/index.md#upgrade-paths)
@@ -1184,313 +1183,3 @@ Rate limits are enforced using the following:
```
1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
-
-<!-- ## Troubleshooting
-
-Include any troubleshooting steps that you can foresee. If you know beforehand what issues
-one might have when setting this up, or when something is changed, or on upgrading, it's
-important to describe those, too. Think of things that may go wrong and include them in
-the section below.
-This is important to minimize requests for support, and to avoid doc comments with
-questions that you know someone might ask.
-
-Each scenario can be a third-level heading, for example `### Getting error message X`.
-If you have none to add when creating a doc, leave this section in place
-but commented out to help encourage others to add to it in the future. -->
-
-## Troubleshooting
-
-### How to see GitLab Pages logs
-
-You can see Pages daemon logs by running:
-
-```shell
-sudo gitlab-ctl tail gitlab-pages
-```
-
-You can also find the log file in `/var/log/gitlab/gitlab-pages/current`.
-
-### `unsupported protocol scheme \"\""`
-
-If you see the following error:
-
-```plaintext
-{"error":"failed to connect to internal Pages API: Get \"/api/v4/internal/pages/status\": unsupported protocol scheme \"\"","level":"warning","msg":"attempted to connect to the API","time":"2021-06-23T20:03:30Z"}
-```
-
-It means you didn't set the HTTP(S) protocol scheme in the Pages server settings.
-To fix it:
-
-1. Edit `/etc/gitlab/gitlab.rb`:
-
- ```ruby
- gitlab_pages['gitlab_server'] = "https://<your_pages_domain_name>"
- gitlab_pages['internal_gitlab_server'] = "https://<your_pages_domain_name>"
- ```
-
-1. Reconfigure GitLab:
-
- ```shell
- sudo gitlab-ctl reconfigure
- ```
-
-### 502 error when connecting to GitLab Pages proxy when server does not listen over IPv6
-
-In some cases, NGINX might default to using IPv6 to connect to the GitLab Pages
-service even when the server does not listen over IPv6. You can identify when
-this is happening if you see something similar to the log entry below in the
-`gitlab_pages_error.log`:
-
-```plaintext
-2020/02/24 16:32:05 [error] 112654#0: *4982804 connect() failed (111: Connection refused) while connecting to upstream, client: 123.123.123.123, server: ~^(?<group>.*)\.pages\.example\.com$, request: "GET /-/group/project/-/jobs/1234/artifacts/artifact.txt HTTP/1.1", upstream: "http://[::1]:8090//-/group/project/-/jobs/1234/artifacts/artifact.txt", host: "group.example.com"
-```
-
-To resolve this, set an explicit IP and port for the GitLab Pages `listen_proxy` setting
-to define the explicit address that the GitLab Pages daemon should listen on:
-
-```ruby
-gitlab_pages['listen_proxy'] = '127.0.0.1:8090'
-```
-
-### Intermittent 502 errors or after a few days
-
-If you run Pages on a system that uses `systemd` and
-[`tmpfiles.d`](https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html),
-you may encounter intermittent 502 errors trying to serve Pages with an error similar to:
-
-```plaintext
-dial tcp: lookup gitlab.example.com on [::1]:53: dial udp [::1]:53: connect: no route to host"
-```
-
-GitLab Pages creates a [bind mount](https://man7.org/linux/man-pages/man8/mount.8.html)
-inside `/tmp/gitlab-pages-*` that includes files like `/etc/hosts`.
-However, `systemd` may clean the `/tmp/` directory on a regular basis so the DNS
-configuration may be lost.
-
-To stop `systemd` from cleaning the Pages related content:
-
-1. Tell `tmpfiles.d` to not remove the Pages `/tmp` directory:
-
- ```shell
- echo 'x /tmp/gitlab-pages-*' >> /etc/tmpfiles.d/gitlab-pages-jail.conf
- ```
-
-1. Restart GitLab Pages:
-
- ```shell
- sudo gitlab-ctl restart gitlab-pages
- ```
-
-### Unable to access GitLab Pages
-
-If you can't access your GitLab Pages (such as receiving `502 Bad Gateway` errors, or a login loop)
-and in your Pages log shows this error:
-
-```plaintext
-"error":"retrieval context done: context deadline exceeded","host":"root.docs-cit.otenet.gr","level":"error","msg":"could not fetch domain information from a source"
-```
-
-1. Add the following to `/etc/gitlab/gitlab.rb`:
-
- ```ruby
- gitlab_pages['internal_gitlab_server'] = 'http://localhost:8080'
- ```
-
-1. Restart GitLab Pages:
-
- ```shell
- sudo gitlab-ctl restart gitlab-pages
- ```
-
-### Failed to connect to the internal GitLab API
-
-If you see the following error:
-
-```plaintext
-ERRO[0010] Failed to connect to the internal GitLab API after 0.50s error="failed to connect to internal Pages API: HTTP status: 401"
-```
-
-If you are [Running GitLab Pages on a separate server](#running-gitlab-pages-on-a-separate-server)
-you must copy the `/etc/gitlab/gitlab-secrets.json` file
-from the **GitLab server** to the **Pages server** after upgrading to GitLab 13.3,
-as described in that section.
-
-Other reasons may include network connectivity issues between your
-**GitLab server** and your **Pages server** such as firewall configurations or closed ports.
-For example, if there is a connection timeout:
-
-```plaintext
-error="failed to connect to internal Pages API: Get \"https://gitlab.example.com:3000/api/v4/internal/pages/status\": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)"
-```
-
-### Pages cannot communicate with an instance of the GitLab API
-
-If you use the default value for `domain_config_source=auto` and run multiple instances of GitLab
-Pages, you may see intermittent 502 error responses while serving Pages content. You may also see
-the following warning in the Pages logs:
-
-```plaintext
-WARN[0010] Pages cannot communicate with an instance of the GitLab API. Please sync your gitlab-secrets.json file https://gitlab.com/gitlab-org/gitlab-pages/-/issues/535#workaround. error="pages endpoint unauthorized"
-```
-
-This can happen if your `gitlab-secrets.json` file is out of date between GitLab Rails and GitLab
-Pages. Follow steps 8-10 of [Running GitLab Pages on a separate server](#running-gitlab-pages-on-a-separate-server),
-in all of your GitLab Pages instances.
-
-### Intermittent 502 errors when using an AWS Network Load Balancer and GitLab Pages
-
-Connections will time out when using a Network Load Balancer with client IP preservation enabled and [the request is looped back to the source server](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-troubleshooting.html#loopback-timeout).
-This can happen to GitLab instances with multiple servers
-running both the core GitLab application and GitLab Pages. This can also happen when a single
-container is running both the core GitLab application and GitLab Pages.
-
-AWS [recommends using an IP target type](https://aws.amazon.com/premiumsupport/knowledge-center/target-connection-fails-load-balancer/)
-to resolve this issue.
-
-Turning off [client IP preservation](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html#client-ip-preservation)
-may resolve this issue when the core GitLab application and GitLab Pages run on the same host or
-container.
-
-### 500 error with `securecookie: failed to generate random iv` and `Failed to save the session`
-
-This problem most likely results from an [out-dated operating system](../package_information/supported_os.md#os-versions-that-are-no-longer-supported).
-The [Pages daemon uses the `securecookie` library](https://gitlab.com/search?group_id=9970&project_id=734943&repository_ref=master&scope=blobs&search=securecookie&snippets=false) to get random strings via [`crypto/rand` in Go](https://pkg.go.dev/crypto/rand#pkg-variables).
-This requires the `getrandom` system call or `/dev/urandom` to be available on the host OS.
-Upgrading to an [officially supported operating system](https://about.gitlab.com/install/) is recommended.
-
-### The requested scope is invalid, malformed, or unknown
-
-This problem comes from the permissions of the GitLab Pages OAuth application. To fix it:
-
-1. On the top bar, select **Main menu > Admin**.
-1. On the left sidebar, select **Applications > GitLab Pages**.
-1. Edit the application.
-1. Under **Scopes**, ensure that the `api` scope is selected.
-1. Save your changes.
-
-When running a [separate Pages server](#running-gitlab-pages-on-a-separate-server),
-this setting needs to be configured on the main GitLab server.
-
-### Workaround in case no wildcard DNS entry can be set
-
-If the wildcard DNS [prerequisite](#prerequisites) can't be met, you can still use GitLab Pages in a limited fashion:
-
-1. [Move](../../user/project/settings/index.md#transfer-a-project-to-another-namespace)
- all projects you need to use Pages with into a single group namespace, for example `pages`.
-1. Configure a [DNS entry](#dns-configuration) without the `*.`-wildcard, for example `pages.example.io`.
-1. Configure `pages_external_url http://example.io/` in your `gitlab.rb` file.
- Omit the group namespace here, because it automatically is prepended by GitLab.
-
-### Pages daemon fails with permission denied errors
-
-If `/tmp` is mounted with `noexec`, the Pages daemon fails to start with an error like:
-
-```plaintext
-{"error":"fork/exec /gitlab-pages: permission denied","level":"fatal","msg":"could not create pages daemon","time":"2021-02-02T21:54:34Z"}
-```
-
-In this case, change `TMPDIR` to a location that is not mounted with `noexec`. Add the following to
-`/etc/gitlab/gitlab.rb`:
-
-```ruby
-gitlab_pages['env'] = {'TMPDIR' => '<new_tmp_path>'}
-```
-
-Once added, reconfigure with `sudo gitlab-ctl reconfigure` and restart GitLab with
-`sudo gitlab-ctl restart`.
-
-### `The redirect URI included is not valid.` when using Pages Access Control
-
-You may see this error if `pages_external_url` was updated at some point of time. Verify the following:
-
-1. The **Callback URL**/Redirect URI in the GitLab Pages [System OAuth application](../../integration/oauth_provider.md#create-an-instance-wide-application)
-is using the protocol (HTTP or HTTPS) that `pages_external_url` is configured to use.
-1. The domain and path components of `Redirect URI` are valid: they should look like `projects.<pages_external_url>/auth`.
-
-### 500 error `cannot serve from disk`
-
-If you get a 500 response from Pages and encounter an error similar to:
-
-```plaintext
-ERRO[0145] cannot serve from disk error="gitlab: disk access is disabled via enable-disk=false" project_id=27 source_path="file:///shared/pages/@hashed/67/06/670671cd97404156226e507973f2ab8330d3022ca96e0c93bdbdb320c41adcaf/pages_deployments/14/artifacts.zip" source_type=zip
-```
-
-It means that GitLab Rails is telling GitLab Pages to serve content from a location on disk,
-however, GitLab Pages was configured to disable disk access.
-
-To enable disk access:
-
-1. Enable disk access for GitLab Pages in `/etc/gitlab/gitlab.rb`:
-
- ```ruby
- gitlab_pages['enable_disk'] = true
- ```
-
-1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
-
-### `httprange: new resource 403`
-
-If you see an error similar to:
-
-```plaintext
-{"error":"httprange: new resource 403: \"403 Forbidden\"","host":"root.pages.example.com","level":"error","msg":"vfs.Root","path":"/pages1/","time":"2021-06-10T08:45:19Z"}
-```
-
-And you run pages on the separate server syncing files via NFS, it may mean that
-the shared pages directory is mounted on a different path on the main GitLab server and the
-GitLab Pages server.
-
-In that case, it's highly recommended you to configure
-[object storage and migrate any existing pages data to it](#using-object-storage).
-
-Alternatively, you can mount the GitLab Pages shared directory to the same path on
-both servers.
-
-### GitLab Pages doesn't work after upgrading to GitLab 14.0 or above
-
-GitLab 14.0 introduces a number of changes to GitLab Pages which may require manual intervention.
-
-1. Firstly [follow the migration guide](#prepare-gitlab-pages-for-140).
-1. Try to upgrade to GitLab 14.3 or above. Some of the issues were fixed in GitLab 14.1, 14.2 and 14.3.
-1. If it doesn't work, see [GitLab Pages logs](#how-to-see-gitlab-pages-logs), and if you see any errors there then search them on this page.
-
-WARNING:
-In GitLab 14.0-14.2 you can temporarily enable legacy storage and configuration mechanisms.
-
-To do that:
-
-1. Describe the issue you're seeing in the [migration feedback issue](https://gitlab.com/gitlab-org/gitlab/-/issues/331699).
-
-1. Edit `/etc/gitlab/gitlab.rb`:
-
- ```ruby
- gitlab_pages['use_legacy_storage'] = true
- ```
-
-1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
-
-### GitLab Pages deploy job fails with error "is not a recognized provider"
-
-If the **pages** job succeeds but the **deploy** job gives the error "is not a recognized provider":
-
-![Pages Deploy Failure](img/pages_deploy_failure_v14_8.png)
-
-The error message `is not a recognized provider` could be coming from the `fog` gem that GitLab uses to connect to cloud providers for object storage.
-
-To fix that:
-
-1. Check your `gitlab.rb` file. If you have `gitlab_rails['pages_object_store_enabled']` enabled, but no bucket details have been configured, either:
-
- - Configure object storage for your Pages deployments, following the [S3-compatible connection settings](#s3-compatible-connection-settings) guide.
- - Store your deployments locally, by commenting out that line.
-
-1. Save the changes you made to your `gitlab.rb` file, then [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
-
-### 404 error `The page you're looking for could not be found`
-
-If you get a `404 Page Not Found` response from GitLab Pages:
-
-1. Check `.gitlab-ci.yml` contains the job `pages:`.
-1. Check the current project's pipeline to confirm the job `pages:deploy` is being run.
-
-Without the `pages:deploy` job, the updates to your GitLab Pages site are never published.
diff --git a/doc/administration/pages/troubleshooting.md b/doc/administration/pages/troubleshooting.md
new file mode 100644
index 00000000000..6cc851a3335
--- /dev/null
+++ b/doc/administration/pages/troubleshooting.md
@@ -0,0 +1,304 @@
+---
+stage: Plan
+group: Knowledge
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
+---
+
+# Troubleshooting GitLab Pages administration **(FREE SELF)**
+
+This page contains a list of issues you might encounter when administering GitLab Pages.
+
+## How to see GitLab Pages logs
+
+You can see Pages daemon logs by running:
+
+```shell
+sudo gitlab-ctl tail gitlab-pages
+```
+
+You can also find the log file in `/var/log/gitlab/gitlab-pages/current`.
+
+## `unsupported protocol scheme \"\""`
+
+If you see the following error:
+
+```plaintext
+{"error":"failed to connect to internal Pages API: Get \"/api/v4/internal/pages/status\": unsupported protocol scheme \"\"","level":"warning","msg":"attempted to connect to the API","time":"2021-06-23T20:03:30Z"}
+```
+
+It means you didn't set the HTTP(S) protocol scheme in the Pages server settings.
+To fix it:
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_pages['gitlab_server'] = "https://<your_pages_domain_name>"
+ gitlab_pages['internal_gitlab_server'] = "https://<your_pages_domain_name>"
+ ```
+
+1. Reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+## 502 error when connecting to GitLab Pages proxy when server does not listen over IPv6
+
+In some cases, NGINX might default to using IPv6 to connect to the GitLab Pages
+service even when the server does not listen over IPv6. You can identify when
+this is happening if you see something similar to the log entry below in the
+`gitlab_pages_error.log`:
+
+```plaintext
+2020/02/24 16:32:05 [error] 112654#0: *4982804 connect() failed (111: Connection refused) while connecting to upstream, client: 123.123.123.123, server: ~^(?<group>.*)\.pages\.example\.com$, request: "GET /-/group/project/-/jobs/1234/artifacts/artifact.txt HTTP/1.1", upstream: "http://[::1]:8090//-/group/project/-/jobs/1234/artifacts/artifact.txt", host: "group.example.com"
+```
+
+To resolve this, set an explicit IP and port for the GitLab Pages `listen_proxy` setting
+to define the explicit address that the GitLab Pages daemon should listen on:
+
+```ruby
+gitlab_pages['listen_proxy'] = '127.0.0.1:8090'
+```
+
+## Intermittent 502 errors or after a few days
+
+If you run Pages on a system that uses `systemd` and
+[`tmpfiles.d`](https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html),
+you may encounter intermittent 502 errors trying to serve Pages with an error similar to:
+
+```plaintext
+dial tcp: lookup gitlab.example.com on [::1]:53: dial udp [::1]:53: connect: no route to host"
+```
+
+GitLab Pages creates a [bind mount](https://man7.org/linux/man-pages/man8/mount.8.html)
+inside `/tmp/gitlab-pages-*` that includes files like `/etc/hosts`.
+However, `systemd` may clean the `/tmp/` directory on a regular basis so the DNS
+configuration may be lost.
+
+To stop `systemd` from cleaning the Pages related content:
+
+1. Tell `tmpfiles.d` to not remove the Pages `/tmp` directory:
+
+ ```shell
+ echo 'x /tmp/gitlab-pages-*' >> /etc/tmpfiles.d/gitlab-pages-jail.conf
+ ```
+
+1. Restart GitLab Pages:
+
+ ```shell
+ sudo gitlab-ctl restart gitlab-pages
+ ```
+
+## Unable to access GitLab Pages
+
+If you can't access your GitLab Pages (such as receiving `502 Bad Gateway` errors, or a login loop)
+and in your Pages log shows this error:
+
+```plaintext
+"error":"retrieval context done: context deadline exceeded","host":"root.docs-cit.otenet.gr","level":"error","msg":"could not fetch domain information from a source"
+```
+
+1. Add the following to `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_pages['internal_gitlab_server'] = 'http://localhost:8080'
+ ```
+
+1. Restart GitLab Pages:
+
+ ```shell
+ sudo gitlab-ctl restart gitlab-pages
+ ```
+
+## Failed to connect to the internal GitLab API
+
+If you see the following error:
+
+```plaintext
+ERRO[0010] Failed to connect to the internal GitLab API after 0.50s error="failed to connect to internal Pages API: HTTP status: 401"
+```
+
+If you are [Running GitLab Pages on a separate server](index.md#running-gitlab-pages-on-a-separate-server)
+you must copy the `/etc/gitlab/gitlab-secrets.json` file
+from the **GitLab server** to the **Pages server** after upgrading to GitLab 13.3,
+as described in that section.
+
+Other reasons may include network connectivity issues between your
+**GitLab server** and your **Pages server** such as firewall configurations or closed ports.
+For example, if there is a connection timeout:
+
+```plaintext
+error="failed to connect to internal Pages API: Get \"https://gitlab.example.com:3000/api/v4/internal/pages/status\": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)"
+```
+
+## Pages cannot communicate with an instance of the GitLab API
+
+If you use the default value for `domain_config_source=auto` and run multiple instances of GitLab
+Pages, you may see intermittent 502 error responses while serving Pages content. You may also see
+the following warning in the Pages logs:
+
+```plaintext
+WARN[0010] Pages cannot communicate with an instance of the GitLab API. Please sync your gitlab-secrets.json file https://gitlab.com/gitlab-org/gitlab-pages/-/issues/535#workaround. error="pages endpoint unauthorized"
+```
+
+This can happen if your `gitlab-secrets.json` file is out of date between GitLab Rails and GitLab
+Pages. Follow steps 8-10 of [Running GitLab Pages on a separate server](index.md#running-gitlab-pages-on-a-separate-server),
+in all of your GitLab Pages instances.
+
+## Intermittent 502 errors when using an AWS Network Load Balancer and GitLab Pages
+
+Connections will time out when using a Network Load Balancer with client IP preservation enabled and [the request is looped back to the source server](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-troubleshooting.html#loopback-timeout).
+This can happen to GitLab instances with multiple servers
+running both the core GitLab application and GitLab Pages. This can also happen when a single
+container is running both the core GitLab application and GitLab Pages.
+
+AWS [recommends using an IP target type](https://aws.amazon.com/premiumsupport/knowledge-center/target-connection-fails-load-balancer/)
+to resolve this issue.
+
+Turning off [client IP preservation](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html#client-ip-preservation)
+may resolve this issue when the core GitLab application and GitLab Pages run on the same host or
+container.
+
+## 500 error with `securecookie: failed to generate random iv` and `Failed to save the session`
+
+This problem most likely results from an [out-dated operating system](../package_information/supported_os.md#os-versions-that-are-no-longer-supported).
+The [Pages daemon uses the `securecookie` library](https://gitlab.com/search?group_id=9970&project_id=734943&repository_ref=master&scope=blobs&search=securecookie&snippets=false) to get random strings via [`crypto/rand` in Go](https://pkg.go.dev/crypto/rand#pkg-variables).
+This requires the `getrandom` system call or `/dev/urandom` to be available on the host OS.
+Upgrading to an [officially supported operating system](https://about.gitlab.com/install/) is recommended.
+
+## The requested scope is invalid, malformed, or unknown
+
+This problem comes from the permissions of the GitLab Pages OAuth application. To fix it:
+
+1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, select **Applications > GitLab Pages**.
+1. Edit the application.
+1. Under **Scopes**, ensure that the `api` scope is selected.
+1. Save your changes.
+
+When running a [separate Pages server](index.md#running-gitlab-pages-on-a-separate-server),
+this setting needs to be configured on the main GitLab server.
+
+## Workaround in case no wildcard DNS entry can be set
+
+If the wildcard DNS [prerequisite](index.md#prerequisites) can't be met, you can still use GitLab Pages in a limited fashion:
+
+1. [Move](../../user/project/settings/index.md#transfer-a-project-to-another-namespace)
+ all projects you need to use Pages with into a single group namespace, for example `pages`.
+1. Configure a [DNS entry](index.md#dns-configuration) without the `*.`-wildcard, for example `pages.example.io`.
+1. Configure `pages_external_url http://example.io/` in your `gitlab.rb` file.
+ Omit the group namespace here, because it automatically is prepended by GitLab.
+
+## Pages daemon fails with permission denied errors
+
+If `/tmp` is mounted with `noexec`, the Pages daemon fails to start with an error like:
+
+```plaintext
+{"error":"fork/exec /gitlab-pages: permission denied","level":"fatal","msg":"could not create pages daemon","time":"2021-02-02T21:54:34Z"}
+```
+
+In this case, change `TMPDIR` to a location that is not mounted with `noexec`. Add the following to
+`/etc/gitlab/gitlab.rb`:
+
+```ruby
+gitlab_pages['env'] = {'TMPDIR' => '<new_tmp_path>'}
+```
+
+Once added, reconfigure with `sudo gitlab-ctl reconfigure` and restart GitLab with
+`sudo gitlab-ctl restart`.
+
+## `The redirect URI included is not valid.` when using Pages Access Control
+
+You may see this error if `pages_external_url` was updated at some point of time. Verify the following:
+
+1. The **Callback URL**/Redirect URI in the GitLab Pages [System OAuth application](../../integration/oauth_provider.md#create-an-instance-wide-application)
+is using the protocol (HTTP or HTTPS) that `pages_external_url` is configured to use.
+1. The domain and path components of `Redirect URI` are valid: they should look like `projects.<pages_external_url>/auth`.
+
+## 500 error `cannot serve from disk`
+
+If you get a 500 response from Pages and encounter an error similar to:
+
+```plaintext
+ERRO[0145] cannot serve from disk error="gitlab: disk access is disabled via enable-disk=false" project_id=27 source_path="file:///shared/pages/@hashed/67/06/670671cd97404156226e507973f2ab8330d3022ca96e0c93bdbdb320c41adcaf/pages_deployments/14/artifacts.zip" source_type=zip
+```
+
+It means that GitLab Rails is telling GitLab Pages to serve content from a location on disk,
+however, GitLab Pages was configured to disable disk access.
+
+To enable disk access:
+
+1. Enable disk access for GitLab Pages in `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_pages['enable_disk'] = true
+ ```
+
+1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+
+## `httprange: new resource 403`
+
+If you see an error similar to:
+
+```plaintext
+{"error":"httprange: new resource 403: \"403 Forbidden\"","host":"root.pages.example.com","level":"error","msg":"vfs.Root","path":"/pages1/","time":"2021-06-10T08:45:19Z"}
+```
+
+And you run pages on the separate server syncing files via NFS, it may mean that
+the shared pages directory is mounted on a different path on the main GitLab server and the
+GitLab Pages server.
+
+In that case, it's highly recommended you to configure
+[object storage and migrate any existing pages data to it](index.md#using-object-storage).
+
+Alternatively, you can mount the GitLab Pages shared directory to the same path on
+both servers.
+
+## GitLab Pages doesn't work after upgrading to GitLab 14.0 or above
+
+GitLab 14.0 introduces a number of changes to GitLab Pages which may require manual intervention.
+
+1. Firstly [follow the migration guide](index.md#prepare-gitlab-pages-for-140).
+1. Try to upgrade to GitLab 14.3 or above. Some of the issues were fixed in GitLab 14.1, 14.2 and 14.3.
+1. If it doesn't work, see [GitLab Pages logs](#how-to-see-gitlab-pages-logs), and if you see any errors there then search them on this page.
+
+WARNING:
+In GitLab 14.0-14.2 you can temporarily enable legacy storage and configuration mechanisms.
+
+To do that:
+
+1. Describe the issue you're seeing in the [migration feedback issue](https://gitlab.com/gitlab-org/gitlab/-/issues/331699).
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_pages['use_legacy_storage'] = true
+ ```
+
+1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+
+## GitLab Pages deploy job fails with error "is not a recognized provider"
+
+If the **pages** job succeeds but the **deploy** job gives the error "is not a recognized provider":
+
+![Pages Deploy Failure](img/pages_deploy_failure_v14_8.png)
+
+The error message `is not a recognized provider` could be coming from the `fog` gem that GitLab uses to connect to cloud providers for object storage.
+
+To fix that:
+
+1. Check your `gitlab.rb` file. If you have `gitlab_rails['pages_object_store_enabled']` enabled, but no bucket details have been configured, either:
+
+ - Configure object storage for your Pages deployments, following the [S3-compatible connection settings](index.md#s3-compatible-connection-settings) guide.
+ - Store your deployments locally, by commenting out that line.
+
+1. Save the changes you made to your `gitlab.rb` file, then [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+
+## 404 error `The page you're looking for could not be found`
+
+If you get a `404 Page Not Found` response from GitLab Pages:
+
+1. Check `.gitlab-ci.yml` contains the job `pages:`.
+1. Check the current project's pipeline to confirm the job `pages:deploy` is being run.
+
+Without the `pages:deploy` job, the updates to your GitLab Pages site are never published.
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 126ba7f16e7..c7a44667364 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -5341,6 +5341,25 @@ Input type: `SecurityFindingCreateIssueInput`
| <a id="mutationsecurityfindingcreateissueerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationsecurityfindingcreateissueissue"></a>`issue` | [`Issue`](#issue) | Issue created after mutation. |
+### `Mutation.securityFindingCreateMergeRequest`
+
+Input type: `SecurityFindingCreateMergeRequestInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationsecurityfindingcreatemergerequestclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationsecurityfindingcreatemergerequestuuid"></a>`uuid` | [`String!`](#string) | UUID of the security finding to be used to create a merge request. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationsecurityfindingcreatemergerequestclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationsecurityfindingcreatemergerequesterrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+| <a id="mutationsecurityfindingcreatemergerequestmergerequest"></a>`mergeRequest` | [`MergeRequest`](#mergerequest) | Merge Request created after mutation. |
+
### `Mutation.securityFindingDismiss`
Input type: `SecurityFindingDismissInput`
diff --git a/doc/architecture/blueprints/cells/index.md b/doc/architecture/blueprints/cells/index.md
index 54244265b30..f3839d54e09 100644
--- a/doc/architecture/blueprints/cells/index.md
+++ b/doc/architecture/blueprints/cells/index.md
@@ -164,12 +164,17 @@ self-managed instances.
A number of technical issues need to be resolved to implement Cells (in no particular order). This section will be expanded.
-1. How are users of an organization routed to the correct Cell?
-1. How do users authenticate?
+1. How are Cells provisioned? - [Design discussion](https://gitlab.com/gitlab-org/gitlab/-/issues/396641)
+1. What is a Cells topology? - [Design discussion](https://gitlab.com/gitlab-org/gitlab/-/issues/396641)
+1. How are users of an organization routed to the correct Cell? -
+1. How do users authenticate with Cells and Organizations? - [Design discussion](https://gitlab.com/gitlab-org/gitlab/-/issues/395736)
1. How are Cells rebalanced?
-1. How are Cells provisioned?
1. How can Cells implement disaster recovery capabilities?
+## Decision log
+
+- 2022-03-15: Google Cloud as the cloud service. [Reference](https://gitlab.com/gitlab-org/gitlab/-/issues/396641#note_1314932272)
+
## Cross-section impact
Cells is a fundamental architecture change that impacts other sections and stages. This section summarizes and links to other groups that may be impacted and highlights potential conflicts that need to be resolved. The Tenant Scale group is not responsible for achieving the goals of other groups but we want to ensure that dependencies are resolved.
diff --git a/doc/ci/testing/accessibility_testing.md b/doc/ci/testing/accessibility_testing.md
index 58bb4308095..ee833ea4a74 100644
--- a/doc/ci/testing/accessibility_testing.md
+++ b/doc/ci/testing/accessibility_testing.md
@@ -4,10 +4,15 @@ group: Pipeline Execution
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
-# Accessibility testing **(FREE)**
+<!--- start_remove The following content will be removed on remove_date: '2024-05-22' -->
+# Accessibility testing (deprecated) **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25144) in GitLab 12.8.
+WARNING:
+This feature was deprecated in GitLab 15.9
+and is planned for removal in 17.0. This change is a breaking change.
+
If your application offers a web interface, you can use
[GitLab CI/CD](../index.md) to determine the accessibility
impact of pending code changes.
@@ -74,3 +79,5 @@ The job definition provided by the template does not support Kubernetes.
You cannot pass configurations into Pa11y via CI configuration.
To change the configuration, edit a copy of the template in your CI file.
+
+<!--- end_remove --> \ No newline at end of file
diff --git a/doc/development/fe_guide/vue.md b/doc/development/fe_guide/vue.md
index b8dcf1c336f..80b8a755773 100644
--- a/doc/development/fe_guide/vue.md
+++ b/doc/development/fe_guide/vue.md
@@ -391,6 +391,87 @@ You can read more about components in Vue.js site, [Component System](https://v2
Check this [page](vuex.md) for more details.
+### Vue Router
+
+To add [Vue Router](https://router.vuejs.org/) to a page:
+
+1. Add a catch-all route to the Rails route file using a wildcard named `*vueroute`:
+
+ ```ruby
+ # example from ee/config/routes/project.rb
+
+ resources :iteration_cadences, path: 'cadences(/*vueroute)', action: :index
+ ```
+
+ The above example serves the `index` page from `iteration_cadences` controller to any route
+ matching the start of the `path`, for example `groupname/projectname/-/cadences/123/456/`.
+1. Pass the base route (everything before `*vueroute`) to the frontend to use as the `base` parameter to initialize Vue Router:
+
+ ```haml
+ .js-my-app{ data: { base_path: project_iteration_cadences_path(project) } }
+ ```
+
+1. Initialize the router:
+
+ ```javascript
+ Vue.use(VueRouter);
+
+ export function createRouter(basePath) {
+ return new VueRouter({
+ routes: createRoutes(),
+ mode: 'history',
+ base: basePath,
+ });
+ }
+ ```
+
+1. Add a fallback for unrecognised routes with `path: '*'`. Either:
+ - Add a redirect to the end of your routes array:
+
+ ```javascript
+ const routes = [
+ {
+ path: '/',
+ name: 'list-page',
+ component: ListPage,
+ },
+ {
+ path: '*',
+ redirect: '/',
+ },
+ ];
+ ```
+
+ - Add a fallback component to the end of your routes array:
+
+ ```javascript
+ const routes = [
+ {
+ path: '/',
+ name: 'list-page',
+ component: ListPage,
+ },
+ {
+ path: '*',
+ component: NotFound,
+ },
+ ];
+ ```
+
+1. Optional. To also allow using the path helper for child routes, add `controller` and `action`
+ parameters to use the parent controller.
+
+ ```ruby
+ resources :iteration_cadences, path: 'cadences(/*vueroute)', action: :index do
+ resources :iterations, only: [:index, :new, :edit, :show], constraints: { id: /\d+/ }, controller: :iteration_cadences, action: :index
+ end
+ ```
+
+ This means routes like `/cadences/123/iterations/456/edit` can be validated on the backend,
+ for example to check group or project membership.
+ It also means we can use the `_path` helper, which means we can load the page in feature specs
+ without manually building the `*vueroute` part of the path..
+
### Mixing Vue and jQuery
- Mixing Vue and jQuery is not recommended.
diff --git a/doc/development/integrations/jira_connect.md b/doc/development/integrations/jira_connect.md
index 4789280c09d..3d5e6aae25a 100644
--- a/doc/development/integrations/jira_connect.md
+++ b/doc/development/integrations/jira_connect.md
@@ -72,22 +72,6 @@ To avoid external dependencies like Gitpod and a Jira Cloud instance, use the [J
1. Go to `http://localhost:9292`.
1. Paste the token and select **Install GitLab.com Jira Cloud app**.
-### Troubleshooting
-
-If the app install failed, you might need to delete `jira_connect_installations` from your database.
-
-1. Open the [database console](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/howto/postgresql.md#access-postgresql).
-1. Run `TRUNCATE TABLE jira_connect_installations CASCADE;`.
-
-#### Not authorized to access the file
-
-If you use Gitpod and you get an error about Jira not being able to access the descriptor file, you might need to make the GDK port public by following these steps:
-
-1. Open your GitLab workspace in Gitpod.
-1. When the GDK is running, select **Ports** in the bottom-right corner.
-1. On the left sidebar, select the port the GDK is listening to (typically `3000`).
-1. If the port is marked as private, select the lock icon to make it public.
-
## Test the GitLab OAuth authentication flow
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81126) in GitLab 14.9 [with a flag](../../administration/feature_flags.md) named `jira_connect_oauth`. Disabled by default.
@@ -123,3 +107,21 @@ The following steps describe setting up an environment to test the GitLab OAuth
1. Scroll down and expand the GitLab for Jira App section.
1. Go to [gitpod.io/variables](https://gitpod.io/variables).
1. Paste the Application ID into the **Jira Connect Application ID** field and select **Save changes**.
+
+## Troubleshooting
+
+### App installation fails
+
+If the app installation fails, you might need to delete `jira_connect_installations` from your database.
+
+1. Open the [database console](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/howto/postgresql.md#access-postgresql).
+1. Run `TRUNCATE TABLE jira_connect_installations CASCADE;`.
+
+### Not authorized to access the file
+
+If you use Gitpod and you get an error about Jira not being able to access the descriptor file, you might need to make the GDK port public by following these steps:
+
+1. Open your GitLab workspace in Gitpod.
+1. When the GDK is running, select **Ports** in the bottom-right corner.
+1. On the left sidebar, select the port the GDK is listening to (typically `3000`).
+1. If the port is marked as private, select the lock icon to make it public.
diff --git a/doc/update/package/index.md b/doc/update/package/index.md
index d3bd89975d2..07a294a4dde 100644
--- a/doc/update/package/index.md
+++ b/doc/update/package/index.md
@@ -294,7 +294,7 @@ To fix this issue:
### Error `Failed to connect to the internal GitLab API` on a separate GitLab Pages server
-See [GitLab Pages troubleshooting](../../administration/pages/index.md#failed-to-connect-to-the-internal-gitlab-api).
+See [GitLab Pages administration troubleshooting](../../administration/pages/troubleshooting.md#failed-to-connect-to-the-internal-gitlab-api).
### Error `An error occurred during the signature verification` when running `apt-get update`
diff --git a/doc/user/analytics/value_stream_analytics.md b/doc/user/analytics/value_stream_analytics.md
index f22a6a483b8..34a2561528a 100644
--- a/doc/user/analytics/value_stream_analytics.md
+++ b/doc/user/analytics/value_stream_analytics.md
@@ -11,10 +11,11 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Renamed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23427) from cycle analytics to value stream analytics in GitLab 12.8.
Value stream analytics provides metrics about each stage of your software development process.
+For more information, see [How value stream analytics measures stages](../group/value_stream_analytics/index.md#how-value-stream-analytics-measures-stages).
A **value stream** is the entire work process that delivers value to customers. For example,
the [DevOps lifecycle](https://about.gitlab.com/stages-devops-lifecycle/) is a value stream that starts
-with the Manage stage and ends with the Protect stage.
+with the Plan stage and ends with the Govern stage.
Use value stream analytics to identify:
@@ -113,7 +114,7 @@ To view the lead time for changes for merge requests in your project:
The **Lead Time for Changes** metrics display below the **Filter results** text box.
-## View number of successful deployments **(FREE)**
+## View number of successful deployments
Prerequisites:
@@ -161,60 +162,6 @@ Access permissions for value stream analytics depend on the project type.
| Internal | Any authenticated user can access. |
| Private | Any member Guest and above can access. |
-## How value stream analytics measures each stage
-
-Value stream analytics uses start and end events to measure the time that an issue or merge request
-spends in each stage.
-
-For example, a stage might start when a user adds a label to an issue, and ends when they add another label.
-Items aren't included in the stage time calculation if they have not reached the end event.
-
-| Stage | Measurement method |
-|---------|----------------------|
-| Issue | The median time between creating an issue and taking action to solve it, by either labeling it or adding it to a milestone. The label is tracked only if it already includes an [issue board list](../project/issue_board.md) that has been created for the label. |
-| Plan | The median time between the action you took for the previous stage, and when you push the first commit to the branch. The first branch commit triggers the transition from **Plan** to **Code**, and at least one of the commits in the branch must include the related issue number (such as `#42`). If the issue number is not included in a commit, that data is not included in the measurement time of the stage. |
-| Code | The median time between pushing a first commit (previous stage) and creating a merge request. The process is tracked with the [issue closing pattern](../project/issues/managing_issues.md#closing-issues-automatically) in the description of the merge request. For example, if the issue is closed with `Closes #xxx`, `xxx` is the issue number for the merge request. If there is no closing pattern, the start time is set to the create time of the first commit. |
-| Test | The time from start to finish for all pipelines. Measures the median time to run the entire pipeline for that project. Related to the time required by GitLab CI/CD to run every job for the commits pushed to that merge request, as defined in the previous stage. |
-| Review | The median time taken to review merge requests with a closing issue pattern, from creation to merge. |
-| Staging | The median time between merging the merge request (with a closing issue pattern) to the first deployment to a [production environment](../../ci/environments/index.md#deployment-tier-of-environments). Data is not collected without a production environment. |
-
-## Example workflow
-
-This example shows a workflow through all seven stages in one day. In this
-example, milestones have been created and CI for testing and setting environments is configured.
-
-- 09:00: Create issue. **Issue** stage starts.
-- 11:00: Add issue to a milestone, start work on the issue, and create a branch locally.
-**Issue** stage stops and **Plan** stage starts.
-- 12:00: Make the first commit.
-- 12:30: Make the second commit to the branch that mentions the issue number. **Plan** stage stops and **Code** stage starts.
-- 14:00: Push branch and create a merge request that contains the [issue closing pattern](../project/issues/managing_issues.md#closing-issues-automatically). **Code** stage stops and **Test** and **Review** stages start.
-- The CI takes 5 minutes to run scripts defined in [`.gitlab-ci.yml`](../../ci/yaml/index.md).
-**Test** stage stops.
-- Review merge request.
-- 19:00: Merge the merge request. **Review** stage stops and **Staging** stage starts.
-- 19:30: Deployment to the `production` environment starts and finishes. **Staging** stops.
-
-Value stream analytics records the following times for each stage:
-
-- **Issue**: 09:00 to 11:00: 2 hrs
-- **Plan**: 11:00 to 12:30: 1.5 hr
-- **Code**: 12:30 to 14:00: 1.5 hrs
-- **Test**: 5 minutes
-- **Review**: 14:00 to 19:00: 5 hrs
-- **Staging**: 19:00 to 19:30: 30 minutes
-
-Keep in mind the following observations related to this example:
-
-- Although this example specifies the issue number in a later commit, the process
-still collects analytics data for the issue.
-- The time required in the **Test** stage is included in the **Review** process,
-as every merge request should be tested.
-- This example illustrates only one cycle of multiple stages. The value
-stream analytics dashboard shows the calculated median elapsed time for these issues.
-- Value stream analytics identifies production environments based on the
-[deployment tier of environments](../../ci/environments/index.md#deployment-tier-of-environments).
-
## Troubleshooting
### 100% CPU utilization by Sidekiq `cronjob:analytics_cycle_analytics`
diff --git a/doc/user/packages/container_registry/reduce_container_registry_storage.md b/doc/user/packages/container_registry/reduce_container_registry_storage.md
index 68feb2d196c..88c5efd1b39 100644
--- a/doc/user/packages/container_registry/reduce_container_registry_storage.md
+++ b/doc/user/packages/container_registry/reduce_container_registry_storage.md
@@ -21,7 +21,7 @@ The Usage Quotas page (**Settings > Usage Quotas > Storage**) displays storage u
This page includes the Container Registry usage, which is only available on GitLab.com.
Measuring usage is only possible on the new version of the GitLab Container Registry backed by a
metadata database. Support for improvements is proposed in epic [5523](https://gitlab.com/groups/gitlab-org/-/epics/5523).
-You cannot use the Container Registry in self-managed instances, but epic [5521](https://gitlab.com/groups/gitlab-org/-/epics/5521) proposes to change this behavior.
+On self-managed instances, you cannot use the Container Registry with a metadata database. For the plan to change this behavior, see [epic 5521](https://gitlab.com/groups/gitlab-org/-/epics/5521).
Image layers stored in the Container Registry are deduplicated at the root namespace level.
diff --git a/doc/user/project/pages/custom_domains_ssl_tls_certification/index.md b/doc/user/project/pages/custom_domains_ssl_tls_certification/index.md
index 7534d0fc91c..e35be518fc6 100644
--- a/doc/user/project/pages/custom_domains_ssl_tls_certification/index.md
+++ b/doc/user/project/pages/custom_domains_ssl_tls_certification/index.md
@@ -196,38 +196,6 @@ from the GitLab project.
in place. Your domain is periodically reverified, and may be
disabled if the record is removed.
-##### Troubleshoot domain verification
-
-To manually verify that you have properly configured the domain verification
-`TXT` DNS entry, you can run the following command in your terminal:
-
-```shell
-dig _gitlab-pages-verification-code.<YOUR-PAGES-DOMAIN> TXT
-```
-
-Expect the output:
-
-```plaintext
-;; ANSWER SECTION:
-_gitlab-pages-verification-code.<YOUR-PAGES-DOMAIN>. 300 IN TXT "gitlab-pages-verification-code=<YOUR-VERIFICATION-CODE>"
-```
-
-In some cases it can help to add the verification code with the same domain name as you are trying to register.
-
-For a root domain:
-
-| From | DNS Record | To |
-| ------------------------------------------------- | ---------- | ---------------------- |
-| `example.com` | `TXT` | `gitlab-pages-verification-code=00112233445566778899aabbccddeeff` |
-| `_gitlab-pages-verification-code.example.com` | `TXT` | `gitlab-pages-verification-code=00112233445566778899aabbccddeeff` |
-
-For a subdomain:
-
-| From | DNS Record | To |
-| ------------------------------------------------- | ---------- | ---------------------- |
-| `www.example.com` | `TXT` | `gitlab-pages-verification-code=00112233445566778899aabbccddeeff` |
-| `_gitlab-pages-verification-code.www.example.com` | `TXT` | `gitlab-pages-verification-code=00112233445566778899aabbccddeeff` |
-
### Add more domain aliases
You can add more than one alias (custom domains and subdomains) to the same project.
@@ -351,14 +319,36 @@ To enable this setting:
If you use Cloudflare CDN in front of GitLab Pages, make sure to set the SSL connection setting to
`full` instead of `flexible`. For more details, see the [Cloudflare CDN directions](https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes#h_4e0d1a7c-eb71-4204-9e22-9d3ef9ef7fef).
-<!-- ## Troubleshooting
+## Troubleshooting
+
+### Domain verification
+
+To manually verify that you have properly configured the domain verification
+`TXT` DNS entry, you can run the following command in your terminal:
+
+```shell
+dig _gitlab-pages-verification-code.<YOUR-PAGES-DOMAIN> TXT
+```
+
+Expect the output:
+
+```plaintext
+;; ANSWER SECTION:
+_gitlab-pages-verification-code.<YOUR-PAGES-DOMAIN>. 300 IN TXT "gitlab-pages-verification-code=<YOUR-VERIFICATION-CODE>"
+```
+
+In some cases it can help to add the verification code with the same domain name as you are trying to register.
-Include any troubleshooting steps that you can foresee. If you know beforehand what issues
-one might have when setting this up, or when something is changed, or on upgrading, it's
-important to describe those, too. Think of things that may go wrong and include them here.
-This is important to minimize requests for support, and to avoid doc comments with
-questions that you know someone might ask.
+For a root domain:
-Each scenario can be a third-level heading, for example, `### Getting error message X`.
-If you have none to add when creating a doc, leave this section in place
-but commented out to help encourage others to add to it in the future. -->
+| From | DNS Record | To |
+| ------------------------------------------------- | ---------- | ---------------------- |
+| `example.com` | `TXT` | `gitlab-pages-verification-code=00112233445566778899aabbccddeeff` |
+| `_gitlab-pages-verification-code.example.com` | `TXT` | `gitlab-pages-verification-code=00112233445566778899aabbccddeeff` |
+
+For a subdomain:
+
+| From | DNS Record | To |
+| ------------------------------------------------- | ---------- | ---------------------- |
+| `www.example.com` | `TXT` | `gitlab-pages-verification-code=00112233445566778899aabbccddeeff` |
+| `_gitlab-pages-verification-code.www.example.com` | `TXT` | `gitlab-pages-verification-code=00112233445566778899aabbccddeeff` |
diff --git a/doc/user/project/remote_development/index.md b/doc/user/project/remote_development/index.md
index 58d43f64812..29711b89d23 100644
--- a/doc/user/project/remote_development/index.md
+++ b/doc/user/project/remote_development/index.md
@@ -154,7 +154,3 @@ Alternatively, you can pass the parameters from a URL and connect directly to th
```
1. Go to that URL and enter the [token you fetched](#fetch-a-token).
-
-## Related topics
-
-- [Web IDE Beta](../web_ide_beta/index.md)
diff --git a/doc/user/project/repository/tags/index.md b/doc/user/project/repository/tags/index.md
index 706b50a916d..9a9b8a49382 100644
--- a/doc/user/project/repository/tags/index.md
+++ b/doc/user/project/repository/tags/index.md
@@ -101,6 +101,18 @@ To create a tag from the GitLab UI:
To prevent users from removing a tag with `git push`, create a [push rule](../push_rules.md).
+## Trigger pipelines from a tag
+
+GitLab CI/CD provides a [`CI_COMMIT_TAG` variable](../../../../ci/variables/predefined_variables.md)
+to identify tags. Use this variable in job rules and workflow rules to test if the pipeline
+was triggered by a tag.
+
+In your `.gitlab-ci.yml` file for the CI/CD pipeline configuration of your project,
+you can trigger based on a new tag:
+
+- At the job level, with the [`only` keyword](../../../../ci/yaml/index.md#only--except).
+- At the pipeline level, with the [workflow rules keywords](../../../../ci/yaml/workflow.md).
+
## Related topics
- [Tagging](https://git-scm.com/book/en/v2/Git-Basics-Tagging) Git reference page.
diff --git a/doc/user/project/web_ide/index.md b/doc/user/project/web_ide/index.md
index e2a74f02008..0b03233e664 100644
--- a/doc/user/project/web_ide/index.md
+++ b/doc/user/project/web_ide/index.md
@@ -450,7 +450,7 @@ when:
- You select any area outside the file editor after editing a file.
- A file or folder is created, deleted, or renamed.
-### Known issues
+## Known issues
The Web IDE has a few limitations:
@@ -458,7 +458,9 @@ The Web IDE has a few limitations:
active terminal at a time.
- LFS files can be rendered and displayed but they cannot be updated and committed using the Web IDE. If an LFS file is modified and pushed to the repository, the LFS pointer in the repository is overwritten with the modified LFS file content.
-### Troubleshooting
+## Troubleshooting
+
+### Web terminals
- If the terminal's text is gray and unresponsive, then the terminal has stopped
and it can no longer be used. A stopped terminal can be restarted by selecting
@@ -466,7 +468,3 @@ The Web IDE has a few limitations:
- If the terminal displays **Connection Failure**, then the terminal could not
connect to the runner. Try to stop and restart the terminal. If the
problem persists, double check your runner configuration.
-
-## Related topics
-
-- [Web IDE Beta](../web_ide_beta/index.md)
diff --git a/doc/user/project/web_ide_beta/index.md b/doc/user/project/web_ide_beta/index.md
index 635b5e12575..200a8b6d804 100644
--- a/doc/user/project/web_ide_beta/index.md
+++ b/doc/user/project/web_ide_beta/index.md
@@ -128,8 +128,3 @@ The [Web Terminal](../web_ide/index.md#interactive-web-terminals-for-the-web-ide
and [Live Preview](../web_ide/index.md#live-preview-removed) are not available in the Web IDE Beta.
These features might become available at a later date.
-
-## Related topics
-
-- [Remote Development](../remote_development/index.md)
-- [Web IDE](../web_ide/index.md)
diff --git a/lib/sidebars/concerns/super_sidebar_panel.rb b/lib/sidebars/concerns/super_sidebar_panel.rb
index 5f3607debbc..1764aad034c 100644
--- a/lib/sidebars/concerns/super_sidebar_panel.rb
+++ b/lib/sidebars/concerns/super_sidebar_panel.rb
@@ -50,7 +50,7 @@ module Sidebars
if menu_item.super_sidebar_before
menus[idx].insert_item_before(menu_item.super_sidebar_before, menu_item)
else
- menus[idx].add_item(menu_item)
+ menus[idx].replace_placeholder(menu_item)
end
end
end
diff --git a/lib/sidebars/menu.rb b/lib/sidebars/menu.rb
index 03995362ff0..432cc6ebc8b 100644
--- a/lib/sidebars/menu.rb
+++ b/lib/sidebars/menu.rb
@@ -117,6 +117,15 @@ module Sidebars
insert_element_after(@items, after_item, new_item)
end
+ def replace_placeholder(item)
+ idx = @items.index { |e| e.item_id == item.item_id && e.is_a?(::Sidebars::NilMenuItem) }
+ if idx.nil?
+ add_item(item)
+ else
+ replace_element(@items, item.item_id, item)
+ end
+ end
+
override :container_html_options
def container_html_options
super.tap do |html_options|
diff --git a/lib/sidebars/projects/menus/analytics_menu.rb b/lib/sidebars/projects/menus/analytics_menu.rb
index fae2efd91de..96b50cdfcd1 100644
--- a/lib/sidebars/projects/menus/analytics_menu.rb
+++ b/lib/sidebars/projects/menus/analytics_menu.rb
@@ -41,9 +41,9 @@ module Sidebars
'chart'
end
- override :pick_into_super_sidebar?
- def pick_into_super_sidebar?
- true
+ override :serialize_as_menu_item_args
+ def serialize_as_menu_item_args
+ nil
end
private
@@ -57,8 +57,9 @@ module Sidebars
end
::Sidebars::MenuItem.new(
- title: _('CI/CD'),
+ title: context.is_super_sidebar ? _('CI/CD analytics') : _('CI/CD'),
link: charts_project_pipelines_path(context.project),
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::AnalyzeMenu,
active_routes: { path: 'pipelines#charts' },
item_id: :ci_cd_analytics
)
@@ -70,8 +71,9 @@ module Sidebars
end
::Sidebars::MenuItem.new(
- title: _('Repository'),
+ title: context.is_super_sidebar ? _('Repository analytics') : _('Repository'),
link: charts_project_graph_path(context.project, context.current_ref),
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::AnalyzeMenu,
container_html_options: { class: 'shortcuts-repository-charts' },
active_routes: { path: 'graphs#charts' },
item_id: :repository_analytics
@@ -85,8 +87,9 @@ module Sidebars
end
::Sidebars::MenuItem.new(
- title: _('Value stream'),
+ title: context.is_super_sidebar ? _('Value stream analytics') : _('Value stream'),
link: project_cycle_analytics_path(context.project),
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::AnalyzeMenu,
container_html_options: { class: 'shortcuts-project-cycle-analytics' },
active_routes: { path: 'cycle_analytics#show' },
item_id: :cycle_analytics
diff --git a/lib/sidebars/projects/menus/repository_menu.rb b/lib/sidebars/projects/menus/repository_menu.rb
index 158a29f0b31..157dd379ed7 100644
--- a/lib/sidebars/projects/menus/repository_menu.rb
+++ b/lib/sidebars/projects/menus/repository_menu.rb
@@ -44,17 +44,18 @@ module Sidebars
'doc-text'
end
- override :pick_into_super_sidebar?
- def pick_into_super_sidebar?
- true
+ override :serialize_as_menu_item_args
+ def serialize_as_menu_item_args
+ nil
end
private
def files_menu_item
::Sidebars::MenuItem.new(
- title: _('Files'),
+ title: context.is_super_sidebar ? _('Repository') : _('Files'),
link: project_tree_path(context.project, context.current_ref),
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::CodeMenu,
active_routes: { controller: %w[tree blob blame edit_tree new_tree find_file] },
item_id: :files
)
@@ -66,6 +67,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Commits'),
link: link,
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::CodeMenu,
active_routes: { controller: %w(commit commits) },
item_id: :commits,
container_html_options: { id: 'js-onboarding-commits-link' }
@@ -76,6 +78,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Branches'),
link: project_branches_path(context.project),
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::CodeMenu,
active_routes: { controller: :branches },
item_id: :branches,
container_html_options: { id: 'js-onboarding-branches-link' }
@@ -86,6 +89,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Tags'),
link: project_tags_path(context.project),
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::CodeMenu,
item_id: :tags,
active_routes: { controller: :tags }
)
@@ -99,6 +103,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Contributor statistics'),
link: link,
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::AnalyzeMenu,
active_routes: { path: 'graphs#show' },
item_id: :contributors
)
@@ -108,8 +113,9 @@ module Sidebars
link = project_network_path(context.project, context.current_ref, ref_type: ref_type_from_context(context))
::Sidebars::MenuItem.new(
- title: _('Graph'),
+ title: context.is_super_sidebar ? _('Repository graph') : _('Graph'),
link: link,
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::CodeMenu,
active_routes: { controller: :network },
item_id: :graphs
)
@@ -118,6 +124,7 @@ module Sidebars
def compare_menu_item
::Sidebars::MenuItem.new(
title: _('Compare revisions'),
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::CodeMenu,
link: project_compare_index_path(context.project, from: context.project.repository.root_ref, to: context.current_ref),
active_routes: { controller: :compare },
item_id: :compare
diff --git a/lib/sidebars/projects/menus/security_compliance_menu.rb b/lib/sidebars/projects/menus/security_compliance_menu.rb
index eb713244a7c..0f009bff12a 100644
--- a/lib/sidebars/projects/menus/security_compliance_menu.rb
+++ b/lib/sidebars/projects/menus/security_compliance_menu.rb
@@ -25,9 +25,9 @@ module Sidebars
'shield'
end
- override :pick_into_super_sidebar?
- def pick_into_super_sidebar?
- true
+ override :serialize_as_menu_item_args
+ def serialize_as_menu_item_args
+ nil
end
private
@@ -40,6 +40,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Security configuration'),
link: project_security_configuration_path(context.project),
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::SecureMenu,
active_routes: { path: configuration_menu_item_paths },
item_id: :configuration
)
diff --git a/lib/sidebars/projects/menus/snippets_menu.rb b/lib/sidebars/projects/menus/snippets_menu.rb
index 535f12963b1..ba458f9f5e9 100644
--- a/lib/sidebars/projects/menus/snippets_menu.rb
+++ b/lib/sidebars/projects/menus/snippets_menu.rb
@@ -39,8 +39,7 @@ module Sidebars
override :serialize_as_menu_item_args
def serialize_as_menu_item_args
super.deep_merge({
- super_sidebar_parent: ::Sidebars::Projects::Menus::RepositoryMenu,
- super_sidebar_before: :contributors,
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::CodeMenu,
item_id: :project_snippets
})
end
diff --git a/lib/sidebars/projects/super_sidebar_menus/analyze_menu.rb b/lib/sidebars/projects/super_sidebar_menus/analyze_menu.rb
new file mode 100644
index 00000000000..2d1b4c0c495
--- /dev/null
+++ b/lib/sidebars/projects/super_sidebar_menus/analyze_menu.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Projects
+ module SuperSidebarMenus
+ class AnalyzeMenu < ::Sidebars::Menu
+ override :title
+ def title
+ s_('Navigation|Analyze')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'chart'
+ end
+
+ override :configure_menu_items
+ def configure_menu_items
+ [
+ :dashboards_analytics,
+ :cycle_analytics,
+ :contributors,
+ :ci_cd_analytics,
+ :repository_analytics,
+ :code_review,
+ :merge_requests,
+ :issues,
+ :insights
+ ].each { |id| add_item(::Sidebars::NilMenuItem.new(item_id: id)) }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/projects/super_sidebar_menus/build_menu.rb b/lib/sidebars/projects/super_sidebar_menus/build_menu.rb
new file mode 100644
index 00000000000..0a7879136ac
--- /dev/null
+++ b/lib/sidebars/projects/super_sidebar_menus/build_menu.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Projects
+ module SuperSidebarMenus
+ class BuildMenu < ::Sidebars::Menu
+ override :title
+ def title
+ s_('Navigation|Build')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'rocket'
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/projects/super_sidebar_menus/code_menu.rb b/lib/sidebars/projects/super_sidebar_menus/code_menu.rb
new file mode 100644
index 00000000000..a201312f8ce
--- /dev/null
+++ b/lib/sidebars/projects/super_sidebar_menus/code_menu.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Projects
+ module SuperSidebarMenus
+ class CodeMenu < ::Sidebars::Menu
+ override :title
+ def title
+ s_('Navigation|Code')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'code'
+ end
+
+ override :configure_menu_items
+ def configure_menu_items
+ [
+ :files,
+ :branches,
+ :commits,
+ :tags,
+ :graphs,
+ :compare,
+ :project_snippets,
+ :file_locks
+ ].each { |id| add_item(::Sidebars::NilMenuItem.new(item_id: id)) }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/projects/super_sidebar_menus/manage_menu.rb b/lib/sidebars/projects/super_sidebar_menus/manage_menu.rb
new file mode 100644
index 00000000000..72743910411
--- /dev/null
+++ b/lib/sidebars/projects/super_sidebar_menus/manage_menu.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Projects
+ module SuperSidebarMenus
+ class ManageMenu < ::Sidebars::Menu
+ override :title
+ def title
+ s_('Navigation|Manage')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'users'
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/projects/super_sidebar_menus/monitor_menu.rb b/lib/sidebars/projects/super_sidebar_menus/monitor_menu.rb
new file mode 100644
index 00000000000..40981813cb6
--- /dev/null
+++ b/lib/sidebars/projects/super_sidebar_menus/monitor_menu.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Projects
+ module SuperSidebarMenus
+ class MonitorMenu < ::Sidebars::Menu
+ override :title
+ def title
+ s_('Navigation|Monitor')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'monitor'
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/projects/super_sidebar_menus/operations_menu.rb b/lib/sidebars/projects/super_sidebar_menus/operations_menu.rb
index 5490aac5a65..2688860017a 100644
--- a/lib/sidebars/projects/super_sidebar_menus/operations_menu.rb
+++ b/lib/sidebars/projects/super_sidebar_menus/operations_menu.rb
@@ -6,7 +6,7 @@ module Sidebars
class OperationsMenu < ::Sidebars::Menu
override :title
def title
- _('Operations')
+ s_('Navigation|Operate')
end
override :sprite_icon
diff --git a/lib/sidebars/projects/super_sidebar_menus/plan_menu.rb b/lib/sidebars/projects/super_sidebar_menus/plan_menu.rb
index ae9b2d826b7..787d096cabf 100644
--- a/lib/sidebars/projects/super_sidebar_menus/plan_menu.rb
+++ b/lib/sidebars/projects/super_sidebar_menus/plan_menu.rb
@@ -6,7 +6,7 @@ module Sidebars
class PlanMenu < ::Sidebars::Menu
override :title
def title
- _('Plan')
+ s_('Navigation|Plan')
end
override :sprite_icon
diff --git a/lib/sidebars/projects/super_sidebar_menus/secure_menu.rb b/lib/sidebars/projects/super_sidebar_menus/secure_menu.rb
new file mode 100644
index 00000000000..8639e3dbb1d
--- /dev/null
+++ b/lib/sidebars/projects/super_sidebar_menus/secure_menu.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module Sidebars
+ module Projects
+ module SuperSidebarMenus
+ class SecureMenu < ::Sidebars::Menu
+ override :title
+ def title
+ s_('Navigation|Secure')
+ end
+
+ override :sprite_icon
+ def sprite_icon
+ 'shield'
+ end
+
+ override :configure_menu_items
+ def configure_menu_items
+ [
+ :discover_project_security,
+ :audit_events,
+ :dashboard,
+ :vulnerability_report,
+ :on_demand_scans,
+ :scan_policies,
+ :dependency_list,
+ :license_compliance,
+ :configuration
+ ].each { |id| add_item(::Sidebars::NilMenuItem.new(item_id: id)) }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/sidebars/projects/super_sidebar_panel.rb b/lib/sidebars/projects/super_sidebar_panel.rb
index f76f28eb642..640666fd968 100644
--- a/lib/sidebars/projects/super_sidebar_panel.rb
+++ b/lib/sidebars/projects/super_sidebar_panel.rb
@@ -13,16 +13,20 @@ module Sidebars
@menus = []
add_menu(Sidebars::StaticMenu.new(context))
+ add_menu(Sidebars::Projects::SuperSidebarMenus::ManageMenu.new(context))
add_menu(Sidebars::Projects::SuperSidebarMenus::PlanMenu.new(context))
-
+ add_menu(Sidebars::Projects::SuperSidebarMenus::CodeMenu.new(context))
+ add_menu(Sidebars::Projects::SuperSidebarMenus::BuildMenu.new(context))
+ add_menu(Sidebars::Projects::SuperSidebarMenus::SecureMenu.new(context))
+ add_menu(Sidebars::Projects::SuperSidebarMenus::OperationsMenu.new(context))
+ add_menu(Sidebars::Projects::SuperSidebarMenus::MonitorMenu.new(context))
+ add_menu(Sidebars::Projects::SuperSidebarMenus::AnalyzeMenu.new(context))
+
+ # Pick old menus, will be obsolete once everything is in their own
+ # super sidebar menu
pick_from_old_menus(old_menus)
insert_menu_before(
- Sidebars::Projects::Menus::MonitorMenu,
- Sidebars::Projects::SuperSidebarMenus::OperationsMenu.new(context)
- )
-
- insert_menu_before(
Sidebars::Projects::Menus::SettingsMenu,
Sidebars::UncategorizedMenu.new(context)
)
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index abc8ec296e1..889f137560d 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -5002,6 +5002,9 @@ msgstr ""
msgid "Application ID"
msgstr ""
+msgid "Application analytics"
+msgstr ""
+
msgid "Application limits saved successfully"
msgstr ""
@@ -7967,6 +7970,9 @@ msgstr ""
msgid "CI/CD Settings"
msgstr ""
+msgid "CI/CD analytics"
+msgstr ""
+
msgid "CI/CD configuration"
msgstr ""
@@ -10341,6 +10347,9 @@ msgstr ""
msgid "Code review"
msgstr ""
+msgid "Code review analytics"
+msgstr ""
+
msgid "Code snippet"
msgstr ""
@@ -18036,6 +18045,9 @@ msgstr ""
msgid "File name"
msgstr ""
+msgid "File permissions"
+msgstr ""
+
msgid "File renamed with no changes."
msgstr ""
@@ -23997,6 +24009,9 @@ msgstr ""
msgid "Issue already promoted to epic."
msgstr ""
+msgid "Issue analytics"
+msgstr ""
+
msgid "Issue board"
msgstr ""
@@ -28513,6 +28528,15 @@ msgstr ""
msgid "Navigation|Admin"
msgstr ""
+msgid "Navigation|Analyze"
+msgstr ""
+
+msgid "Navigation|Build"
+msgstr ""
+
+msgid "Navigation|Code"
+msgstr ""
+
msgid "Navigation|Context navigation"
msgstr ""
@@ -28531,12 +28555,24 @@ msgstr ""
msgid "Navigation|Groups you visit often will appear here."
msgstr ""
+msgid "Navigation|Manage"
+msgstr ""
+
+msgid "Navigation|Monitor"
+msgstr ""
+
msgid "Navigation|No group matches found"
msgstr ""
msgid "Navigation|No project matches found"
msgstr ""
+msgid "Navigation|Operate"
+msgstr ""
+
+msgid "Navigation|Plan"
+msgstr ""
+
msgid "Navigation|Projects"
msgstr ""
@@ -28549,6 +28585,9 @@ msgstr ""
msgid "Navigation|Search for projects or groups"
msgstr ""
+msgid "Navigation|Secure"
+msgstr ""
+
msgid "Navigation|Switch to..."
msgstr ""
@@ -36945,6 +36984,9 @@ msgstr ""
msgid "Repository already read-only"
msgstr ""
+msgid "Repository analytics"
+msgstr ""
+
msgid "Repository by URL"
msgstr ""
@@ -36969,6 +37011,9 @@ msgstr ""
msgid "Repository files count over the limit"
msgstr ""
+msgid "Repository graph"
+msgstr ""
+
msgid "Repository has an invalid default branch name."
msgstr ""
@@ -47752,6 +47797,9 @@ msgstr ""
msgid "Value stream"
msgstr ""
+msgid "Value stream analytics"
+msgstr ""
+
msgid "ValueStreamAnalyticsStage|We don't have enough data to show this stage."
msgstr ""
diff --git a/rubocop/cop/rspec/feature_category_on_shared_examples.rb b/rubocop/cop/rspec/feature_category_on_shared_examples.rb
new file mode 100644
index 00000000000..acb2ae79d12
--- /dev/null
+++ b/rubocop/cop/rspec/feature_category_on_shared_examples.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require 'rubocop/cop/rspec/base'
+
+module RuboCop
+ module Cop
+ module RSpec
+ # Ensures that shared examples don't have feature category.
+ #
+ # @example
+ #
+ # # bad
+ # RSpec.shared_examples 'an external link with rel attribute', feature_category: :team_planning do
+ # end
+ #
+ # # good
+ # RSpec.shared_examples 'an external link with rel attribute' do
+ # end
+ #
+ # it 'adds rel="nofollow" to external links', feature_category: :team_planning do
+ # end
+ class FeatureCategoryOnSharedExamples < RuboCop::Cop::RSpec::Base
+ MSG = 'Shared examples should not have feature category set'
+
+ # @!method feature_category_value(node)
+ def_node_matcher :feature_category_value, <<~PATTERN
+ (block
+ (send #rspec? {#SharedGroups.all} ...
+ $(hash <(pair (sym :feature_category) _) ...>)
+ )
+ ...
+ )
+ PATTERN
+
+ def on_block(node)
+ value_node = feature_category_value(node)
+
+ return unless value_node
+
+ add_offense(value_node, message: MSG)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/frontend/clusters_list/components/agent_table_spec.js b/spec/frontend/clusters_list/components/agent_table_spec.js
index 5088069d015..0f68a69458e 100644
--- a/spec/frontend/clusters_list/components/agent_table_spec.js
+++ b/spec/frontend/clusters_list/components/agent_table_spec.js
@@ -36,6 +36,7 @@ describe('AgentTable', () => {
const findStatusIcon = (at) => findStatusText(at).findComponent(GlIcon);
const findLastContactText = (at) => wrapper.findAllByTestId('cluster-agent-last-contact').at(at);
const findVersionText = (at) => wrapper.findAllByTestId('cluster-agent-version').at(at);
+ const findAgentId = (at) => wrapper.findAllByTestId('cluster-agent-id').at(at);
const findConfiguration = (at) =>
wrapper.findAllByTestId('cluster-agent-configuration-link').at(at);
const findDeleteAgentButton = () => wrapper.findAllComponents(DeleteAgentButton);
@@ -66,6 +67,17 @@ describe('AgentTable', () => {
});
it.each`
+ agentGraphQLId | agentId | lineNumber
+ ${'gid://gitlab/Clusters::Agent/1'} | ${'1'} | ${0}
+ ${'gid://gitlab/Clusters::Agent/2'} | ${'2'} | ${1}
+ `(
+ 'displays agent id as "$agentId" for "$agentGraphQLId" at line $lineNumber',
+ ({ agentId, lineNumber }) => {
+ expect(findAgentId(lineNumber).text()).toBe(agentId);
+ },
+ );
+
+ it.each`
status | iconName | lineNumber
${'Never connected'} | ${'status-neutral'} | ${0}
${'Connected'} | ${'status-success'} | ${1}
diff --git a/spec/frontend/clusters_list/components/mock_data.js b/spec/frontend/clusters_list/components/mock_data.js
index b5d25c780b6..af1fb496118 100644
--- a/spec/frontend/clusters_list/components/mock_data.js
+++ b/spec/frontend/clusters_list/components/mock_data.js
@@ -19,7 +19,7 @@ export const connectedTimeInactive = new Date(connectedTimeNow.getTime() - ACTIV
export const clusterAgents = [
{
name: 'agent-1',
- id: 'agent-1-id',
+ id: 'gid://gitlab/Clusters::Agent/1',
configFolder: {
webPath: '/agent/full/path',
},
@@ -30,7 +30,7 @@ export const clusterAgents = [
},
{
name: 'agent-2',
- id: 'agent-2-id',
+ id: 'gid://gitlab/Clusters::Agent/2',
webPath: '/agent-2',
status: 'active',
lastContact: connectedTimeNow.getTime(),
@@ -54,7 +54,7 @@ export const clusterAgents = [
},
{
name: 'agent-3',
- id: 'agent-3-id',
+ id: 'gid://gitlab/Clusters::Agent/3',
webPath: '/agent-3',
status: 'inactive',
lastContact: connectedTimeInactive.getTime(),
@@ -75,7 +75,7 @@ export const clusterAgents = [
},
{
name: 'agent-4',
- id: 'agent-4-id',
+ id: 'gid://gitlab/Clusters::Agent/4',
webPath: '/agent-4',
status: 'inactive',
lastContact: connectedTimeInactive.getTime(),
@@ -99,7 +99,7 @@ export const clusterAgents = [
},
{
name: 'agent-5',
- id: 'agent-5-id',
+ id: 'gid://gitlab/Clusters::Agent/5',
webPath: '/agent-5',
status: 'inactive',
lastContact: connectedTimeInactive.getTime(),
@@ -123,7 +123,7 @@ export const clusterAgents = [
},
{
name: 'agent-6',
- id: 'agent-6-id',
+ id: 'gid://gitlab/Clusters::Agent/6',
webPath: '/agent-6',
status: 'inactive',
lastContact: connectedTimeInactive.getTime(),
@@ -144,7 +144,7 @@ export const clusterAgents = [
},
{
name: 'agent-7',
- id: 'agent-7-id',
+ id: 'gid://gitlab/Clusters::Agent/7',
webPath: '/agent-7',
status: 'inactive',
lastContact: connectedTimeInactive.getTime(),
@@ -165,7 +165,7 @@ export const clusterAgents = [
},
{
name: 'agent-8',
- id: 'agent-8-id',
+ id: 'gid://gitlab/Clusters::Agent/8',
webPath: '/agent-8',
status: 'inactive',
lastContact: connectedTimeInactive.getTime(),
@@ -186,7 +186,7 @@ export const clusterAgents = [
},
{
name: 'agent-9',
- id: 'agent-9-id',
+ id: 'gid://gitlab/Clusters::Agent/9',
webPath: '/agent-9',
status: 'inactive',
lastContact: connectedTimeInactive.getTime(),
diff --git a/spec/frontend/diffs/components/commit_item_spec.js b/spec/frontend/diffs/components/commit_item_spec.js
index 4b4b6351d3f..3c092296130 100644
--- a/spec/frontend/diffs/components/commit_item_spec.js
+++ b/spec/frontend/diffs/components/commit_item_spec.js
@@ -1,4 +1,5 @@
import { mount } from '@vue/test-utils';
+import { GlFormCheckbox } from '@gitlab/ui';
import getDiffWithCommit from 'test_fixtures/merge_request_diffs/with_commit.json';
import { TEST_HOST } from 'helpers/test_constants';
import { trimText } from 'helpers/text_helper';
@@ -28,6 +29,7 @@ describe('diffs/components/commit_item', () => {
const getCommitterElement = () => wrapper.find('.committer');
const getCommitActionsElement = () => wrapper.find('.commit-actions');
const getCommitPipelineStatus = () => wrapper.findComponent(CommitPipelineStatus);
+ const getCommitCheckbox = () => wrapper.findComponent(GlFormCheckbox);
const mountComponent = (propsData) => {
wrapper = mount(Component, {
@@ -168,4 +170,24 @@ describe('diffs/components/commit_item', () => {
expect(getCommitPipelineStatus().exists()).toBe(true);
});
});
+
+ describe('when commit is selectable', () => {
+ beforeEach(() => {
+ mountComponent({
+ commit: { ...commit },
+ isSelectable: true,
+ });
+ });
+
+ it('renders checkbox', () => {
+ expect(getCommitCheckbox().exists()).toBe(true);
+ });
+
+ it('emits "handleCheckboxChange" event on change', () => {
+ expect(wrapper.emitted('handleCheckboxChange')).toBeUndefined();
+ getCommitCheckbox().vm.$emit('change');
+
+ expect(wrapper.emitted('handleCheckboxChange')[0]).toEqual([true]);
+ });
+ });
});
diff --git a/spec/lib/sidebars/concerns/super_sidebar_panel_spec.rb b/spec/lib/sidebars/concerns/super_sidebar_panel_spec.rb
index f33cb4ab7f6..b1051c1387b 100644
--- a/spec/lib/sidebars/concerns/super_sidebar_panel_spec.rb
+++ b/spec/lib/sidebars/concerns/super_sidebar_panel_spec.rb
@@ -83,6 +83,16 @@ RSpec.describe Sidebars::Concerns::SuperSidebarPanel, feature_category: :navigat
expect(uncategorized_menu.renderable_items).to eq([])
end
+ it 'replaces placeholder Menu Items in the defined super_sidebar_parent' do
+ menu_foo.insert_item_before(:exists, nil_menu_item)
+ allow(menu_item).to receive(:item_id).and_return(:nil_item)
+
+ subject.transform_old_menus(current_menus, menu_bar)
+
+ expect(menu_foo.renderable_items).to eq([menu_item, existing_item])
+ expect(uncategorized_menu.renderable_items).to eq([])
+ end
+
it 'adds Menu Items to defined super_sidebar_parent, before super_sidebar_before' do
allow(menu_item).to receive(:super_sidebar_before).and_return(:exists)
subject.transform_old_menus(current_menus, menu_bar)
diff --git a/spec/lib/sidebars/menu_spec.rb b/spec/lib/sidebars/menu_spec.rb
index 7577eeb8478..74ed344dd24 100644
--- a/spec/lib/sidebars/menu_spec.rb
+++ b/spec/lib/sidebars/menu_spec.rb
@@ -238,6 +238,47 @@ RSpec.describe Sidebars::Menu, feature_category: :navigation do
end
end
+ describe '#replace_placeholder' do
+ let(:item1) { Sidebars::NilMenuItem.new(item_id: :foo1) }
+ let(:item2) { Sidebars::MenuItem.new(item_id: :foo2, title: 'foo2', link: 'foo2', active_routes: {}) }
+ let(:item3) { Sidebars::NilMenuItem.new(item_id: :foo3) }
+
+ subject { menu.instance_variable_get(:@items) }
+
+ before do
+ menu.add_item(item1)
+ menu.add_item(item2)
+ menu.add_item(item3)
+ end
+
+ context 'when a NilMenuItem reference element exists' do
+ it 'replaces the reference element with the provided item' do
+ item = Sidebars::MenuItem.new(item_id: :foo1, title: 'target', active_routes: {}, link: 'target')
+ menu.replace_placeholder(item)
+
+ expect(subject).to eq [item, item2, item3]
+ end
+ end
+
+ context 'when a MenuItem reference element exists' do
+ it 'does not replace the reference element and adds to the end of the list' do
+ item = Sidebars::MenuItem.new(item_id: :foo2, title: 'target', active_routes: {}, link: 'target')
+ menu.replace_placeholder(item)
+
+ expect(subject).to eq [item1, item2, item3, item]
+ end
+ end
+
+ context 'when reference element does not exist' do
+ it 'adds the element to the end of the list' do
+ item = Sidebars::MenuItem.new(item_id: :new_element, title: 'target', active_routes: {}, link: 'target')
+ menu.replace_placeholder(item)
+
+ expect(subject).to eq [item1, item2, item3, item]
+ end
+ end
+ end
+
describe '#remove_element' do
let(:item1) { Sidebars::MenuItem.new(title: 'foo1', link: 'foo1', active_routes: {}, item_id: :foo1) }
let(:item2) { Sidebars::MenuItem.new(title: 'foo2', link: 'foo2', active_routes: {}, item_id: :foo2) }
diff --git a/spec/lib/sidebars/projects/menus/repository_menu_spec.rb b/spec/lib/sidebars/projects/menus/repository_menu_spec.rb
index b0631aacdb9..1aa0ea30d0a 100644
--- a/spec/lib/sidebars/projects/menus/repository_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/repository_menu_spec.rb
@@ -6,7 +6,11 @@ RSpec.describe Sidebars::Projects::Menus::RepositoryMenu, feature_category: :sou
let_it_be(:project) { create(:project, :repository) }
let(:user) { project.first_owner }
- let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project, current_ref: 'master') }
+ let(:is_super_sidebar) { false }
+ let(:context) do
+ Sidebars::Projects::Context.new(current_user: user, container: project, current_ref: 'master',
+ is_super_sidebar: is_super_sidebar)
+ end
subject { described_class.new(context) }
@@ -36,9 +40,8 @@ RSpec.describe Sidebars::Projects::Menus::RepositoryMenu, feature_category: :sou
end
context 'for menu items' do
- shared_examples_for 'repository menu item link for' do |item_id|
+ shared_examples_for 'repository menu item link for' do
let(:ref) { 'master' }
- let(:item_id) { item_id }
subject { described_class.new(context).renderable_items.find { |e| e.item_id == item_id }.link }
using RSpec::Parameterized::TableSyntax
@@ -77,10 +80,34 @@ RSpec.describe Sidebars::Projects::Menus::RepositoryMenu, feature_category: :sou
end
end
+ shared_examples_for 'repository menu item with different super sidebar title' do |title, super_sidebar_title|
+ subject { described_class.new(context).renderable_items.find { |e| e.item_id == item_id } }
+
+ specify do
+ expect(subject.title).to eq(title)
+ end
+
+ context 'when inside the super sidebar' do
+ let(:is_super_sidebar) { true }
+
+ specify do
+ expect(subject.title).to eq(super_sidebar_title)
+ end
+ end
+ end
+
+ describe 'Files' do
+ let_it_be(:item_id) { :files }
+
+ it_behaves_like 'repository menu item with different super sidebar title',
+ _('Files'),
+ _('Repository')
+ end
+
describe 'Commits' do
let_it_be(:item_id) { :commits }
- it_behaves_like 'repository menu item link for', :commits do
+ it_behaves_like 'repository menu item link for' do
let(:route) { "/#{project.full_path}/-/commits/#{ref}" }
end
end
@@ -103,16 +130,22 @@ RSpec.describe Sidebars::Projects::Menus::RepositoryMenu, feature_category: :sou
project.project_feature.update!(analytics_access_level: ProjectFeature::ENABLED)
end
- it_behaves_like 'repository menu item link for', :contributors do
+ it_behaves_like 'repository menu item link for' do
let(:route) { "/#{project.full_path}/-/graphs/#{ref}" }
end
end
end
describe 'Network' do
- it_behaves_like 'repository menu item link for', :graphs do
+ let_it_be(:item_id) { :graphs }
+
+ it_behaves_like 'repository menu item link for' do
let(:route) { "/#{project.full_path}/-/network/#{ref}" }
end
+
+ it_behaves_like 'repository menu item with different super sidebar title',
+ _('Graph'),
+ _('Repository graph')
end
end
end
diff --git a/spec/lib/sidebars/projects/menus/snippets_menu_spec.rb b/spec/lib/sidebars/projects/menus/snippets_menu_spec.rb
index c5fd407dae9..9d50eb6f817 100644
--- a/spec/lib/sidebars/projects/menus/snippets_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/snippets_menu_spec.rb
@@ -13,8 +13,7 @@ RSpec.describe Sidebars::Projects::Menus::SnippetsMenu, feature_category: :navig
let(:menu) { subject }
let(:extra_attrs) do
{
- super_sidebar_parent: ::Sidebars::Projects::Menus::RepositoryMenu,
- super_sidebar_before: :contributors,
+ super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::CodeMenu,
item_id: :project_snippets
}
end
diff --git a/spec/lib/sidebars/projects/super_sidebar_menus/analyze_menu_spec.rb b/spec/lib/sidebars/projects/super_sidebar_menus/analyze_menu_spec.rb
new file mode 100644
index 00000000000..b8d74665042
--- /dev/null
+++ b/spec/lib/sidebars/projects/super_sidebar_menus/analyze_menu_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Projects::SuperSidebarMenus::AnalyzeMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ let(:items) { subject.instance_variable_get(:@items) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Analyze"))
+ expect(subject.sprite_icon).to eq("chart")
+ end
+
+ it 'defines list of NilMenuItem placeholders' do
+ expect(items.map(&:class).uniq).to eq([Sidebars::NilMenuItem])
+ expect(items.map(&:item_id)).to eq([
+ :dashboards_analytics,
+ :cycle_analytics,
+ :contributors,
+ :ci_cd_analytics,
+ :repository_analytics,
+ :code_review,
+ :merge_requests,
+ :issues,
+ :insights
+ ])
+ end
+end
diff --git a/spec/lib/sidebars/projects/super_sidebar_menus/build_menu_spec.rb b/spec/lib/sidebars/projects/super_sidebar_menus/build_menu_spec.rb
new file mode 100644
index 00000000000..96e54d358c5
--- /dev/null
+++ b/spec/lib/sidebars/projects/super_sidebar_menus/build_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Projects::SuperSidebarMenus::BuildMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Build"))
+ expect(subject.sprite_icon).to eq("rocket")
+ end
+end
diff --git a/spec/lib/sidebars/projects/super_sidebar_menus/code_menu_spec.rb b/spec/lib/sidebars/projects/super_sidebar_menus/code_menu_spec.rb
new file mode 100644
index 00000000000..e307ff91234
--- /dev/null
+++ b/spec/lib/sidebars/projects/super_sidebar_menus/code_menu_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Projects::SuperSidebarMenus::CodeMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ let(:items) { subject.instance_variable_get(:@items) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Code"))
+ expect(subject.sprite_icon).to eq("code")
+ end
+
+ it 'defines list of NilMenuItem placeholders' do
+ expect(items.map(&:class).uniq).to eq([Sidebars::NilMenuItem])
+ expect(items.map(&:item_id)).to eq([
+ :files,
+ :branches,
+ :commits,
+ :tags,
+ :graphs,
+ :compare,
+ :project_snippets,
+ :file_locks
+ ])
+ end
+end
diff --git a/spec/lib/sidebars/projects/super_sidebar_menus/manage_menu_spec.rb b/spec/lib/sidebars/projects/super_sidebar_menus/manage_menu_spec.rb
new file mode 100644
index 00000000000..8c5f7aaaf36
--- /dev/null
+++ b/spec/lib/sidebars/projects/super_sidebar_menus/manage_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Projects::SuperSidebarMenus::ManageMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Manage"))
+ expect(subject.sprite_icon).to eq("users")
+ end
+end
diff --git a/spec/lib/sidebars/projects/super_sidebar_menus/monitor_menu_spec.rb b/spec/lib/sidebars/projects/super_sidebar_menus/monitor_menu_spec.rb
new file mode 100644
index 00000000000..6398e20efd0
--- /dev/null
+++ b/spec/lib/sidebars/projects/super_sidebar_menus/monitor_menu_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Projects::SuperSidebarMenus::MonitorMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Monitor"))
+ expect(subject.sprite_icon).to eq("monitor")
+ end
+end
diff --git a/spec/lib/sidebars/projects/super_sidebar_menus/operations_menu_spec.rb b/spec/lib/sidebars/projects/super_sidebar_menus/operations_menu_spec.rb
index df3f7e6cdab..54d4dcce264 100644
--- a/spec/lib/sidebars/projects/super_sidebar_menus/operations_menu_spec.rb
+++ b/spec/lib/sidebars/projects/super_sidebar_menus/operations_menu_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Sidebars::Projects::SuperSidebarMenus::OperationsMenu, feature_ca
subject { described_class.new({}) }
it 'has title and sprite_icon' do
- expect(subject.title).to eq(_("Operations"))
+ expect(subject.title).to eq(s_("Navigation|Operate"))
expect(subject.sprite_icon).to eq("deployments")
end
end
diff --git a/spec/lib/sidebars/projects/super_sidebar_menus/plan_menu_spec.rb b/spec/lib/sidebars/projects/super_sidebar_menus/plan_menu_spec.rb
index 3917d26f6f2..5f6f6e4f6c2 100644
--- a/spec/lib/sidebars/projects/super_sidebar_menus/plan_menu_spec.rb
+++ b/spec/lib/sidebars/projects/super_sidebar_menus/plan_menu_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Sidebars::Projects::SuperSidebarMenus::PlanMenu, feature_category
subject { described_class.new({}) }
it 'has title and sprite_icon' do
- expect(subject.title).to eq(_("Plan"))
+ expect(subject.title).to eq(s_("Navigation|Plan"))
expect(subject.sprite_icon).to eq("planning")
end
end
diff --git a/spec/lib/sidebars/projects/super_sidebar_menus/secure_menu_spec.rb b/spec/lib/sidebars/projects/super_sidebar_menus/secure_menu_spec.rb
new file mode 100644
index 00000000000..b68b33941c3
--- /dev/null
+++ b/spec/lib/sidebars/projects/super_sidebar_menus/secure_menu_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Sidebars::Projects::SuperSidebarMenus::SecureMenu, feature_category: :navigation do
+ subject { described_class.new({}) }
+
+ let(:items) { subject.instance_variable_get(:@items) }
+
+ it 'has title and sprite_icon' do
+ expect(subject.title).to eq(s_("Navigation|Secure"))
+ expect(subject.sprite_icon).to eq("shield")
+ end
+
+ it 'defines list of NilMenuItem placeholders' do
+ expect(items.map(&:class).uniq).to eq([Sidebars::NilMenuItem])
+ expect(items.map(&:item_id)).to eq([
+ :discover_project_security,
+ :audit_events,
+ :dashboard,
+ :vulnerability_report,
+ :on_demand_scans,
+ :scan_policies,
+ :dependency_list,
+ :license_compliance,
+ :configuration
+ ])
+ end
+end
diff --git a/spec/lib/sidebars/projects/super_sidebar_panel_spec.rb b/spec/lib/sidebars/projects/super_sidebar_panel_spec.rb
index d6fc3fd8fe1..30a3612b3aa 100644
--- a/spec/lib/sidebars/projects/super_sidebar_panel_spec.rb
+++ b/spec/lib/sidebars/projects/super_sidebar_panel_spec.rb
@@ -26,13 +26,16 @@ RSpec.describe Sidebars::Projects::SuperSidebarPanel, feature_category: :navigat
let(:category_menu) do
[
Sidebars::StaticMenu,
+ Sidebars::Projects::SuperSidebarMenus::ManageMenu,
Sidebars::Projects::SuperSidebarMenus::PlanMenu,
- Sidebars::Projects::Menus::RepositoryMenu,
- Sidebars::Projects::Menus::CiCdMenu,
- Sidebars::Projects::Menus::SecurityComplianceMenu,
+ Sidebars::Projects::SuperSidebarMenus::CodeMenu,
+ Sidebars::Projects::SuperSidebarMenus::BuildMenu,
+ Sidebars::Projects::SuperSidebarMenus::SecureMenu,
Sidebars::Projects::SuperSidebarMenus::OperationsMenu,
+ Sidebars::Projects::SuperSidebarMenus::MonitorMenu,
+ Sidebars::Projects::SuperSidebarMenus::AnalyzeMenu,
+ Sidebars::Projects::Menus::CiCdMenu,
Sidebars::Projects::Menus::MonitorMenu,
- Sidebars::Projects::Menus::AnalyticsMenu,
Sidebars::UncategorizedMenu,
Sidebars::Projects::Menus::SettingsMenu
]
diff --git a/spec/rubocop/cop/rspec/feature_category_on_shared_examples_spec.rb b/spec/rubocop/cop/rspec/feature_category_on_shared_examples_spec.rb
new file mode 100644
index 00000000000..6b337471f0a
--- /dev/null
+++ b/spec/rubocop/cop/rspec/feature_category_on_shared_examples_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'rubocop_spec_helper'
+require 'rspec-parameterized'
+
+require_relative '../../../../rubocop/cop/rspec/feature_category_on_shared_examples'
+
+RSpec.describe RuboCop::Cop::RSpec::FeatureCategoryOnSharedExamples, feature_category: :tooling do
+ it 'flags feature category in shared example' do
+ expect_offense(<<~RUBY)
+ RSpec.shared_examples 'foo', feature_category: :shared do
+ ^^^^^^^^^^^^^^^^^^^^^^^^^ Shared examples should not have feature category set
+ end
+
+ shared_examples 'foo', feature_category: :shared do
+ ^^^^^^^^^^^^^^^^^^^^^^^^^ Shared examples should not have feature category set
+ end
+ RUBY
+ end
+
+ it 'does not flag if feature category is missing' do
+ expect_no_offenses(<<~RUBY)
+ RSpec.shared_examples 'foo' do
+ end
+
+ shared_examples 'foo', some: :tag do
+ end
+ RUBY
+ end
+end