Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-02-16 18:11:03 +00:00
parent de288afc2f
commit 6c040cd502
62 changed files with 492 additions and 234 deletions

View File

@ -656,6 +656,11 @@
- "lib/gitlab/audit/type/definition.rb"
- "ee/lib/ee/gitlab/audit/type/definition.rb"
.custom-roles-patterns: &custom-roles-patterns
- "ee/config/custom_abilities/*.yml"
- "doc/user/custom_roles/abilities.md"
- "tooling/custom_roles/docs/templates/custom_abilities.md.erb"
##################
# Conditions set #
##################
@ -1197,6 +1202,16 @@
- <<: *if-default-refs
changes: *audit-events-patterns
############################
# Custom roles rules #
############################
.custom-roles:rules:custom-roles-verify:
rules:
- <<: *if-not-ee
when: never
- <<: *if-default-refs
changes: *custom-roles-patterns
##################
# Frontend rules #
##################

View File

@ -200,6 +200,19 @@ audit-event-types-verify:
script:
- bundle exec rake gitlab:audit_event_types:check_docs
custom-roles-verify:
variables:
SETUP_DB: "false"
extends:
- .default-retry
- .ruby-cache
- .default-before_script
- .custom-roles:rules:custom-roles-verify
stage: lint
needs: []
script:
- bundle exec rake gitlab:custom_roles:check_docs
templates-shellcheck:
extends:
- .ci-templates:rules:shellcheck

View File

@ -1 +1 @@
076bbe2525323fa920885350e0e81d81b2f58cf6
131b6727764a79bfe84c172b06aa4897230c805f

View File

@ -1074,7 +1074,7 @@ This file is located at:
DETAILS:
**Tier:** Premium, Ultimate
**Offering:** Self-Managed, SaaS
**Offering:** Saas, self-managed
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/120506) in GitLab 16.9.

View File

@ -8,13 +8,11 @@ info: Any user with at least the Maintainer role can merge updates to this conte
## Set up GitLab Duo Chat
NOTE:
Use [this snippet](https://gitlab.com/gitlab-org/gitlab/-/snippets/2554994) for help automating the following section.
There is a difference in the setup for Saas and self-managed instances.
We recommend to start with a process described for SaaS-only AI features.
1. [Enable Anthropic API features](index.md#configure-anthropic-access).
1. [Ensure the embedding database is configured](index.md#embeddings-database).
1. Ensure that your current branch is up-to-date with `master`.
1. Enable the feature in Rails console: `Feature.enable(:tanuki_bot_breadcrumbs_entry_point)`
1. [Setup SaaS-only AI features](index.md#test-saas-only-ai-features-locally).
1. [Setup self-managed AI features](index.md#test-ai-features-with-ai-gateway-locally).
## Working with GitLab Duo Chat

View File

@ -34,8 +34,8 @@ info: Any user with at least the Maintainer role can merge updates to this conte
Apply the following feature flags to any AI feature work:
- A general flag (`ai_duo_chat_switch`) that applies to all GitLab Duo Chat features.
- A general flag (`ai_global_switch`) that applies to all other AI features.
- A general flag (`ai_duo_chat_switch`) that applies to all GitLab Duo Chat features. It's enabled by default.
- A general flag (`ai_global_switch`) that applies to all other AI features. It's enabled by default.
- A flag specific to that feature. The feature flag name [must be different](../feature_flags/index.md#feature-flags-for-licensed-features) than the licensed feature name.
See the [feature flag tracker epic](https://gitlab.com/groups/gitlab-org/-/epics/10524) for the list of all feature flags and how to use them.
@ -55,33 +55,51 @@ See [below](#test-ai-features-with-ai-gateway-locally)
## Test SaaS-only AI features locally
**One-line setup**
**Automated setup**
Replace`<test-group-name>` with the group name you want to enable GitLab Duo features.
If the group doesn't exist, it creates a new one.
You might need to re-run the script multiple times,
it will print useful error messages with links to the docs on how to resolve the error.
```shell
# Replace the <test-group-name> by the group name you want to enable GitLab Duo features. If the group doesn't exist, it creates a new one.
RAILS_ENV=development bundle exec rake gitlab:duo:setup['<test-group-name>']
GITLAB_SIMULATE_SAAS=1 RAILS_ENV=development bundle exec rake 'gitlab:duo:setup[<test-group-name>]'
```
**Manual way**
1. Enable the required general feature flags:
```ruby
Feature.enable(:ai_duo_chat_switch, type: :ops)
Feature.enable(:ai_global_switch, type: :ops)
```
1. Ensure you have followed [the process to obtain an EE license](https://handbook.gitlab.com/handbook/developer-onboarding/#working-on-gitlab-ee-developer-licenses) for your local instance and you applied this license.
1. Simulate the GDK to [simulate SaaS](../ee_features.md#simulate-a-saas-instance) and ensure the group you want to test has an Ultimate license
1. Enable `Experiment & Beta features`
1. Ensure you have followed [the process to obtain an EE license](https://handbook.gitlab.com/handbook/developer-onboarding/#working-on-gitlab-ee-developer-licenses) for your local instance and you applied Ultimate license.
1. To verify that the license is applied go to **Admin Area** > **Subscription** and check the subscription plan.
1. Allow use of EE features for your instance.
1. Go to **Admin Area** > **Settings** > **General** -> **Account and limit**
1. Enable **Allow use of licensed EE features**
1. Simulate the GDK to [simulate SaaS](../ee_features.md#simulate-a-saas-instance).
1. Ensure the group you want to test has an Ultimate license.
1. Go to **Admin Area** > **Overview** > **Groups**
1. Select **Edit** for your chosen group.
1. Go to **Permissions and group features**
1. Choose *Ultimate* from the **Plan** list.
1. Enable `Experiment & Beta features` for your group.
1. Go to the group with the Ultimate license
1. **Group Settings** > **General** -> **Permissions and group features**
1. Enable **Experiment & Beta features**
1. Enable the specific feature flag for the feature you want to test
1. You can use Rake task `rake gitlab:duo:enable_feature_flags` to enable all feature flags that are assigned to group AI Framework
1. Setup [AI Gateway](#test-ai-features-with-ai-gateway-locally)
### Temporary workaround to avoid AI Gateway setup
NOTE:
You need to setup AI Gateway since GitLab 16.8.
It's a recommended way to test AI features. Sending requests directly to LLMs could lead to unnoticed bugs.
Use this workaround with caution.
To setup direct requests to LLMs you have to:
1. Disable a feature flag `gitlab_duo_chat_requests_to_ai_gateway`.
1. Set the required access token. To receive an access token:
1. For Vertex, follow the [instructions below](#configure-gcp-vertex-access).
1. For Anthropic, create an access request
1. For Anthropic, create [an access request](https://gitlab.com/gitlab-com/team-member-epics/access-requests/-/issues/new).
### Configure GCP Vertex access

View File

@ -864,8 +864,9 @@ See also:
## GitLab SaaS
Use **GitLab SaaS** to refer to the product offering.
It does not refer to the GitLab instance, which is [GitLab.com](#gitlabcom).
**GitLab SaaS** refers to both [GitLab.com](#gitlabcom) (multi-tenant SaaS) as well as [GitLab Dedicated](#gitlab-dedicated) (single-tenant SaaS).
Try to avoid **GitLab SaaS** and instead, refer to the [specific offering](#offerings) instead.
## GitLab self-managed
@ -873,7 +874,7 @@ Use **GitLab self-managed** to refer to the product offering. It refers to a Git
## GitLab.com
Use **GitLab.com** to refer to the URL. GitLab.com is the instance that's managed by GitLab.
Use **GitLab.com** to refer to the URL or product offering. GitLab.com is the instance that's managed by GitLab.
## guide
@ -1287,7 +1288,7 @@ Instead of:
The current product offerings are:
- [GitLab SaaS](#gitlab-saas)
- [GitLab.com](#gitlabcom)
- [GitLab self-managed](#gitlab-self-managed)
- [GitLab Dedicated](#gitlab-dedicated)

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Premium, Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
<!-- vale gitlab.FutureTense = NO -->

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -0,0 +1,184 @@
---
stage: Plan
group: Project Management
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Tutorial: Set up a single project for idea management
DETAILS:
**Tier:** Free, Premium, Ultimate
**Offering:** SaaS, self-managed
<!-- vale gitlab.FutureTense = NO -->
Idea management refers to the collection, organization, evaluation, and implementation of ideas
within an organization or community.
Ideas can originate from various stakeholders, such as employees, customers, or partners.
A separate idea backlog allows the team to capture and prioritize potential concepts and suggestions
before they're fully fleshed out.
Having this separate backlog enables efficient management of raw ideas.
It does so without cluttering the main backlog with unrefined or not validated concepts.
In this tutorial, you'll learn how to set up a GitLab project for idea management.
To set up GitLab for idea management in a project:
1. [Create a project](#create-a-project)
1. [Define the idea workflow](#define-the-idea-workflow)
1. [Document your criteria](#document-your-criteria)
1. [Create scoped labels](#create-scoped-labels)
1. [Create an idea status board](#create-an-idea-status-board)
1. [Stakeholders submit and vote on ideas](#stakeholders-submit-and-vote-on-ideas)
1. [Triage new ideas](#triage-new-ideas)
## Before you begin
- If you're using an existing project for this tutorial, make sure you have at least the Reporter role
for the project.
- If you follow the steps below and later decide to create a
parent group for your project, to make
best use of labels, you'll have to promote the project labels to group labels.
## Create a project
A project contains the issues that will be used to track ideas.
To create a blank project:
1. On the left sidebar, at the top, select **Create new** (**{plus}**) and **New project/repository**.
1. Select **Create blank project**.
1. Enter the project details.
- For **Project name**, enter `Idea management tutorial`.
1. Select **Create project**.
## Define the idea workflow
Next, you'll need to determine the **status workflow** that ideas will follow.
Communicating the status of an idea helps set the correct expectations with stakeholders.
For this tutorial, suppose you've decided on the following status workflow:
- `In Review`
- `Backlog`
- `In Progress`
- `Complete`
- `Rejected`
## Document your criteria
After you agree on the status workflow, write it all down somewhere your team mates can always access.
For example, add it to a [wiki](../../user/project/wiki/index.md) in your project, or your company
handbook published with [GitLab Pages](../../user/project/pages/index.md).
<!-- Idea for expanding this tutorial:
Add steps for [creating a wiki page](../../user/project/wiki/index.md#create-a-new-wiki-page). -->
## Create scoped labels
DETAILS:
**Tier:** Premium, Ultimate
**Offering:** SaaS, Self-managed
Next, you'll create labels to add to ideas to represent the status workflow.
The best tool for this is [scoped labels](../../user/project/labels.md#scoped-labels), which you
can use to set mutually exclusive attributes.
Checking with the list of statuses you've assembled
[previously](#define-the-idea-workflow), you'll want to create matching
scoped labels.
The double colon (`::`) in the name of a scoped label prevents two labels of the same scope being
used together.
For example, if you add the `status::backlog` label to an issue that already has `status::in review`, the
previous one is removed.
NOTE:
Scoped labels are available in the Premium and Ultimate tier.
If you're on the Free tier, you can use regular labels instead.
However, they aren't mutually exclusive.
To create each label:
1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Manage > Labels**.
1. Select **New label**.
1. In the **Title** field, enter the name of the label. Start with `status::in review`.
1. Optional. Select a color by selecting from the available colors, or enter a hex color value for
a specific color in the **Background color** field.
1. Select **Create label**.
Repeat these steps to create all the labels you'll need:
- `status::backlog`
- `status::in progress`
- `status::complete`
- `status::rejected`
## Create an idea status board
To prepare for the incoming ideas, create an [issue board](../../user/project/issue_board.md) that organizes ideas by label.
You'll use it to quickly create issues and add labels to them by dragging cards to various lists.
To set up your issue board:
1. On the left sidebar, select **Search or go to** and find your
**Idea management tutorial** project.
1. Select **Plan > Issue boards**.
1. In the upper-left corner of the issue board page, select the dropdown list with the current board name.
1. Select **Create new board**.
1. In the **Title field**, enter `Idea status workflow`.
1. Keep the **Show the Open list** checkbox selected and clear the **Show the Closed list** one.
1. Select **Create board**. You should see an empty board.
1. Create a list for the `status::in review` label:
1. In the upper-left corner of the issue board page, select **Create list**.
1. In the column that appears, from the **Value** dropdown list, select the `status::in review` label.
1. Select **Add to board**.
1. Repeat the previous step for labels `status::backlog`, `status::in progress`, `status::complete`, and `status::rejected`.
For now, the lists in your board should be empty. Next, you'll populate them with some issues.
![Idea status board](img/blank_idea_board_v16_10.png)
## Stakeholders submit and vote on ideas
Share your idea management project with stakeholders and invite them to document their ideas!
To invite your stakeholders:
1. On the left sidebar, select **Manage > Members**
1. Select **Invite members**
1. Type your stakeholders email address.
1. Select **Reporter** role.
Your stakeholders can now access your project to create new ideas:
1. On the left sidebar, select **Plan > Issues**
1. On the top right, select **New issue**
1. Enter a title and description.
1. Select **Create issue**
Stakeholders can also upvote an existing idea to signal that they are interested in an idea:
1. On the left sidebar, select **Plan > Issues**.
1. Select an issue.
1. Select the **Thumbs up** [emoji reaction](../../user/emoji_reactions.md) under the issue description.
## Triage new ideas
Try it out by dragging some issues from the **Open** list to one of the label lists to set the workflow status.
![Idea issue board with example issues](img/populated_idea_board_v16_10.png)
## Next steps
Next, you can:
- Create an [issue template](../../user/project/description_templates.md) to gather all the important
details from your stakeholders.
- Use [comments and threads](../../user/discussions/index.md) to gather more information about an idea.
- [Relate](../../user/project/issues/related_issues.md) issues in your team backlog to issues in your
idea project.

View File

@ -87,7 +87,7 @@ handbook published with [GitLab Pages](../../user/project/pages/index.md).
DETAILS:
**Tier:** Premium, Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
Next, you'll create labels to add to issues to categorize them.

View File

@ -15,6 +15,7 @@ issues, epics, and more.
| [GitLab Agile Project Management](https://levelup.gitlab.com/courses/gitlab-agile-project-management-s2) | Learn how to use planning features to manage your projects in this self-paced course. | **{star}** |
| [Build a protected workflow for your project](protected_workflow/index.md) | Set up a workflow for your teams, and enforce protections with approval rules. | |
| [Run an agile iteration](agile_sprint/index.md) | Use group, projects, and iterations to run an agile development iteration. | |
| [Set up a single project for idea management](idea_management/index.md) | Use an issue board and scoped labels to manage ideas in a team. | **{star}** |
| [Set up a single project for issue triage](issue_triage/index.md) | Use labels to set up a project for issue triage. | **{star}** |
| [Set up issue boards for team hand-off](boards_for_teams/index.md) | Use issue boards and scoped labels to set up collaboration across many teams. | **{star}** |
| <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Epics and issue boards](https://www.youtube.com/watch?v=eQUnHwbKEkY) | Find out how to use epics and issue boards for project management. | |

View File

@ -50,6 +50,9 @@ Some features are still in development. View details about [support for each sta
- View [how to enable this setting](group/manage.md#enable-experiment-and-beta-features).
- [Code Suggestions](project/repository/code_suggestions/index.md) is enabled when you purchase the
GitLab Duo Pro add-on and assign seats to users.
- [Chat](gitlab_duo_chat.md)
- View [how to enable for self-managed](gitlab_duo_chat.md#for-self-managed-users).
- View [how to enable for SaaS](gitlab_duo_chat.md#for-saas-users).
## Experimental AI features and how to use them

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
HTTP Archive (HAR) format files are an industry standard for exchanging information about HTTP
requests and HTTP responses. A HAR file's content is JSON formatted, containing browser interactions

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
Web API fuzzing performs fuzz testing of API operation parameters. Fuzz testing sets operation
parameters to unexpected values in an effort to cause unexpected behavior and errors in the API

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/9302) in GitLab 15.9. The API Discovery feature is in [Beta](../../../../policy/experiment-beta-support.md).

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
API Security refers to the measures taken to secure and protect web Application Programming Interfaces (APIs) from unauthorized access, misuse, and attacks.
APIs are a crucial component of modern application development as they allow applications to interact with each other and exchange data.

View File

@ -76,7 +76,7 @@ You can configure the following security controls:
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
You can configure the following security controls:

View File

@ -454,7 +454,7 @@ The `ADDITIONAL_CA_CERT_BUNDLE` value can also be configured as a [custom variab
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
To allowlist specific vulnerabilities, follow these steps:
@ -804,7 +804,7 @@ After a vulnerability is found, you can [address it](../vulnerabilities/index.md
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
Some vulnerabilities can be fixed by applying the solution that GitLab
automatically generates.

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/371063) in GitLab 16.4 as an [Experiment](../../../policy/experiment-beta-support.md#experiment) with two [features flags](../../../administration/feature_flags.md) named `dependency_scanning_on_advisory_ingestion` and `package_metadata_advisory_sync`. Enabled by default.
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/427424) in GitLab 16.7 with an additional feature flag named `global_dependency_scanning_on_advisory_ingestion`. Enabled by default.

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
Coverage-guided fuzz testing sends random inputs to an instrumented version of your application in
an effort to cause unexpected behavior. Such behavior indicates a bug that you should address.

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
WARNING:
**DO NOT** use credentials that are valid for production systems, production servers, or any that

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
The [logs](#read-the-logs) provide insight into what DAST is doing and expecting during the authentication process. For more detailed
information, configure the [authentication report](#configure-the-authentication-report).

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
The following troubleshooting scenarios have been collected from customer support cases. If you
experience a problem not addressed here, or the information here does not fix your problem, create a

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
WARNING:
Proxy-based DAST was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/430966) in GitLab

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
WARNING:
Do not run DAST scans against a production server. Not only can it perform *any* function that a user can, such

View File

@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
WARNING:
This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/430966) in GitLab 16.9 and will be removed in 17.0. Use [browser-based DAST](browser_based.md) instead. This change is a breaking change.

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
For self-managed GitLab instances in an environment with limited, restricted, or intermittent access
to external resources through the internet, some adjustments are required for the DAST job to

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
> DAST API analyzer [became the default analyzer for on-demand DAST API scans](https://gitlab.com/groups/gitlab-org/-/epics/4254) in GitLab 15.6.

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
> - System dependencies [introduced](https://gitlab.com/groups/gitlab-org/-/epics/6698) in GitLab 14.6.
> - Group-level dependency list [introduced](https://gitlab.com/groups/gitlab-org/-/epics/8090) in GitLab 16.2 [with a flag](../../../administration/feature_flags.md) named `group_level_dependencies`. Disabled by default.

View File

@ -45,7 +45,7 @@ table.no-vertical-table-lines tr {
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
Dependency Scanning analyzes your application's dependencies for known vulnerabilities. All
dependencies are scanned, including transitive dependencies, also known as nested dependencies.

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
For an overview, see [Adopting GitLab application security](https://www.youtube.com/watch?v=5QlxkiKR04k).

View File

@ -86,7 +86,7 @@ Supported configuration formats:
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
> Support for overriding rules [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/235359) in GitLab 14.8.

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
GitLab can check your application for security vulnerabilities including:

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
> [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/321258) in GitLab 14.4. Feature flag `security_orchestration_policies_configuration` removed.

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
> - Group-level security policies [introduced](https://gitlab.com/groups/gitlab-org/-/epics/4425) in GitLab 15.2.
> - Group-level security policies [enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/356258) in GitLab 15.4.

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
> - Group-level scan result policies [introduced](https://gitlab.com/groups/gitlab-org/-/epics/7622) in GitLab 15.6.
> - Scan result policies feature was renamed to merge request approval policies in GitLab 16.9.

View File

@ -80,7 +80,7 @@ content directly. Instead, it enhances the results with additional properties, i
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
## Transition to Semgrep-based scanning

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/235382) in GitLab 13.5.
> - [Enabled](https://gitlab.com/gitlab-org/gitlab/-/issues/339614) support for

View File

@ -134,7 +134,7 @@ the repository. For details on the Solution format, see the Microsoft reference
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
> - Introduced for Ruby in GitLab 14.2.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/378622) for Go in GitLab 15.8.
@ -153,7 +153,7 @@ False positive detection is available in a subset of the [supported languages](#
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5144) in GitLab 14.2.
@ -269,7 +269,7 @@ The [SAST report file](#output) is processed by GitLab and the details are shown
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
SAST results display in the merge request widget area if a report from the target
branch is available for comparison. The merge request widget displays SAST results and resolutions that
@ -281,7 +281,7 @@ were introduced by the changes made in the merge request.
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10959) in GitLab 16.6 with a [flag](../../../administration/feature_flags.md) named `sast_reports_in_inline_diff`. Disabled by default.
> - Enabled by default in GitLab 16.8.
@ -341,7 +341,7 @@ The method you can use depends on your GitLab license tier.
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
> [Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/410013) individual SAST analyzers configuration options from the UI in GitLab 16.2.

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Free, Premium, Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
GitLab SAST uses a set of [analyzers](analyzers.md) to scan code for potential vulnerabilities.
Each analyzer processes the code then uses rules to find possible weaknesses in source code.

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/4639) in GitLab 13.6.

View File

@ -331,7 +331,7 @@ To enable full history Secret Detection, set the variable `SECRET_DETECTION_HIST
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/211387) in GitLab 13.5.
> - [Enabled](https://gitlab.com/gitlab-org/gitlab/-/issues/339614) support for passthrough chains.

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
## Security Dashboards

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
When working with application security features, you might encounter the following issues.

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
Each vulnerability in a project has a vulnerability page containing details of the vulnerability,
including:

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
GitLab vulnerability analyzers attempt to return vulnerability severity level values whenever
possible. The following is a list of available GitLab vulnerability severity levels, ranked from

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
The Vulnerability Report provides information about vulnerabilities from scans of the default branch. It contains
cumulative results of all successful jobs, regardless of whether the pipeline was successful. The scan results from a

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Free, Premium, Ultimate
**Offering:** self-managed
**Offering:** Self-managed
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/39840) in GitLab 11.11.
> - [Deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.

View File

@ -99,7 +99,7 @@ Custom project templates are available at:
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13756) in GitLab 12.10

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/725) in GitLab 12.0.

View File

@ -338,7 +338,7 @@ You can [review recently triggered webhook payloads](#troubleshooting) in GitLab
## Configure webhooks to support mutual TLS
DETAILS:
**Offering:** self-managed
**Offering:** Self-managed
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27450) in GitLab 16.9.

View File

@ -36,8 +36,7 @@ merge request again.
## Rebase a merge request from the Rails console
DETAILS:
**tier:** Free, Premium, Ultimate
**Offering:** Self-managed
**Tier:** Free, Premium, Ultimate
In addition to the `/rebase` [quick action](../quick_actions.md#issues-merge-requests-and-epics),
users with access to the [Rails console](../../../administration/operations/rails_console.md)

View File

@ -385,7 +385,7 @@ and set **Maintainer** in the **Allowed to create** column.
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/259703) in GitLab Premium 13.9.

View File

@ -103,7 +103,7 @@ Evidence collection snapshots are visible on the Releases page, along with the t
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32773) in GitLab 13.2.

View File

@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
DETAILS:
**Tier:** Ultimate
**Offering:** SaaS, Self-managed
**Offering:** SaaS, self-managed
NOTE:
In 14.4, Requirements was moved under **Issues**.

View File

@ -105,6 +105,11 @@ pre-push:
files: git diff --name-only --diff-filter=d $(git merge-base origin/master HEAD)..HEAD
glob: '{config/audit_events/types/*.yml,ee/config/audit_events/types/*yml,doc/administration/audit_event_types.md,tooling/audit_events/docs/templates/audit_event_types.md.erb}'
run: bundle exec rake gitlab:audit_event_types:check_docs
custom_roles_docs:
tags: documentation
files: git diff --name-only --diff-filter=d $(git merge-base origin/master HEAD)..HEAD
glob: '{ee/config/custom_abilities/*yml,doc/user/custom_roles/abilities.md,tooling/custom_roles/docs/templates/custom_abilities.md.erb}'
run: bundle exec rake gitlab:custom_roles:check_docs
rubocop:
tags: backend style
files: git diff --name-only --diff-filter=d $(git merge-base origin/master HEAD)..HEAD

View File

@ -148,6 +148,7 @@ RSpec.describe '.gitlab/ci/rules.gitlab-ci.yml', feature_category: :tooling do
# Ignore EE-only patterns list when in FOSS context
relevant_patterns = foss_context ? patterns.reject { |pattern| pattern =~ %r|^{?ee/| } : patterns
next if relevant_patterns.empty?
next if foss_context && name == '.custom-roles-patterns'
PatternsList.new(name, relevant_patterns)
end

View File

@ -1,7 +1,9 @@
import { GlDropdownItem, GlSorting, GlFilteredSearch, GlFormCheckbox } from '@gitlab/ui';
import { shallowMount, mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
import waitForPromises from 'helpers/wait_for_promises';
import RecentSearchesService from '~/filtered_search/services/recent_searches_service';
import RecentSearchesStore from '~/filtered_search/stores/recent_searches_store';
import {
@ -34,45 +36,39 @@ jest.mock('~/vue_shared/components/filtered_search_bar/filtered_search_utils', (
).filterEmptySearchTerm,
}));
const createComponent = ({
shallow = true,
namespace = 'gitlab-org/gitlab-test',
recentSearchesStorageKey = 'requirements',
tokens = mockAvailableTokens,
sortOptions,
initialSortBy,
initialFilterValue = [],
showCheckbox = false,
checkboxChecked = false,
searchInputPlaceholder = 'Filter requirements',
} = {}) => {
const mountMethod = shallow ? shallowMount : mount;
return mountMethod(FilteredSearchBarRoot, {
propsData: {
namespace,
recentSearchesStorageKey,
tokens,
sortOptions,
initialSortBy,
initialFilterValue,
showCheckbox,
checkboxChecked,
searchInputPlaceholder,
},
});
const defaultProps = {
namespace: 'gitlab-org/gitlab-test',
recentSearchesStorageKey: 'requirements',
tokens: mockAvailableTokens,
initialFilterValue: [],
showCheckbox: false,
checkboxChecked: false,
searchInputPlaceholder: 'Filter requirements',
};
describe('FilteredSearchBarRoot', () => {
useLocalStorageSpy();
let wrapper;
const createComponent = ({ shallow = true, propsData = {} } = {}) => {
const mountMethod = shallow ? shallowMount : mount;
wrapper = mountMethod(FilteredSearchBarRoot, { propsData: { ...defaultProps, ...propsData } });
};
const findGlSorting = () => wrapper.findComponent(GlSorting);
const findGlFilteredSearch = () => wrapper.findComponent(GlFilteredSearch);
const findGlFormCheckbox = () => wrapper.findComponent(GlFormCheckbox);
const findGlDropdownItem = () => wrapper.findComponent(GlDropdownItem);
afterEach(() => {
localStorage.clear();
});
describe('data', () => {
describe('when `sortOptions` are provided', () => {
beforeEach(() => {
wrapper = createComponent({ sortOptions: mockSortOptions });
createComponent({ propsData: { sortOptions: mockSortOptions } });
});
it('sets a correct initial value for GlFilteredSearch', () => {
@ -95,7 +91,7 @@ describe('FilteredSearchBarRoot', () => {
});
it('does not initialize the sort dropdown when `sortOptions` are not provided', () => {
wrapper = createComponent();
createComponent();
expect(findGlSorting().exists()).toBe(false);
});
@ -104,6 +100,7 @@ describe('FilteredSearchBarRoot', () => {
describe('computed', () => {
describe('tokenSymbols', () => {
it('returns a map containing type and symbols from `tokens` prop', () => {
createComponent();
expect(wrapper.vm.tokenSymbols).toEqual({
[TOKEN_TYPE_AUTHOR]: '@',
[TOKEN_TYPE_LABEL]: '~',
@ -114,6 +111,7 @@ describe('FilteredSearchBarRoot', () => {
describe('tokenTitles', () => {
it('returns a map containing type and title from `tokens` prop', () => {
createComponent();
expect(wrapper.vm.tokenTitles).toEqual({
[TOKEN_TYPE_AUTHOR]: 'Author',
[TOKEN_TYPE_LABEL]: 'Label',
@ -124,7 +122,7 @@ describe('FilteredSearchBarRoot', () => {
describe('sortDirectionIcon', () => {
beforeEach(() => {
wrapper = createComponent({ sortOptions: mockSortOptions });
createComponent({ propsData: { sortOptions: mockSortOptions } });
});
it('passes isAscending=false to GlSorting by default', () => {
@ -141,7 +139,7 @@ describe('FilteredSearchBarRoot', () => {
describe('filteredRecentSearches', () => {
beforeEach(() => {
wrapper = createComponent();
createComponent();
});
it('returns array of recent searches filtering out any string type (unsupported) items', async () => {
@ -187,7 +185,7 @@ describe('FilteredSearchBarRoot', () => {
describe('events', () => {
it('emits component event `onFilter` with empty array and true when initially selected filter value was cleared', async () => {
wrapper = createComponent({ initialFilterValue: [tokenValueLabel] });
createComponent({ propsData: { initialFilterValue: [tokenValueLabel] } });
wrapper.findComponent(GlFilteredSearch).vm.$emit('clear');
@ -199,15 +197,16 @@ describe('FilteredSearchBarRoot', () => {
describe('methods', () => {
describe('setupRecentSearch', () => {
it('initializes `recentSearchesService` and `recentSearchesStore` props when `recentSearchesStorageKey` is available', () => {
createComponent();
expect(wrapper.vm.recentSearchesService instanceof RecentSearchesService).toBe(true);
expect(wrapper.vm.recentSearchesStore instanceof RecentSearchesStore).toBe(true);
});
it('initializes `recentSearchesPromise` prop with a promise by using `recentSearchesService.fetch()`', () => {
jest.spyOn(wrapper.vm.recentSearchesService, 'fetch').mockResolvedValue([]);
wrapper.vm.setupRecentSearch();
expect(localStorage.setItem).not.toHaveBeenCalled();
createComponent();
expect(localStorage.setItem).toHaveBeenCalledWith('canUseLocalStorage', 'true');
expect(wrapper.vm.recentSearchesPromise instanceof Promise).toBe(true);
});
});
@ -216,6 +215,7 @@ describe('FilteredSearchBarRoot', () => {
const mockFilters = [tokenValueAuthor, tokenValueLabel, tokenValueConfidential, 'foo'];
it('returns filter array with unescaped strings for values which have spaces', () => {
createComponent();
expect(wrapper.vm.removeQuotesEnclosure(mockFilters)).toEqual([
tokenValueAuthor,
tokenValueLabel,
@ -227,7 +227,7 @@ describe('FilteredSearchBarRoot', () => {
describe('handleSortOptionChange', () => {
it('emits component event `onSort` with selected sort by value', async () => {
wrapper = createComponent({ sortOptions: mockSortOptions });
createComponent({ propsData: { sortOptions: mockSortOptions } });
findGlSorting().vm.$emit('sortByChange', mockSortOptions[1].id);
await nextTick();
@ -239,9 +239,11 @@ describe('FilteredSearchBarRoot', () => {
describe('handleSortDirectionChange', () => {
beforeEach(() => {
wrapper = createComponent({
sortOptions: mockSortOptions,
initialSortBy: mockSortOptions[0].sortDirection.descending,
createComponent({
propsData: {
sortOptions: mockSortOptions,
initialSortBy: mockSortOptions[0].sortDirection.descending,
},
});
});
@ -263,24 +265,27 @@ describe('FilteredSearchBarRoot', () => {
describe('handleHistoryItemSelected', () => {
it('emits `onFilter` event with provided filters param', () => {
jest.spyOn(wrapper.vm, 'removeQuotesEnclosure');
wrapper.vm.handleHistoryItemSelected(mockHistoryItems[0]);
createComponent();
expect(wrapper.emitted('onFilter')).toEqual(undefined);
findGlFilteredSearch().vm.$emit('history-item-selected', mockHistoryItems[0]);
expect(wrapper.emitted('onFilter')[0]).toEqual([mockHistoryItems[0]]);
expect(wrapper.vm.removeQuotesEnclosure).toHaveBeenCalledWith(mockHistoryItems[0]);
});
});
describe('handleClearHistory', () => {
it('clears search history from recent searches store', () => {
createComponent();
jest.spyOn(wrapper.vm.recentSearchesStore, 'setRecentSearches').mockReturnValue([]);
jest.spyOn(wrapper.vm.recentSearchesService, 'save');
wrapper.vm.handleClearHistory();
expect(localStorage.setItem).toHaveBeenCalledTimes(2);
findGlFilteredSearch().vm.$emit('clear-history');
expect(wrapper.vm.recentSearchesStore.setRecentSearches).toHaveBeenCalledWith([]);
expect(wrapper.vm.recentSearchesService.save).toHaveBeenCalledWith([]);
expect(localStorage.setItem).toHaveBeenCalledTimes(4);
expect(localStorage.setItem).toHaveBeenLastCalledWith(
'gitlab-org/gitlab-test-requirements-recent-searches',
'[]',
);
expect(wrapper.vm.recentSearches).toEqual([]);
});
});
@ -289,7 +294,7 @@ describe('FilteredSearchBarRoot', () => {
const mockFilters = [tokenValueAuthor, 'foo'];
beforeEach(async () => {
wrapper = createComponent();
createComponent();
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
@ -319,25 +324,27 @@ describe('FilteredSearchBarRoot', () => {
});
it('calls `recentSearchesService.save` with array of searches', async () => {
jest.spyOn(wrapper.vm.recentSearchesService, 'save');
expect(localStorage.setItem).toHaveBeenCalledTimes(4);
findGlFilteredSearch().vm.$emit('submit');
await waitForPromises();
wrapper.vm.handleFilterSubmit();
await nextTick();
return wrapper.vm.recentSearchesPromise.then(() => {
expect(wrapper.vm.recentSearchesService.save).toHaveBeenCalledWith([mockFilters]);
});
expect(localStorage.setItem).toHaveBeenCalledTimes(6);
expect(localStorage.setItem).toHaveBeenLastCalledWith(
'gitlab-org/gitlab-test-requirements-recent-searches',
JSON.stringify([mockFilters]),
);
});
it('sets `recentSearches` data prop with array of searches', () => {
jest.spyOn(wrapper.vm.recentSearchesService, 'save');
it('sets `recentSearches` data prop with array of searches', async () => {
expect(localStorage.setItem).toHaveBeenCalledTimes(4);
findGlFilteredSearch().vm.$emit('submit');
await waitForPromises();
wrapper.vm.handleFilterSubmit();
return wrapper.vm.recentSearchesPromise.then(() => {
expect(wrapper.vm.recentSearches).toEqual([mockFilters]);
});
expect(localStorage.setItem).toHaveBeenCalledTimes(6);
expect(localStorage.setItem).toHaveBeenLastCalledWith(
'gitlab-org/gitlab-test-requirements-recent-searches',
JSON.stringify([mockFilters]),
);
});
it('calls `blurSearchInput` method to remove focus from filter input field', () => {
@ -349,20 +356,18 @@ describe('FilteredSearchBarRoot', () => {
});
it('emits component event `onFilter` with provided filters param', async () => {
jest.spyOn(wrapper.vm, 'removeQuotesEnclosure');
expect(wrapper.emitted('onFilter')).toEqual(undefined);
findGlFilteredSearch().vm.$emit('submit');
await nextTick();
expect(wrapper.emitted('onFilter')[0]).toEqual([mockFilters]);
expect(wrapper.vm.removeQuotesEnclosure).toHaveBeenCalledWith(mockFilters);
});
});
});
describe('template', () => {
it('renders gl-filtered-search component', async () => {
wrapper = createComponent();
createComponent();
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
await wrapper.setData({
@ -376,89 +381,70 @@ describe('FilteredSearchBarRoot', () => {
expect(glFilteredSearchEl.props('historyItems')).toEqual(mockHistoryItems);
});
it('renders checkbox when `showCheckbox` prop is true', () => {
let wrapperWithCheckbox = createComponent({
showCheckbox: true,
});
it('renders unchecked checkbox when `showCheckbox` prop is true', () => {
createComponent({ propsData: { showCheckbox: true } });
expect(findGlFormCheckbox().exists()).toBe(true);
expect(findGlFormCheckbox().attributes('checked')).not.toBeDefined();
});
expect(wrapperWithCheckbox.findComponent(GlFormCheckbox).exists()).toBe(true);
expect(
wrapperWithCheckbox.findComponent(GlFormCheckbox).attributes('checked'),
).not.toBeDefined();
wrapperWithCheckbox.destroy();
wrapperWithCheckbox = createComponent({
showCheckbox: true,
checkboxChecked: true,
});
expect(wrapperWithCheckbox.findComponent(GlFormCheckbox).attributes('checked')).toBe('true');
wrapperWithCheckbox.destroy();
it('renders checked checkbox when `checkboxChecked` prop is true', () => {
createComponent({ propsData: { showCheckbox: true, checkboxChecked: true } });
expect(findGlFormCheckbox().attributes('checked')).toBe('true');
});
it('renders search history items dropdown with formatting done using token symbols', async () => {
const wrapperFullMount = createComponent({ sortOptions: mockSortOptions, shallow: false });
wrapperFullMount.vm.recentSearchesStore.addRecentSearch(mockHistoryItems[0]);
createComponent({ propsData: { sortOptions: mockSortOptions }, shallow: false });
wrapper.vm.recentSearchesStore.addRecentSearch(mockHistoryItems[0]);
await nextTick();
const searchHistoryItemsEl = wrapperFullMount.findAll(
const searchHistoryItemsEl = wrapper.findAll(
'.gl-search-box-by-click-menu .gl-search-box-by-click-history-item',
);
expect(searchHistoryItemsEl.at(0).text()).toBe(
'Author := @rootLabel := ~bugMilestone := %v1.0"duo"',
);
wrapperFullMount.destroy();
});
describe('when token options have `title` attribute defined', () => {
it('renders search history items using the provided `title` attribute', async () => {
const wrapperFullMount = createComponent({
sortOptions: mockSortOptions,
tokens: [mockMembershipToken],
createComponent({
propsData: {
sortOptions: mockSortOptions,
tokens: [mockMembershipToken],
},
shallow: false,
});
wrapperFullMount.vm.recentSearchesStore.addRecentSearch([tokenValueMembership]);
wrapper.vm.recentSearchesStore.addRecentSearch([tokenValueMembership]);
await nextTick();
expect(wrapperFullMount.findComponent(GlDropdownItem).text()).toBe('Membership := Direct');
wrapperFullMount.destroy();
expect(findGlDropdownItem().text()).toBe('Membership := Direct');
});
});
describe('when token options have do not have `title` attribute defined', () => {
it('renders search history items using the provided `value` attribute', async () => {
const wrapperFullMount = createComponent({
sortOptions: mockSortOptions,
tokens: [mockMembershipTokenOptionsWithoutTitles],
createComponent({
propsData: {
sortOptions: mockSortOptions,
tokens: [mockMembershipTokenOptionsWithoutTitles],
},
shallow: false,
});
wrapperFullMount.vm.recentSearchesStore.addRecentSearch([tokenValueMembership]);
wrapper.vm.recentSearchesStore.addRecentSearch([tokenValueMembership]);
await nextTick();
expect(wrapperFullMount.findComponent(GlDropdownItem).text()).toBe('Membership := exclude');
wrapperFullMount.destroy();
expect(findGlDropdownItem().text()).toBe('Membership := exclude');
});
});
it('renders sort dropdown component', () => {
wrapper = createComponent({ sortOptions: mockSortOptions });
createComponent({ propsData: { sortOptions: mockSortOptions } });
expect(findGlSorting().exists()).toBe(true);
});
it('renders sort dropdown items', () => {
wrapper = createComponent({ sortOptions: mockSortOptions });
createComponent({ propsData: { sortOptions: mockSortOptions } });
const { sortOptions, sortBy } = findGlSorting().props();
@ -485,7 +471,7 @@ describe('FilteredSearchBarRoot', () => {
};
beforeEach(() => {
wrapper = createComponent({ sortOptions: mockSortOptions });
createComponent({ propsData: { sortOptions: mockSortOptions } });
});
it('syncs filter value', async () => {

View File

@ -0,0 +1,49 @@
# frozen_string_literal: true
RSpec.shared_examples 'checks if the doc is up-to-date' do
subject(:check_docs_task) { described_class.new(docs_dir, docs_path, template_erb_path).run }
shared_examples 'outputs an error' do
before do
stub_definitions
end
it 'raises an error' do
expect { check_docs_task }.to raise_error(SystemExit).and output(/#{error_message}/).to_stdout
end
end
context 'when custom_abilities.md is up to date' do
it 'outputs success message after checking the documentation' do
expect { check_docs_task }.to output(success_message).to_stdout
end
end
context 'when custom_abilities.md is updated manually' do
before do
File.write(docs_path, "Manually adding this line at the end of the custom_abilities.md", mode: 'a+')
end
it 'raises an error' do
expect { check_docs_task }.to raise_error(SystemExit).and output(/#{error_message}/).to_stdout
end
end
context 'when an existing custom ability is removed' do
let(:updated_definitions) { removed_definition }
it_behaves_like 'outputs an error'
end
context 'when a new custom ability is added' do
let(:updated_definitions) { added_definition }
it_behaves_like 'outputs an error'
end
context 'when an existing audit event type is updated' do
let(:updated_definitions) { updated_definition }
it_behaves_like 'outputs an error'
end
end

View File

@ -9,7 +9,9 @@ RSpec.describe Tasks::Gitlab::AuditEventTypes::CheckDocsTask, feature_category:
let(:docs_path) { Rails.root.join(docs_dir, 'audit_event_types.md') }
let(:template_erb_path) { Rails.root.join("tooling/audit_events/docs/templates/audit_event_types.md.erb") }
subject(:check_docs_task) { described_class.new(docs_dir, docs_path, template_erb_path) }
let(:stub_definitions) do
expect(Gitlab::Audit::Type::Definition).to receive(:definitions).and_return(updated_definitions)
end
describe '#run' do
before do
@ -17,51 +19,34 @@ RSpec.describe Tasks::Gitlab::AuditEventTypes::CheckDocsTask, feature_category:
Tasks::Gitlab::AuditEventTypes::CompileDocsTask.new(docs_dir, docs_path, template_erb_path).run
end
context 'when audit_event_types.md is up to date' do
it 'outputs success message after checking the documentation' do
expect { subject.run }.to output("Audit event types documentation is up to date.\n").to_stdout
end
let(:new_audit_event) do
{ new_audit_event: instance_double(Gitlab::Audit::Type::Definition,
name: 'new_audit_event',
description: 'some description',
feature_category: 'audit_events',
introduced_by_mr: 'https://mr',
introduced_by_issue: 'https://issue',
milestone: '16.0',
saved_to_database: true,
streamed: false
) }
end
context 'when audit_event_types.md is updated manually' do
before do
File.write(docs_path, "Manually adding this line at the end of the audit_event_types.md", mode: 'a+')
end
let(:added_definition) { Gitlab::Audit::Type::Definition.definitions.merge(new_audit_event) }
let(:removed_definition) { Gitlab::Audit::Type::Definition.definitions.except(:feature_flag_created) }
let(:updated_definition) do
definitions = Gitlab::Audit::Type::Definition.definitions
definitions[:feature_flag_created].attributes[:streamed] = false
it 'raises an error' do
expected_output = "Audit event types documentation is outdated! Please update it " \
"by running `bundle exec rake gitlab:audit_event_types:compile_docs`"
expect { subject.run }.to raise_error(SystemExit).and output(/#{expected_output}/).to_stdout
end
definitions
end
context 'when an existing audit event type is removed' do
let(:updated_definition) { Gitlab::Audit::Type::Definition.definitions.except(:feature_flag_created) }
it 'raises an error' do
expect(Gitlab::Audit::Type::Definition).to receive(:definitions).and_return(updated_definition)
expected_output = "Audit event types documentation is outdated! Please update it " \
"by running `bundle exec rake gitlab:audit_event_types:compile_docs`"
expect { subject.run }.to raise_error(SystemExit).and output(/#{expected_output}/).to_stdout
end
let(:success_message) { "Audit event types documentation is up to date.\n" }
let(:error_message) do
"Audit event types documentation is outdated! Please update it " \
"by running `bundle exec rake gitlab:audit_event_types:compile_docs`"
end
context 'when an existing audit event type is updated' do
let(:updated_definition) { Gitlab::Audit::Type::Definition.definitions }
it 'raises an error' do
updated_definition[:feature_flag_created].attributes[:streamed] = false
expect(Gitlab::Audit::Type::Definition).to receive(:definitions).and_return(updated_definition)
expected_output = "Audit event types documentation is outdated! Please update it " \
"by running `bundle exec rake gitlab:audit_event_types:compile_docs`"
expect { subject.run }.to raise_error(SystemExit).and output(/#{expected_output}/).to_stdout
end
end
it_behaves_like 'checks if the doc is up-to-date'
end
end