Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-09-06 15:13:23 +00:00
parent 65b6ccd12e
commit b333706699
60 changed files with 874 additions and 366 deletions

View File

@ -9,7 +9,7 @@ docs/CODEOWNERS @clefelhocz1 @timzallmann @cdu1 @whaber @dsatcher @sgoldstein @j
.gitlab/CODEOWNERS @clefelhocz1 @timzallmann @cdu1 @whaber @dsatcher @sgoldstein @jeromezng @stanhu
## Allows release tooling to update the Gitaly Version
GITALY_SERVER_VERSION @project_278964_bot6
GITALY_SERVER_VERSION @project_278964_bot6 @gitlab-org/maintainers/rails-backend @gitlab-org/delivery
## Excludes documentation markdown file changes from required approval
/doc/*.md

View File

@ -44,7 +44,7 @@ docs-lint markdown:
- .default-retry
- .docs:rules:docs-lint
# When updating the image version here, update it in /scripts/lint-doc.sh too.
image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-docs/lint-markdown:alpine-3.16-vale-2.17.0-markdownlint-0.31.1
image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-docs/lint-markdown:alpine-3.16-vale-2.20.1-markdownlint-0.32.2
stage: lint
needs: []
script:

View File

@ -23,7 +23,8 @@ first-line-h1: false
code-block-style:
style: "fenced"
emphasis-style: false
strong-style: false
link-fragments: false
reference-links-images: false
proper-names:
names: [
"Akismet",

View File

@ -3,10 +3,4 @@
Layout/HashAlignment:
Exclude:
- 'ee/spec/lib/ee/gitlab/usage_data_spec.rb'
- 'spec/controllers/projects/merge_requests_controller_spec.rb'
- 'spec/routing/project_routing_spec.rb'
- 'spec/serializers/ci/lint/job_entity_spec.rb'
- 'spec/serializers/container_repository_entity_spec.rb'
- 'spec/serializers/deployment_entity_spec.rb'
- 'spec/serializers/environment_serializer_spec.rb'
- 'spec/serializers/merge_request_metrics_helper_spec.rb'

View File

@ -483,7 +483,7 @@ gem 'ssh_data', '~> 1.3'
gem 'spamcheck', '~> 1.0.0'
# Gitaly GRPC protocol definitions
gem 'gitaly', '~> 15.3.0-rc4'
gem 'gitaly', '~> 15.4.0-rc2'
# KAS GRPC protocol definitions
gem 'kas-grpc', '~> 0.0.2'

View File

@ -531,7 +531,7 @@ GEM
rails (>= 3.2.0)
git (1.11.0)
rchardet (~> 1.8)
gitaly (15.3.0.pre.rc4)
gitaly (15.4.0.pre.rc2)
grpc (~> 1.0)
github-markup (1.7.0)
gitlab (4.16.1)
@ -1586,7 +1586,7 @@ DEPENDENCIES
gettext (~> 3.3)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.3)
gitaly (~> 15.3.0.pre.rc4)
gitaly (~> 15.4.0.pre.rc2)
github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5)
gitlab-dangerfiles (~> 3.5.1)

View File

@ -20,6 +20,8 @@ export const createAppOptions = (selector, apolloProvider) => {
const {
canGenerateCodequalityReports,
codequalityReportDownloadPath,
codequalityBlobPath,
codequalityProjectPath,
downloadablePathForReportType,
exposeSecurityDashboard,
exposeLicenseScanningData,
@ -40,9 +42,12 @@ export const createAppOptions = (selector, apolloProvider) => {
hasTestReport,
emptyStateImagePath,
artifactsExpiredImagePath,
isFullCodequalityReportAvailable,
testsCount,
} = dataset;
// TODO remove projectPath variable once https://gitlab.com/gitlab-org/gitlab/-/issues/371641 is resolved
const projectPath = fullPath;
const defaultTabValue = getPipelineDefaultTab(window.location.href);
return {
@ -63,6 +68,10 @@ export const createAppOptions = (selector, apolloProvider) => {
provide: {
canGenerateCodequalityReports: parseBoolean(canGenerateCodequalityReports),
codequalityReportDownloadPath,
codequalityBlobPath,
codequalityProjectPath,
isFullCodequalityReportAvailable: parseBoolean(isFullCodequalityReportAvailable),
projectPath,
defaultTabValue,
downloadablePathForReportType,
exposeSecurityDashboard: parseBoolean(exposeSecurityDashboard),

View File

@ -333,7 +333,7 @@
font-size: 13px;
line-height: 1.6em;
overflow-x: auto;
border-radius: 2px;
border-radius: $border-radius-default;
// Multi-line code blocks should scroll horizontally
code {

View File

@ -21,9 +21,30 @@ module Types
field :path, GraphQL::Types::String, null: false,
description: 'Path to the environment.'
field :slug, GraphQL::Types::String,
description: 'Slug of the environment.'
field :external_url, GraphQL::Types::String, null: true,
description: 'External URL of the environment.'
field :created_at, Types::TimeType,
description: 'When the environment was created.'
field :updated_at, Types::TimeType,
description: 'When the environment was updated.'
field :auto_stop_at, Types::TimeType,
description: 'When the environment is going to be stopped automatically.'
field :auto_delete_at, Types::TimeType,
description: 'When the environment is going to be deleted automatically.'
field :tier, Types::DeploymentTierEnum,
description: 'Deployment tier of the environment.'
field :environment_type, GraphQL::Types::String,
description: 'Folder name of the environment.'
field :metrics_dashboard, Types::Metrics::DashboardType, null: true,
description: 'Metrics dashboard schema for the environment.',
resolver: Resolvers::Metrics::DashboardResolver
@ -41,5 +62,9 @@ module Types
description: 'Deployments of the environment.',
resolver: Resolvers::DeploymentsResolver,
complexity: 150
def tier
object.tier.to_sym
end
end
end

View File

@ -6,7 +6,6 @@ module Projects
def js_pipeline_tabs_data(project, pipeline, _user)
{
can_generate_codequality_reports: pipeline.can_generate_codequality_reports?.to_json,
failed_jobs_count: pipeline.failed_builds.count,
failed_jobs_summary: prepare_failed_jobs_summary_data(pipeline.failed_builds),
full_path: project.full_path,

View File

@ -440,7 +440,6 @@ module ProjectsHelper
def show_inactive_project_deletion_banner?(project)
return false unless project.present? && project.saved?
return false unless delete_inactive_projects?
return false unless Feature.enabled?(:inactive_projects_deletion, project.root_namespace)
project.inactive?
end

View File

@ -17,4 +17,4 @@ module Preloaders
end
end
Preloaders::GroupPolicyPreloader.prepend_mod_with('Preloaders::GroupPolicyPreloader')
Preloaders::GroupPolicyPreloader.prepend_mod

View File

@ -0,0 +1,23 @@
# frozen_string_literal: true
module Preloaders
class ProjectPolicyPreloader
def initialize(projects, current_user)
@projects = projects
@current_user = current_user
end
def execute
return if projects.is_a?(ActiveRecord::NullRelation)
ActiveRecord::Associations::Preloader.new.preload(projects, { group: :route, namespace: :owner })
::Preloaders::UserMaxAccessLevelInProjectsPreloader.new(projects, current_user).execute
end
private
attr_reader :projects, :current_user
end
end
Preloaders::ProjectPolicyPreloader.prepend_mod

View File

@ -0,0 +1,37 @@
# frozen_string_literal: true
module Preloaders
class ProjectRootAncestorPreloader
def initialize(projects, namespace_sti_name = :namespace, root_ancestor_preloads = [])
@projects = projects
@namespace_sti_name = namespace_sti_name
@root_ancestor_preloads = root_ancestor_preloads
end
def execute
return if @projects.is_a?(ActiveRecord::NullRelation)
return unless ::Feature.enabled?(:use_traversal_ids)
root_query = Namespace.joins("INNER JOIN (#{join_sql}) as root_query ON root_query.root_id = namespaces.id")
.select('namespaces.*, root_query.id as source_id')
root_query = root_query.preload(*@root_ancestor_preloads) if @root_ancestor_preloads.any?
root_ancestors_by_id = root_query.group_by(&:source_id)
ActiveRecord::Associations::Preloader.new.preload(@projects, :namespace)
@projects.each do |project|
project.namespace.root_ancestor = root_ancestors_by_id[project.id]&.first
end
end
private
def join_sql
@projects
.joins(@namespace_sti_name)
.select('projects.id, namespaces.traversal_ids[1] as root_id')
.to_sql
end
end
end

View File

@ -51,4 +51,4 @@ module Preloaders
end
end
# Preloaders::UsersMaxAccessLevelInProjectsPreloader.prepend_mod
Preloaders::UsersMaxAccessLevelInProjectsPreloader.prepend_mod

View File

@ -1,3 +1,2 @@
%p
All discussions on merge request #{merge_request_reference_link(@merge_request)}
were resolved by #{sanitize_name(@resolved_by.name)}
= s_('Notify|All discussions on merge request %{mr_link} were resolved by %{name}') %{mr_link: sanitize(merge_request_reference_link(@merge_request)), name: sanitize_name(@resolved_by.name)}

View File

@ -39,8 +39,6 @@ module Projects
raise TimeoutError
end
next unless Feature.enabled?(:inactive_projects_deletion, project.root_namespace)
with_context(project: project, user: admin_user) do
deletion_warning_email_sent_on = notified_inactive_projects["project:#{project.id}"]

View File

@ -1,8 +0,0 @@
---
name: inactive_projects_deletion
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85689
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/357968
milestone: '15.0'
type: development
group: group::compliance
default_enabled: false

View File

@ -105,7 +105,10 @@ gitlab:
## Geo proxying with Separate URLs
Since GitLab 15.1, Geo secondary proxying is enabled by default for separate URLs also.
> Geo secondary proxying for separate URLs is [enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/346112) in GitLab 15.1.
NOTE:
The feature flag described in this section is planned to be deprecated and removed in a future release. Support for read-only Geo secondary sites is proposed in [issue 366810](https://gitlab.com/gitlab-org/gitlab/-/issues/366810), you can upvote and share your use cases in that issue.
There are minor known issues linked in the
["Geo secondary proxying with separate URLs" epic](https://gitlab.com/groups/gitlab-org/-/epics/6865).

View File

@ -6,18 +6,16 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Inactive project deletion **(FREE SELF)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85689) in GitLab 15.0 [with a flag](../administration/feature_flags.md) named `inactive_projects_deletion`. Disabled by default.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to
[enable the feature flag](../administration/feature_flags.md) named `inactive_projects_deletion`.
On GitLab.com, this feature is not available. This feature is not ready for production use.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85689) in GitLab 15.0 [with a flag](../administration/feature_flags.md) named `inactive_projects_deletion`. Disabled by default.
> - [Feature flag `inactive_projects_deletion`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96803) removed in GitLab 15.4.
Administrators of large GitLab instances can find that over time, projects become inactive and are no longer used.
These projects take up unnecessary disk space. With inactive project deletion, you can identify these projects, warn
the maintainers ahead of time, and then delete the projects if they remain inactive. When an inactive project is
deleted, the action generates an audit event that it was performed by the first active administrator.
For the default setting on GitLab.com, see the [GitLab.com settings page](../user/gitlab_com/index.md#inactive-project-deletion).
## Configure inactive project deletion
You can configure inactive projects deletion or turn it off using either:

View File

@ -11536,12 +11536,19 @@ Describes where code is deployed for a project.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="environmentautodeleteat"></a>`autoDeleteAt` | [`Time`](#time) | When the environment is going to be deleted automatically. |
| <a id="environmentautostopat"></a>`autoStopAt` | [`Time`](#time) | When the environment is going to be stopped automatically. |
| <a id="environmentcreatedat"></a>`createdAt` | [`Time`](#time) | When the environment was created. |
| <a id="environmentenvironmenttype"></a>`environmentType` | [`String`](#string) | Folder name of the environment. |
| <a id="environmentexternalurl"></a>`externalUrl` | [`String`](#string) | External URL of the environment. |
| <a id="environmentid"></a>`id` | [`ID!`](#id) | ID of the environment. |
| <a id="environmentlatestopenedmostseverealert"></a>`latestOpenedMostSevereAlert` | [`AlertManagementAlert`](#alertmanagementalert) | Most severe open alert for the environment. If multiple alerts have equal severity, the most recent is returned. |
| <a id="environmentname"></a>`name` | [`String!`](#string) | Human-readable name of the environment. |
| <a id="environmentpath"></a>`path` | [`String!`](#string) | Path to the environment. |
| <a id="environmentslug"></a>`slug` | [`String`](#string) | Slug of the environment. |
| <a id="environmentstate"></a>`state` | [`String!`](#string) | State of the environment, for example: available/stopped. |
| <a id="environmenttier"></a>`tier` | [`DeploymentTier`](#deploymenttier) | Deployment tier of the environment. |
| <a id="environmentupdatedat"></a>`updatedAt` | [`Time`](#time) | When the environment was updated. |
#### Fields with arguments

View File

@ -286,7 +286,7 @@ listed in the descriptions of the relevant settings.
| `default_snippet_visibility` | string | no | What visibility level new snippets receive. Can take `private`, `internal` and `public` as a parameter. Default is `private`. |
| `delayed_project_deletion` **(PREMIUM SELF)** | boolean | no | Enable delayed project deletion by default in new groups. Default is `false`. [From GitLab 15.1](https://gitlab.com/gitlab-org/gitlab/-/issues/352960), can only be enabled when `delayed_group_deletion` is true. |
| `delayed_group_deletion` **(PREMIUM SELF)** | boolean | no | Enable delayed group deletion. Default is `true`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/352959) in GitLab 15.0. [From GitLab 15.1](https://gitlab.com/gitlab-org/gitlab/-/issues/352960), disables and locks the group-level setting for delayed protect deletion when set to `false`. |
| `delete_inactive_projects` | boolean | no | Enable inactive project deletion feature. Default is `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/84519) in GitLab 14.10. [Became operational](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85689) in GitLab 15.0 (with feature flag `inactive_projects_deletion`, disabled by default). |
| `delete_inactive_projects` | boolean | no | Enable inactive project deletion feature. Default is `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/84519) in GitLab 14.10. [Became operational without feature flag](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96803) in GitLab 15.4. |
| `deletion_adjourned_period` **(PREMIUM SELF)** | integer | no | The number of days to wait before deleting a project or group that is marked for deletion. Value must be between `1` and `90`. Defaults to `7`. [From GitLab 15.1](https://gitlab.com/gitlab-org/gitlab/-/issues/352960), a hook on `deletion_adjourned_period` sets the period to `1` on every update, and sets both `delayed_project_deletion` and `delayed_group_deletion` to `false` if the period is `0`. |
| `diff_max_patch_bytes` | integer | no | Maximum [diff patch size](../user/admin_area/diff_limits.md), in bytes. |
| `diff_max_files` | integer | no | Maximum [files in a diff](../user/admin_area/diff_limits.md). |

View File

@ -79,7 +79,7 @@ cannot be cleaned by `autovacuum`. This highlight the need for small tables.
We will measure how much bloat we accumulate when [re]indexing huge tables. Base on this analysis,
we will be able to set up SLO (dead tuples / bloat), associated with [re]indexing.
Weve seen numerous S1 and S2 database-related production environment
We've seen numerous S1 and S2 database-related production environment
incidents, over the last couple of months, for example:
- S1: 2022-03-17 [Increase in writes in `ci_builds` table](https://gitlab.com/gitlab-com/gl-infra/production/-/issues/6625)
@ -135,7 +135,7 @@ remaining database tables when it becomes necessary.
It is also important to avoid large data migrations. We store almost 6
terabytes of data in the biggest CI/CD tables, in many different columns and
indexes. Migrating this amount of data might be challenging and could cause
instability in the production environment. Due to this concern, weve developed
instability in the production environment. Due to this concern, we've developed
a way to attach an existing database table as a partition zero without downtime
and excessive database locking, what has been demonstrated in one of the
[first proofs of concept](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80186).
@ -150,7 +150,7 @@ Our plan is to use logical partition IDs. We want to start with the
`ci_pipelines` table and create a `partition_id` column with a `DEFAULT` value
of `100` or `1000`. Using a `DEFAULT` value avoids the challenge of backfilling
this value for every row. Adding a `CHECK` constraint prior to attaching the
first partition tells PostgreSQL that weve already ensured consistency and
first partition tells PostgreSQL that we've already ensured consistency and
there is no need to check it while holding an exclusive table lock when
attaching this table as a partition to the routing table (partitioned schema
definition). We will increment this value every time we create a new partition
@ -256,12 +256,12 @@ smart enough to move rows between partitions on its own.
### Naming conventions
A partitioned table is called a __routing__ table and it will use the `p_`
A partitioned table is called a **routing** table and it will use the `p_`
prefix which should help us with building automated tooling for query analysis.
A table partition will be simply called __partition__ and it can use the a
A table partition will be simply called **partition** and it can use the a
physical partition ID as suffix, leaded by a `p` letter, for example
`ci_builds_p101`. Existing CI tables will become __zero partitions__ of the
`ci_builds_p101`. Existing CI tables will become **zero partitions** of the
new routing tables. Depending on the chosen
[partitioning strategy](#how-do-we-want-to-partition-cicd-data) for a given
table, it is possible to have many logical partitions per one physical partition.
@ -274,8 +274,8 @@ metadata table, called `ci_partitions`. In that table we would store metadata
about all the logical partitions, with many pipelines per partition. We may
need to store a range of pipeline ids per logical partition. Using it we will
be able to find the `partition_id` number for a given pipeline ID and we will
also find information about which logical partitions are “active” or
“archived”, which will help us to implement a time-decay pattern using database
also find information about which logical partitions are "active" or
"archived", which will help us to implement a time-decay pattern using database
declarative partitioning.
`ci_partitions` table will store information about a partition identifier,
@ -621,7 +621,7 @@ strategy. The strategy, described in this document, is subject to iteration as
well. Whenever we find a better way to reduce the risk and improve our plan, we
should update this document as well.
Weve managed to find a way to avoid large-scale data migrations, and we are
We've managed to find a way to avoid large-scale data migrations, and we are
building an iterative strategy for partitioning CI/CD data. We documented our
strategy here to share knowledge and solicit feedback from other team members.

View File

@ -176,7 +176,7 @@ Using phpenv also allows to easily configure the PHP environment with:
phpenv config-add my_config.ini
```
*__Important note:__ It seems `phpenv/phpenv`
**Important note:** It seems `phpenv/phpenv`
[is abandoned](https://github.com/phpenv/phpenv/issues/57). There is a fork
at [`madumlao/phpenv`](https://github.com/madumlao/phpenv) that tries to bring
the project back to life. [`CHH/phpenv`](https://github.com/CHH/phpenv) also

View File

@ -82,8 +82,7 @@ To enable merge trains for your project:
1. [Configure your CI/CD configuration file](merge_request_pipelines.md#prerequisites)
so that the pipeline or individual jobs run for merge requests.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Merge requests**.
1. On the left sidebar, select **Settings > Merge requests**.
1. In the **Merge method** section, verify that **Merge commit** is selected.
1. In the **Merge options** section, select **Enable merged results pipelines** (if not already selected) and **Enable merge trains**.
1. Select **Save changes**.

View File

@ -42,9 +42,8 @@ To enable merged results pipelines in a project, you must have at least the
Maintainer role:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Merge requests**.
1. Select **Enable merged results pipelines**.
1. On the left sidebar, select **Settings > Merge requests**.
1. In the **Merge options** section, select **Enable merged results pipelines**.
1. Select **Save changes**.
WARNING:

View File

@ -3882,16 +3882,13 @@ test:
### `trigger`
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8997) in GitLab Premium 11.8.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/199224) to GitLab Free in 12.8.
Use `trigger` to declare that a job is a "trigger job" which starts a
[downstream pipeline](../pipelines/downstream_pipelines.md) that is either:
- [A multi-project pipeline](../pipelines/downstream_pipelines.md#multi-project-pipelines).
- [A child pipeline](../pipelines/downstream_pipelines.md#parent-child-pipelines).
Trigger jobs can use only a limited set of the GitLab CI/CD configuration keywords.
Trigger jobs can use only a limited set of GitLab CI/CD configuration keywords.
The keywords available for use in trigger jobs are:
- [`trigger`](#trigger).
@ -3907,29 +3904,16 @@ The keywords available for use in trigger jobs are:
**Possible inputs**:
- For multi-project pipelines, path to the downstream project. CI/CD variables
[are supported](../variables/where_variables_can_be_used.md#gitlab-ciyml-file)
- For multi-project pipelines, the path to the downstream project. CI/CD variables [are supported](../variables/where_variables_can_be_used.md#gitlab-ciyml-file)
in GitLab 15.3 and later, but not [job-level persisted variables](../variables/where_variables_can_be_used.md#persisted-variables).
- For child pipelines, path to the child pipeline CI/CD configuration file.
Alternatively, use [`trigger:project](#triggerproject).
- For child pipelines, use [`trigger:include`](#triggerinclude).
**Example of `trigger` for multi-project pipeline**:
**Example of `trigger`**:
```yaml
rspec:
stage: test
script: bundle exec rspec
staging:
stage: deploy
trigger: my/deployment
```
**Example of `trigger` for child pipelines**:
```yaml
trigger_job:
trigger:
include: path/to/child-pipeline.yml
trigger-multi-project-pipeline:
trigger: my-group/my-project
```
**Additional details**:
@ -3938,8 +3922,6 @@ trigger_job:
- In [GitLab 13.5 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/201938), you
can use [`when:manual`](#when) in the same job as `trigger`. In GitLab 13.4 and
earlier, using them together causes the error `jobs:#{job-name} when should be on_success, on_failure or always`.
- In [GitLab 13.2 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/197140/), you can
view which job triggered a downstream pipeline in the [pipeline graph](../pipelines/index.md#visualize-pipelines).
- [Manual pipeline variables](../variables/index.md#override-a-defined-cicd-variable)
and [scheduled pipeline variables](../pipelines/schedules.md#add-a-pipeline-schedule)
are not passed to downstream pipelines by default. Use [trigger:forward](#triggerforward)
@ -3950,11 +3932,74 @@ trigger_job:
**Related topics**:
- [Multi-project pipeline configuration examples](../pipelines/downstream_pipelines.md#trigger-a-multi-project-pipeline-from-a-job-in-your-gitlab-ciyml-file).
- [Child pipeline configuration examples](../pipelines/downstream_pipelines.md#trigger-a-parent-child-pipeline).
- To run a pipeline for a specific branch, tag, or commit, you can use a [trigger token](../triggers/index.md)
to authenticate with the [pipeline triggers API](../../api/pipeline_triggers.md).
The trigger token is different than the `trigger` keyword.
#### `trigger:include`
Use `trigger:include` to declare that a job is a "trigger job" which starts a
[child pipeline](../pipelines/downstream_pipelines.md#parent-child-pipelines).
Use `trigger:include:artifact` to trigger a [dynamic child pipeline](../pipelines/downstream_pipelines.md#dynamic-child-pipelines).
**Keyword type**: Job keyword. You can use it only as part of a job.
**Possible inputs**:
- The path to the child pipeline's configuration file.
**Example of `trigger:include`**:
```yaml
trigger-child-pipeline:
trigger:
include: path/to/child-pipeline.gitlab-ci.yml
```
**Related topics**:
- [Child pipeline configuration examples](../pipelines/downstream_pipelines.md#trigger-a-parent-child-pipeline).
#### `trigger:project`
Use `trigger:project` to declare that a job is a "trigger job" which starts a
[multi-project pipeline](../pipelines/downstream_pipelines.md#multi-project-pipelines).
By default, the multi-project pipeline triggers for the default branch. Use `trigger:branch`
to specify a different branch.
**Keyword type**: Job keyword. You can use it only as part of a job.
**Possible inputs**:
- The path to the downstream project. CI/CD variables [are supported](../variables/where_variables_can_be_used.md#gitlab-ciyml-file)
in GitLab 15.3 and later, but not [job-level persisted variables](../variables/where_variables_can_be_used.md#persisted-variables).
**Example of `trigger:project`**:
```yaml
trigger-multi-project-pipeline:
trigger:
project: my-group/my-project
```
**Example of `trigger:project` for a different branch**:
```yaml
trigger-multi-project-pipeline:
trigger:
project: my-group/my-project
branch: development
```
**Related topics**:
- [Multi-project pipeline configuration examples](../pipelines/downstream_pipelines.md#trigger-a-multi-project-pipeline-from-a-job-in-your-gitlab-ciyml-file).
- To run a pipeline for a specific branch, tag, or commit, you can also use a [trigger token](../triggers/index.md)
to authenticate with the [pipeline triggers API](../../api/pipeline_triggers.md).
The trigger token is different than the `trigger` keyword.
#### `trigger:strategy`
Use `trigger:strategy` to force the `trigger` job to wait for the downstream pipeline to complete

View File

@ -53,8 +53,13 @@ end
## Add a `NOT NULL` constraint to an existing column
Adding `NOT NULL` to existing database columns requires multiple steps split into at least two
different releases:
Adding `NOT NULL` to existing database columns usually requires multiple steps split into at least two
different releases. If your table is small enough that you don't need to
use a background migration, you can include all these in the same merge
request. We recommend to use separate migrations to reduce
transaction durations.
The steps required are:
1. Release `N.M` (current release)

View File

@ -81,7 +81,7 @@ text = "foo\nbar"
p text.match /^bar$/
```
The output of this example is `#<MatchData "bar">`, as Ruby treats the input `text` line by line. In order to match the whole __string__ the Regex anchors `\A` and `\z` should be used.
The output of this example is `#<MatchData "bar">`, as Ruby treats the input `text` line by line. To match the whole **string**, the Regex anchors `\A` and `\z` should be used.
#### Impact

View File

@ -0,0 +1,124 @@
---
stage: Systems
group: Distribution
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Comparison of GitLab self-managed with GitLab SaaS
GitLab SaaS is the largest hosted instance of GitLab in the world, managed by an
[all-remote team](https://about.gitlab.com/company/culture/all-remote/) that knows GitLab best. With GitLab SaaS, updates, maintenance, and patches are all performed by this team.
Self-managed GitLab gives you a deeper breadth of control over many of the functions and systems of the application.
## Administration
In GitLab SaaS, administration tasks are limited compared to a self-managed application.
In a self-managed instance:
- You have complete access and administrative control over the application, including the [Admin Area](../../user/admin_area/settings/index.md).
- You can impersonate, create, add, and remove users.
- You can assign the [`Auditor`](../../administration/auditor_users.md) user type and `External` role.
On GitLab SaaS:
- You have limited administrative control. For example, you cannot impersonate, create, add, or remove users.
- You cannot access the [Admin Area](../../user/admin_area/settings/index.md).
- You cannot assign the `Auditor` user type and `External` role.
## Logs
Logs give insight into your processes and can help GitLab Support maintain your application and resolve problems.
In a self-managed instance:
- You have full access to system logs.
On GitLab SaaS:
- You do not have access to system logs because they are at the instance level, and managed by the GitLab [infrastructure team](https://about.gitlab.com/handbook/engineering/infrastructure/).
- You can view [Audit Events](../../administration/audit_events.md) and the [GitLab API](../../api/audit_events.md).
- You must [request audit information](https://about.gitlab.com/handbook/support/workflows/log_requests.html) from the Support team.
## Runners
Runners are available for both SaaS and self-managed applications.
In a self-managed instance, your runner availability and options are broader, but there are more [security concerns](https://docs.gitlab.com/runner/security/#security-for-self-managed-runners) to consider.
On GitLab SaaS:
- Private [runners](../../ci/runners/index.md) are available for GitLab SaaS [groups](../../user/group/index.md) and [projects](../../user/project/index.md).
- Shared runners provided by GitLab SaaS are not configurable. Each runner instance is used once for only one job, ensuring any sensitive data left on the system is destroyed after the job is complete.
- Shared runners are subject to usage limits and are [plan specific](https://about.gitlab.com/pricing/).
## Custom Git hooks
In a self-managed instance you can use any custom Git hooks.
On GitLab SaaS:
- SaaS users do not have access to the file system, and cannot use custom Git hooks.
- You can use [webhooks](../../user/project/integrations/webhooks.md) as an alternative.
## API and GraphQL
In a self-managed instance, users can access all API endpoints, including those that require instance `admin` permissions.
On GitLab SaaS:
- SaaS users have access to all of the [API endpoints](../../api/index.md) except those that require instance `admin` permissions.
- Only authorized GitLab engineers have administrative access.
## Authentication
In a self-managed instance:
- You can use an internal encryption key for your data store.
- You can view console logs.
- You can enforce jobs on every pipeline across the group or organization.
- You have control over your data backup.
- You can use the [Interactive Web Terminal](../../ci/interactive_web_terminal/index.md#interactive-web-terminals) for shared runners.
On GitLab SaaS:
- You cannot use internal encryption key for the data store ([bring-your-own-key](https://about.gitlab.com/handbook/engineering/security/vulnerability_management/encryption-policy.html#rolling-your-own-crypto)).
- You cannot view console logs.
- You cannot enforce jobs on every pipeline across the group or organization.
- You cannot configure or control data backups. You must use [group](../../api/group_import_export.md) and [project](../../api/project_import_export.md) export.
- The [Interactive Web Terminal](../../ci/interactive_web_terminal/index.md#interactive-web-terminals) is not available for shared runners.
## Public or private projects
Project privacy is different when using a self-managed application or GitLab SaaS.
In a self-managed instance, you control who can view your projects.
On GitLab SaaS:
- The GitLab SaaS instance is open to the public.
- When your projects are set as `Public`, they are open to everyone on the public internet.
## Encryption
In a self-managed instance, you control the encryption type and configuration.
On GitLab SaaS:
- An [Access Management Process](https://about.gitlab.com/handbook/engineering/security/#access-management-process) is in place.
- All data on GitLab.com is encrypted at rest by default. Access to encryption keys is strictly managed by GitLab.
- GitLab does not access your tenant data except as part of a verified service request from you.
## Support
In a self-managed instance:
- You can access any of your back-end systems.
- Our Support team can request logs to assist you.
On GitLab SaaS:
- For your privacy and security, there is no public access to GitLab back-end systems.
- Support staff work with [Site Reliability Engineers](https://about.gitlab.com/job-families/engineering/infrastructure/site-reliability-engineer/) to support the [infrastructure](https://about.gitlab.com/handbook/engineering/infrastructure/).
- GitLab Support can access instance logs and view projects, as well as impersonate users. The Support Team can access your logs.

View File

@ -55,9 +55,8 @@ You can prevent merge requests from being merged if they do not refer to a Jira
To enforce this:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Merge requests**.
1. Under **Merge checks**, select the **Require an associated issue from Jira** checkbox.
1. On the left sidebar, select **Settings > Merge requests**.
1. In the **Merge checks** section, select **Require an associated issue from Jira**.
1. Select **Save**.
After you enable this feature, a merge request that doesn't reference an associated

View File

@ -340,9 +340,8 @@ resolved. When this setting is enabled, the **Unresolved threads** counter in a
is shown in orange when at least one thread remains unresolved.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Merge requests**.
1. Under **Merge checks**, select the **All threads must be resolved** checkbox.
1. On the left sidebar, select **Settings > Merge requests**.
1. In the **Merge checks** section, select the **All threads must be resolved** checkbox.
1. Select **Save changes**.
### Automatically resolve threads in a merge request when they become outdated
@ -351,10 +350,9 @@ You can set merge requests to automatically resolve threads when lines are modif
with a new push.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Merge requests**.
1. Under **Merge options**, select the
**Automatically resolve merge request diff threads when they become outdated** checkbox.
1. On the left sidebar, select **Settings > Merge requests**.
1. In the **Merge options** section, select
**Automatically resolve merge request diff threads when they become outdated**.
1. Select **Save changes**.
Threads are now resolved if a push makes a diff section outdated.

View File

@ -774,6 +774,8 @@ Combined emphasis with **asterisks and _underscores_**.
Strikethrough uses two tildes. ~~Scratch this.~~
```
<!-- markdownlint-disable MD050 -->
Emphasis, aka italics, with *asterisks* or _underscores_.
Strong emphasis, aka bold, with double **asterisks** or __underscores__.
@ -782,6 +784,8 @@ Combined emphasis with **asterisks and _underscores_**.
Strikethrough uses two tildes. ~~Scratch this.~~
<!-- markdownlint-enable MD050 -->
#### Multiple underscores in words and mid-word emphasis
If this section isn't rendered correctly,

View File

@ -135,9 +135,8 @@ To set a default description template for merge requests, either:
- Users on GitLab Premium and higher: set the default template in project settings:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings**.
1. Expand **Merge requests**.
1. Fill in the **Default description template for merge requests** text area.
1. On the left sidebar, select **Settings > Merge requests**.
1. In the **Merge commit message template** section, fill in **Default description template for merge requests**.
1. Select **Save changes**.
To set a default description template for issues, either:

View File

@ -32,8 +32,9 @@ use the default approval rules from the target (upstream) project, not the sourc
To add a merge request approval rule:
1. Go to your project and select **Settings > General**.
1. Expand **Merge request (MR) approvals**, and then select **Add approval rule**.
1. Go to your project and select **Settings > Merge requests**.
1. In the **Merge request approvals** section, scroll to **Approval rules**.
1. Select **Add approval rule**.
1. Add a human-readable **Rule name**.
1. Set the number of required approvals in **Approvals required**. A value of `0` makes
[the rule optional](#configure-optional-approval-rules), and any number greater than `0`
@ -65,8 +66,9 @@ to existing merge requests:
To edit a merge request approval rule:
1. Go to your project and select **Settings > General**.
1. Expand **Merge request (MR) approvals**, and then select **Edit**.
1. Go to your project and select **Settings > Merge requests**.
1. In the **Merge request approvals** section, scroll to **Approval rules**.
1. Select **Edit** next to the rule you want to edit.
1. Optional. Change the **Rule name**.
1. Set the number of required approvals in **Approvals required**. The minimum value is `0`.
1. Add or remove eligible approvers, as needed:
@ -155,11 +157,11 @@ approve in these ways:
If you add [code owners](../../code_owners.md) to your repository, the owners of files
become eligible approvers in the project. To enable this merge request approval rule:
1. Go to your project and select **Settings > General**.
1. Expand **Merge request (MR) approvals**.
1. Locate **All eligible users** and select the number of approvals required:
1. Go to your project and select **Settings > Merge requests**.
1. In the **Merge request approvals** section, scroll to **Approval rules**.
1. Locate the **All eligible users** rule, and select the number of approvals required:
![MR approvals by Code Owners](img/mr_approvals_by_code_owners_v15_2.png)
![MR approvals by Code Owners](img/mr_approvals_by_code_owners_v15_2.png)
You can also
[require code owner approval](../../protected_branches.md#require-code-owner-approval-on-a-protected-branch)
@ -182,9 +184,10 @@ granting them push access:
and select the Reporter role for the user.
1. [Share the project with your group](../../members/share_project_with_groups.md#share-a-project-with-a-group-of-users),
based on the Reporter role.
1. Go to your project and select **Settings > General**.
1. Expand **Merge request (MR) approvals**.
1. Select **Add approval rule** or **Update approval rule** and target the protected branch.
1. Go to your project and select **Settings > Merge requests**.
1. In the **Merge request approvals** section, scroll to **Approval rules**, and either:
- For a new rule, select **Add approval rule** and target the protected branch.
- For an existing rule, select **Edit** and target the protected branch.
1. [Add the group](../../../group/manage.md#create-a-group) to the permission list.
![Update approval rule](img/update_approval_rule_v13_10.png)
@ -226,12 +229,12 @@ Approval rules are often relevant only to specific branches, like your
approval rule for certain branches:
1. [Create an approval rule](#add-an-approval-rule).
1. Go to your project and select **Settings**.
1. Expand **Merge request (MR) approvals**.
1. Go to your project and select **Settings > Merge requests**.
1. In the **Merge request approvals** section, scroll to **Approval rules**.
1. Select a **Target branch**:
- To apply the rule to all branches, select **All branches**.
- To apply the rule to all protected branches, select **All protected branches** (GitLab 15.3 and later).
- To apply the rule to a specific branch, select it from the list:
- To apply the rule to a specific branch, select it from the list.
1. To enable this configuration, read
[Code Owner's approvals for protected branches](../../protected_branches.md#require-code-owner-approval-on-a-protected-branch).

View File

@ -16,8 +16,8 @@ those rules are applied as a merge request moves toward completion.
To view or edit merge request approval settings:
1. Go to your project and select **Settings > General**.
1. Expand **Merge request (MR) approvals**.
1. Go to your project and select **Settings > Merge requests**.
1. Expand **Approvals**.
### Approval settings
@ -44,9 +44,9 @@ You can further define what happens to existing approvals when commits are added
By default, the author of a merge request cannot approve it. To change this setting:
1. Go to your project and select **Settings > General**.
1. Expand **Merge request (MR) approvals**.
1. Clear the **Prevent approval by author** checkbox.
1. On the left sidebar, select **Settings > Merge requests**.
1. In the **Merge request approvals** section, scroll to **Approval settings** and
clear the **Prevent approval by author** checkbox.
1. Select **Save changes**.
Authors can edit the approval rule in an individual merge request and override
@ -68,9 +68,9 @@ the project level or [instance level](../../../admin_area/merge_requests_approva
you can prevent committers from approving merge requests that are partially
their own. To do this:
1. Go to your project and select **Settings > General**.
1. Expand **Merge request (MR) approvals**.
1. Select the **Prevent approvals by users who add commits** checkbox.
1. On the left sidebar, select **Settings > Merge requests**.
1. In the **Merge request approvals** section, scroll to **Approval settings** and
select **Prevent approvals by users who add commits**.
If this checkbox is cleared, an administrator has disabled it
[at the instance level](../../../admin_area/merge_requests_approvals.md), and
it can't be changed at the project level.
@ -94,9 +94,9 @@ By default, users can override the approval rules you [create for a project](rul
on a per-merge-request basis. If you don't want users to change approval rules
on merge requests, you can disable this setting:
1. Go to your project and select **Settings > General**.
1. Expand **Merge request (MR) approvals**.
1. Select the **Prevent editing approval rules in merge requests** checkbox.
1. On the left sidebar, select **Settings > Merge requests**.
1. In the **Merge request approvals** section, scroll to **Approval settings** and
select **Prevent editing approval rules in merge requests**.
1. Select **Save changes**.
This change affects all open merge requests.
@ -112,9 +112,9 @@ permission enables an electronic signature for approvals, such as the one define
1. Enable password authentication for the web interface, as described in the
[sign-in restrictions documentation](../../../admin_area/settings/sign_in_restrictions.md#password-authentication-enabled).
1. Go to your project and select **Settings > General**.
1. Expand **Merge request (MR) approvals**.
1. Select the **Require user password to approve** checkbox.
1. On the left sidebar, select **Settings > Merge requests**.
1. In the **Merge request approvals** section, scroll to **Approval settings** and
select **Require user password to approve**.
1. Select **Save changes**.
## Remove all approvals when commits are added to the source branch
@ -123,9 +123,9 @@ By default, an approval on a merge request remains in place, even if you add mor
after the approval. If you want to remove all existing approvals on a merge request
when more changes are added to it:
1. Go to your project and select **Settings > General**.
1. Expand **Merge request (MR) approvals**.
1. Select the **Remove all approvals when commits are added to the source branch** checkbox.
1. On the left sidebar, select **Settings > Merge requests**.
1. In the **Merge request approvals** section, scroll to **Approval settings** and
select **Remove all approvals when commits are added to the source branch**.
1. Select **Save changes**.
Approvals aren't removed when a merge request is [rebased from the UI](../methods/index.md#rebasing-in-semi-linear-merge-methods)
@ -143,10 +143,9 @@ Prerequisite:
To do this:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Merge request approvals**.
1. Select **Remove approvals by Code Owners if their files changed**.
1. On the left sidebar, select **Settings > Merge requests**.
1. In the **Merge request approvals** section, scroll to **Approval settings** and
select **Remove approvals by Code Owners if their files changed**.
1. Select **Save changes**.
## Code coverage check approvals

View File

@ -30,7 +30,7 @@ Prerequisite:
To do this:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > General** and expand **Merge requests**.
1. On the left sidebar, select **Settings > Merge requests**.
1. Depending on the type of template you want to create, scroll to either
[**Merge commit message template**](#default-template-for-merge-commits) or
[**Squash commit message template**](#default-template-for-squash-commits).

View File

@ -57,9 +57,8 @@ does not disable this feature, as it is possible to use pipelines from external
CI providers with this feature. To enable it, you must:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Merge requests**.
1. Under **Merge checks**, select the **Pipelines must succeed** checkbox.
1. On the left sidebar, select **Settings > Merge requests**.
1. In the **Merge checks** section, select **Pipelines must succeed**.
1. Select **Save**.
This setting also prevents merge requests from being merged if there is no pipeline.
@ -106,11 +105,10 @@ When the **Pipelines must succeed** checkbox is checked, [skipped pipelines](../
merge requests from being merged. To change this behavior:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Merge requests**.
1. Under **Merge checks**:
1. On the left sidebar, select **Settings > Merge requests**.
1. In the **Merge checks** section:
- Ensure **Pipelines must succeed** is selected.
- Select the **Skipped pipelines are considered successful** checkbox.
- Select **Skipped pipelines are considered successful**.
1. Select **Save**.
## From the command line

View File

@ -13,8 +13,7 @@ merge requests are merged into an existing branch.
## Configure a project's merge method
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Merge requests**.
1. On the left sidebar, select **Settings > Merge requests**.
1. In the **Merge method** section, select your desired merge method.
1. Select **Save changes**.

View File

@ -61,8 +61,7 @@ squash the commits as part of the merge process:
To configure the default squashing behavior for all merge requests in your project:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Merge requests**.
1. On the left sidebar, select **Settings > Merge requests**.
1. In the **Squash commits when merging** section, select your desired behavior:
- **Do not allow**: Squashing is never performed, and the option is not displayed.
- **Allow**: Squashing is allowed, but cleared by default.

View File

@ -61,9 +61,8 @@ using the API. You don't need to wait for a merge request webhook payload to be
Within each project's settings, you can see a list of status checks added to the project:
1. In your project, go to **Settings > General**.
1. Expand the **Merge requests** section.
1. Scroll down to the **Status checks** sub-section.
1. In your project, go to **Settings > Merge requests** section.
1. Scroll down to **Status checks**.
![Status checks list](img/status_checks_list_view_v14_0.png)

View File

@ -85,8 +85,20 @@ module Gitlab
target_commit = Gitlab::Git::Commit.decorate(@repository, branch.target_commit)
Gitlab::Git::Branch.new(@repository, branch.name, target_commit.id, target_commit)
rescue GRPC::FailedPrecondition => ex
raise Gitlab::Git::Repository::InvalidRef, ex
rescue GRPC::BadStatus => e
detailed_error = GitalyClient.decode_detailed_error(e)
case detailed_error&.error
when :custom_hook
raise Gitlab::Git::PreReceiveError.new(custom_hook_error_message(detailed_error.custom_hook),
fallback_message: e.details)
else
if e.code == GRPC::Core::StatusCodes::FAILED_PRECONDITION
raise Gitlab::Git::Repository::InvalidRef, e
end
raise
end
end
def user_update_branch(branch_name, user, newrev, oldrev)

View File

@ -26841,6 +26841,9 @@ msgstr ""
msgid "Notify|A new GPG key was added to your account:"
msgstr ""
msgid "Notify|All discussions on merge request %{mr_link} were resolved by %{name}"
msgstr ""
msgid "Notify|Assignee changed from %{fromNames} to %{toNames}"
msgstr ""

View File

@ -232,7 +232,7 @@
"jest-raw-loader": "^1.0.1",
"jest-transform-graphql": "^2.1.0",
"jest-util": "^27.5.1",
"markdownlint-cli": "0.31.0",
"markdownlint-cli": "0.32.2",
"miragejs": "^0.1.40",
"mock-apollo-client": "1.2.0",
"nodemon": "^2.0.19",

View File

@ -128,7 +128,7 @@ function run_locally_or_in_docker() {
$cmd $args
elif hash docker 2>/dev/null
then
docker run -t -v ${PWD}:/gitlab -w /gitlab --rm registry.gitlab.com/gitlab-org/gitlab-docs/lint-markdown:alpine-3.15-vale-2.15.5-markdownlint-0.31.1 ${cmd} ${args}
docker run -t -v ${PWD}:/gitlab -w /gitlab --rm registry.gitlab.com/gitlab-org/gitlab-docs/lint-markdown:alpine-3.16-vale-2.20.1-markdownlint-0.32.2 ${cmd} ${args}
else
echo
echo " ✖ ERROR: '${cmd}' not found. Install '${cmd}' or Docker to proceed." >&2

View File

@ -896,12 +896,13 @@ RSpec.describe Projects::MergeRequestsController do
end
subject do
get :exposed_artifacts, params: {
namespace_id: project.namespace.to_param,
project_id: project,
id: merge_request.iid
},
format: :json
get :exposed_artifacts,
params: {
namespace_id: project.namespace.to_param,
project_id: project,
id: merge_request.iid
},
format: :json
end
describe 'permissions on a public project with private CI/CD' do
@ -1031,12 +1032,13 @@ RSpec.describe Projects::MergeRequestsController do
end
subject do
get :coverage_reports, params: {
namespace_id: project.namespace.to_param,
project_id: project,
id: merge_request.iid
},
format: :json
get :coverage_reports,
params: {
namespace_id: project.namespace.to_param,
project_id: project,
id: merge_request.iid
},
format: :json
end
describe 'permissions on a public project with private CI/CD' do
@ -1161,12 +1163,13 @@ RSpec.describe Projects::MergeRequestsController do
end
subject(:get_codequality_mr_diff_reports) do
get :codequality_mr_diff_reports, params: {
namespace_id: project.namespace.to_param,
project_id: project,
id: merge_request.iid
},
format: :json
get :codequality_mr_diff_reports,
params: {
namespace_id: project.namespace.to_param,
project_id: project,
id: merge_request.iid
},
format: :json
end
context 'permissions on a public project with private CI/CD' do
@ -1264,12 +1267,13 @@ RSpec.describe Projects::MergeRequestsController do
end
subject do
get :terraform_reports, params: {
namespace_id: project.namespace.to_param,
project_id: project,
id: merge_request.iid
},
format: :json
get :terraform_reports,
params: {
namespace_id: project.namespace.to_param,
project_id: project,
id: merge_request.iid
},
format: :json
end
describe 'permissions on a public project with private CI/CD' do
@ -1394,12 +1398,13 @@ RSpec.describe Projects::MergeRequestsController do
end
subject do
get :test_reports, params: {
namespace_id: project.namespace.to_param,
project_id: project,
id: merge_request.iid
},
format: :json
get :test_reports,
params: {
namespace_id: project.namespace.to_param,
project_id: project,
id: merge_request.iid
},
format: :json
end
before do
@ -1522,12 +1527,13 @@ RSpec.describe Projects::MergeRequestsController do
end
subject do
get :accessibility_reports, params: {
namespace_id: project.namespace.to_param,
project_id: project,
id: merge_request.iid
},
format: :json
get :accessibility_reports,
params: {
namespace_id: project.namespace.to_param,
project_id: project,
id: merge_request.iid
},
format: :json
end
context 'permissions on a public project with private CI/CD' do
@ -1642,12 +1648,13 @@ RSpec.describe Projects::MergeRequestsController do
end
subject do
get :codequality_reports, params: {
namespace_id: project.namespace.to_param,
project_id: project,
id: merge_request.iid
},
format: :json
get :codequality_reports,
params: {
namespace_id: project.namespace.to_param,
project_id: project,
id: merge_request.iid
},
format: :json
end
context 'permissions on a public project with private CI/CD' do

View File

@ -8,6 +8,7 @@ RSpec.describe GitlabSchema.types['Environment'] do
it 'has the expected fields' do
expected_fields = %w[
name id state metrics_dashboard latest_opened_most_severe_alert path external_url deployments
slug createdAt updatedAt autoStopAt autoDeleteAt tier environmentType
]
expect(described_class).to have_graphql_fields(*expected_fields)

View File

@ -19,7 +19,6 @@ RSpec.describe Projects::PipelineHelper do
it 'returns pipeline tabs data' do
expect(pipeline_tabs_data).to include({
can_generate_codequality_reports: pipeline.can_generate_codequality_reports?.to_json,
failed_jobs_count: pipeline.failed_builds.count,
failed_jobs_summary: prepare_failed_jobs_summary_data(pipeline.failed_builds),
full_path: project.full_path,
@ -33,7 +32,8 @@ RSpec.describe Projects::PipelineHelper do
blob_path: project_blob_path(project, pipeline.sha),
has_test_report: pipeline.has_reports?(Ci::JobArtifact.of_report_type(:test)),
empty_state_image_path: match_asset_path('illustrations/empty-state/empty-test-cases-lg.svg'),
artifacts_expired_image_path: match_asset_path('illustrations/pipeline.svg')
artifacts_expired_image_path: match_asset_path('illustrations/pipeline.svg'),
tests_count: pipeline.test_report_summary.total[:count]
})
end
end

View File

@ -1147,37 +1147,23 @@ RSpec.describe ProjectsHelper do
context 'with the setting enabled' do
before do
stub_application_setting(delete_inactive_projects: true)
stub_application_setting(inactive_projects_min_size_mb: 0)
stub_application_setting(inactive_projects_send_warning_email_after_months: 1)
end
context 'with the feature flag disabled' do
before do
stub_feature_flags(inactive_projects_deletion: false)
end
context 'with an active project' do
it_behaves_like 'does not show the banner'
end
context 'with the feature flag enabled' do
context 'with an inactive project' do
before do
stub_feature_flags(inactive_projects_deletion: true)
stub_application_setting(inactive_projects_min_size_mb: 0)
stub_application_setting(inactive_projects_send_warning_email_after_months: 1)
project.statistics.storage_size = 1.megabyte
project.last_activity_at = 1.year.ago
project.save!
end
context 'with an active project' do
it_behaves_like 'does not show the banner'
end
context 'with an inactive project' do
before do
project.statistics.storage_size = 1.megabyte
project.last_activity_at = 1.year.ago
project.save!
end
it 'shows the banner' do
expect(helper.show_inactive_project_deletion_banner?(project)).to be(true)
end
it 'shows the banner' do
expect(helper.show_inactive_project_deletion_banner?(project)).to be(true)
end
end
end

View File

@ -56,6 +56,85 @@ RSpec.describe Gitlab::GitalyClient::OperationService do
Gitlab::Git::PreReceiveError, "something failed")
end
end
context 'with structured errors' do
context 'with CustomHookError' do
let(:stdout) { nil }
let(:stderr) { nil }
let(:error_message) { "error_message" }
let(:custom_hook_error) do
new_detailed_error(
GRPC::Core::StatusCodes::PERMISSION_DENIED,
error_message,
Gitaly::UserCreateBranchError.new(
custom_hook: Gitaly::CustomHookError.new(
stdout: stdout,
stderr: stderr,
hook_type: Gitaly::CustomHookError::HookType::HOOK_TYPE_PRERECEIVE
)))
end
shared_examples 'failed branch creation' do
it 'raised a PreRecieveError' do
expect_any_instance_of(Gitaly::OperationService::Stub)
.to receive(:user_create_branch)
.and_raise(custom_hook_error)
expect { subject }.to raise_error do |error|
expect(error).to be_a(Gitlab::Git::PreReceiveError)
expect(error.message).to eq(expected_message)
expect(error.raw_message).to eq(expected_raw_message)
end
end
end
context 'when details contain stderr without prefix' do
let(:stderr) { "something" }
let(:stdout) { "GL-HOOK-ERR: stdout is overridden by stderr" }
let(:expected_message) { error_message }
let(:expected_raw_message) { stderr }
it_behaves_like 'failed branch creation'
end
context 'when details contain stderr with prefix' do
let(:stderr) { "GL-HOOK-ERR: something" }
let(:stdout) { "GL-HOOK-ERR: stdout is overridden by stderr" }
let(:expected_message) { "something" }
let(:expected_raw_message) { stderr }
it_behaves_like 'failed branch creation'
end
context 'when details contain stdout without prefix' do
let(:stderr) { " \n" }
let(:stdout) { "something" }
let(:expected_message) { error_message }
let(:expected_raw_message) { stdout }
it_behaves_like 'failed branch creation'
end
context 'when details contain stdout with prefix' do
let(:stderr) { " \n" }
let(:stdout) { "GL-HOOK-ERR: something" }
let(:expected_message) { "something" }
let(:expected_raw_message) { stdout }
it_behaves_like 'failed branch creation'
end
context 'when details contain no stderr or stdout' do
let(:stderr) { " \n" }
let(:stdout) { "\n \n" }
let(:expected_message) { error_message }
let(:expected_raw_message) { "\n \n" }
it_behaves_like 'failed branch creation'
end
end
end
end
describe '#user_update_branch' do

View File

@ -0,0 +1,55 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Preloaders::ProjectPolicyPreloader do
let_it_be(:user) { create(:user) }
let_it_be(:root_parent) { create(:group, :private, name: 'root-1', path: 'root-1') }
let_it_be(:guest_project) { create(:project, name: 'public guest', path: 'public-guest') }
let_it_be(:private_maintainer_project) do
create(:project, :private, name: 'b private maintainer', path: 'b-private-maintainer', namespace: root_parent)
end
let_it_be(:private_developer_project) do
create(:project, :private, name: 'c public developer', path: 'c-public-developer')
end
let_it_be(:public_maintainer_project) do
create(:project, :private, name: 'a public maintainer', path: 'a-public-maintainer')
end
let(:base_projects) do
Project.where(id: [guest_project, private_maintainer_project, private_developer_project, public_maintainer_project])
end
before_all do
guest_project.add_guest(user)
private_maintainer_project.add_maintainer(user)
private_developer_project.add_developer(user)
public_maintainer_project.add_maintainer(user)
end
it 'avoids N+1 queries when authorizing a list of projects', :request_store do
preload_projects_for_policy(user)
control = ActiveRecord::QueryRecorder.new { authorize_all_projects(user) }
new_project1 = create(:project, :private).tap { |project| project.add_maintainer(user) }
new_project2 = create(:project, :private, namespace: root_parent)
another_root = create(:group, :private, name: 'root-3', path: 'root-3')
new_project3 = create(:project, :private, namespace: another_root).tap { |project| project.add_maintainer(user) }
pristine_projects = Project.where(id: base_projects + [new_project1, new_project2, new_project3])
preload_projects_for_policy(user, pristine_projects)
expect { authorize_all_projects(user, pristine_projects) }.not_to exceed_query_limit(control)
end
def authorize_all_projects(current_user, project_list = base_projects)
project_list.each { |project| current_user.can?(:read_project, project) }
end
def preload_projects_for_policy(current_user, project_list = base_projects)
described_class.new(project_list, current_user).execute
end
end

View File

@ -0,0 +1,99 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Preloaders::ProjectRootAncestorPreloader do
let_it_be(:root_parent1) { create(:group, :private, name: 'root-1', path: 'root-1') }
let_it_be(:root_parent2) { create(:group, :private, name: 'root-2', path: 'root-2') }
let_it_be(:guest_project) { create(:project, name: 'public guest', path: 'public-guest') }
let_it_be(:private_maintainer_project) do
create(:project, :private, name: 'b private maintainer', path: 'b-private-maintainer', namespace: root_parent1)
end
let_it_be(:private_developer_project) do
create(:project, :private, name: 'c public developer', path: 'c-public-developer')
end
let_it_be(:public_maintainer_project) do
create(:project, :private, name: 'a public maintainer', path: 'a-public-maintainer', namespace: root_parent2)
end
let(:root_query_regex) { /\ASELECT.+FROM "namespaces" WHERE "namespaces"."id" = \d+/ }
let(:additional_preloads) { [] }
let(:projects) { [guest_project, private_maintainer_project, private_developer_project, public_maintainer_project] }
let(:pristine_projects) { Project.where(id: projects) }
shared_examples 'executes N matching DB queries' do |expected_query_count, query_method = nil|
it 'executes the specified root_ancestor queries' do
expect do
pristine_projects.each do |project|
root_ancestor = project.root_ancestor
root_ancestor.public_send(query_method) if query_method.present?
end
end.to make_queries_matching(root_query_regex, expected_query_count)
end
it 'strong_memoizes the correct root_ancestor' do
pristine_projects.each do |project|
expected_parent_id = project.root_ancestor&.id
expect(project.parent_id).to eq(expected_parent_id)
end
end
end
context 'when use_traversal_ids FF is enabled' do
context 'when the preloader is used' do
before do
preload_ancestors
end
context 'when no additional preloads are provided' do
it_behaves_like 'executes N matching DB queries', 0
end
context 'when additional preloads are provided' do
let(:additional_preloads) { [:route] }
let(:root_query_regex) { /\ASELECT.+FROM "routes" WHERE "routes"."source_id" = \d+/ }
it_behaves_like 'executes N matching DB queries', 0, :full_path
end
end
context 'when the preloader is not used' do
it_behaves_like 'executes N matching DB queries', 4
end
end
context 'when use_traversal_ids FF is disabled' do
before do
stub_feature_flags(use_traversal_ids: false)
end
context 'when the preloader is used' do
before do
preload_ancestors
end
context 'when no additional preloads are provided' do
it_behaves_like 'executes N matching DB queries', 4
end
context 'when additional preloads are provided' do
let(:additional_preloads) { [:route] }
let(:root_query_regex) { /\ASELECT.+FROM "routes" WHERE "routes"."source_id" = \d+/ }
it_behaves_like 'executes N matching DB queries', 4, :full_path
end
end
context 'when the preloader is not used' do
it_behaves_like 'executes N matching DB queries', 4
end
end
def preload_ancestors
described_class.new(pristine_projects, :namespace, additional_preloads).execute
end
end

View File

@ -0,0 +1,48 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Project Environments query' do
include GraphqlHelpers
let_it_be(:project) { create(:project, :private, :repository) }
let_it_be(:environment) { create(:environment, project: project) }
let_it_be(:developer) { create(:user).tap { |u| project.add_developer(u) } }
subject { post_graphql(query, current_user: user) }
let(:user) { developer }
let(:query) do
%(
query {
project(fullPath: "#{project.full_path}") {
environment(name: "#{environment.name}") {
slug
createdAt
updatedAt
autoStopAt
autoDeleteAt
tier
environmentType
}
}
}
)
end
it 'returns the specified fields of the environment', :aggregate_failures do
environment.update!(auto_stop_at: 1.day.ago, auto_delete_at: 2.days.ago, environment_type: 'review')
subject
environment_data = graphql_data.dig('project', 'environment')
expect(environment_data['slug']).to eq(environment.slug)
expect(environment_data['createdAt']).to eq(environment.created_at.iso8601)
expect(environment_data['updatedAt']).to eq(environment.updated_at.iso8601)
expect(environment_data['autoStopAt']).to eq(environment.auto_stop_at.iso8601)
expect(environment_data['autoDeleteAt']).to eq(environment.auto_delete_at.iso8601)
expect(environment_data['tier']).to eq(environment.tier.upcase)
expect(environment_data['environmentType']).to eq(environment.environment_type)
end
end

View File

@ -480,7 +480,7 @@ RSpec.describe 'project routing' do
newline_file = "new\n\nline.txt"
url_encoded_newline_file = ERB::Util.url_encode(newline_file)
assert_routing({ path: "/gitlab/gitlabhq/-/blame/master/#{url_encoded_newline_file}",
method: :get },
method: :get },
{ controller: 'projects/blame', action: 'show',
namespace_id: 'gitlab', project_id: 'gitlabhq',
id: "master/#{newline_file}" })
@ -499,7 +499,7 @@ RSpec.describe 'project routing' do
newline_file = "new\n\nline.txt"
url_encoded_newline_file = ERB::Util.url_encode(newline_file)
assert_routing({ path: "/gitlab/gitlabhq/-/blob/blob/master/blob/#{url_encoded_newline_file}",
method: :get },
method: :get },
{ controller: 'projects/blob', action: 'show',
namespace_id: 'gitlab', project_id: 'gitlabhq',
id: "blob/master/blob/#{newline_file}" })
@ -520,7 +520,7 @@ RSpec.describe 'project routing' do
newline_file = "new\n\nline.txt"
url_encoded_newline_file = ERB::Util.url_encode(newline_file)
assert_routing({ path: "/gitlab/gitlabhq/-/tree/master/#{url_encoded_newline_file}",
method: :get },
method: :get },
{ controller: 'projects/tree', action: 'show',
namespace_id: 'gitlab', project_id: 'gitlabhq',
id: "master/#{newline_file}" })
@ -540,7 +540,7 @@ RSpec.describe 'project routing' do
newline_file = "new\n\nline.txt"
url_encoded_newline_file = ERB::Util.url_encode(newline_file)
assert_routing({ path: "/gitlab/gitlabhq/-/find_file/#{url_encoded_newline_file}",
method: :get },
method: :get },
{ controller: 'projects/find_file', action: 'show',
namespace_id: 'gitlab', project_id: 'gitlabhq',
id: "#{newline_file}" })
@ -551,7 +551,7 @@ RSpec.describe 'project routing' do
newline_file = "new\n\nline.txt"
url_encoded_newline_file = ERB::Util.url_encode(newline_file)
assert_routing({ path: "/gitlab/gitlabhq/-/files/#{url_encoded_newline_file}",
method: :get },
method: :get },
{ controller: 'projects/find_file', action: 'list',
namespace_id: 'gitlab', project_id: 'gitlabhq',
id: "#{newline_file}" })
@ -570,7 +570,7 @@ RSpec.describe 'project routing' do
newline_file = "new\n\nline.txt"
url_encoded_newline_file = ERB::Util.url_encode(newline_file)
assert_routing({ path: "/gitlab/gitlabhq/-/edit/master/docs/#{url_encoded_newline_file}",
method: :get },
method: :get },
{ controller: 'projects/blob', action: 'edit',
namespace_id: 'gitlab', project_id: 'gitlabhq',
id: "master/docs/#{newline_file}" })
@ -584,7 +584,7 @@ RSpec.describe 'project routing' do
newline_file = "new\n\nline.txt"
url_encoded_newline_file = ERB::Util.url_encode(newline_file)
assert_routing({ path: "/gitlab/gitlabhq/-/edit/master/docs/#{url_encoded_newline_file}",
method: :get },
method: :get },
{ controller: 'projects/blob', action: 'edit',
namespace_id: 'gitlab', project_id: 'gitlabhq',
id: "master/docs/#{newline_file}" })
@ -600,7 +600,7 @@ RSpec.describe 'project routing' do
newline_file = "new\n\nline.txt"
url_encoded_newline_file = ERB::Util.url_encode(newline_file)
assert_routing({ path: "/gitlab/gitlabhq/-/raw/master/#{url_encoded_newline_file}",
method: :get },
method: :get },
{ controller: 'projects/raw', action: 'show',
namespace_id: 'gitlab', project_id: 'gitlabhq',
id: "master/#{newline_file}" })
@ -889,8 +889,8 @@ RSpec.describe 'project routing' do
describe Projects::Snippets::BlobsController, "routing" do
it "to #raw" do
expect(get('/gitlab/gitlabhq/-/snippets/1/raw/master/lib/version.rb'))
.to route_to('projects/snippets/blobs#raw', namespace_id: 'gitlab',
project_id: 'gitlabhq', snippet_id: '1', ref: 'master', path: 'lib/version.rb')
.to route_to('projects/snippets/blobs#raw',
namespace_id: 'gitlab', project_id: 'gitlabhq', snippet_id: '1', ref: 'master', path: 'lib/version.rb')
end
end

View File

@ -10,7 +10,7 @@ RSpec.describe Ci::Lint::JobEntity, :aggregate_failures do
stage: 'test',
before_script: ['bundle install', 'bundle exec rake db:create'],
script: ["rake spec"],
after_script: ["rake spec"],
after_script: ["rake spec"],
tag_list: %w[ruby postgres],
environment: { name: 'hello', url: 'world' },
when: 'on_success',

View File

@ -14,8 +14,7 @@ RSpec.describe ContainerRepositoryEntity do
before do
stub_container_registry_config(enabled: true)
stub_container_registry_tags(repository: :any,
tags: %w[stable latest])
stub_container_registry_tags(repository: :any, tags: %w[stable latest])
allow(request).to receive(:project).and_return(project)
allow(request).to receive(:current_user).and_return(user)
end

View File

@ -61,8 +61,7 @@ RSpec.describe DeploymentEntity do
context 'when the pipeline has another manual action' do
let!(:other_build) do
create(:ci_build, :manual, name: 'another deploy',
pipeline: pipeline, environment: build.environment)
create(:ci_build, :manual, name: 'another deploy', pipeline: pipeline, environment: build.environment)
end
let!(:other_deployment) { create(:deployment, deployable: build) }

View File

@ -57,9 +57,9 @@ RSpec.describe MergeRequestMetricsHelper do
expect(MergeRequest::Metrics).to receive(:new)
.with(latest_closed_at: closed_event&.updated_at,
latest_closed_by: closed_event&.author,
merged_at: merge_event&.updated_at,
merged_by: merge_event&.author)
latest_closed_by: closed_event&.author,
merged_at: merge_event&.updated_at,
merged_by: merge_event&.author)
.and_call_original
subject

View File

@ -85,86 +85,58 @@ RSpec.describe Projects::InactiveProjectsDeletionCronWorker do
end
end
context 'when delete inactive projects feature is enabled' do
context 'when delete inactive projects feature is enabled', :clean_gitlab_redis_shared_state, :sidekiq_inline do
before do
stub_application_setting(delete_inactive_projects: true)
end
context 'when feature flag is disabled' do
before do
stub_feature_flags(inactive_projects_deletion: false)
it 'invokes Projects::InactiveProjectsDeletionNotificationWorker for inactive projects' do
Gitlab::Redis::SharedState.with do |redis|
expect(redis).to receive(:hset).with('inactive_projects_deletion_warning_email_notified',
"project:#{inactive_large_project.id}", Date.current)
end
expect(::Projects::InactiveProjectsDeletionNotificationWorker).to receive(:perform_async).with(
inactive_large_project.id, deletion_date).and_call_original
expect(::Projects::DestroyService).not_to receive(:new)
it 'does not invoke Projects::InactiveProjectsDeletionNotificationWorker' do
expect(::Projects::InactiveProjectsDeletionNotificationWorker).not_to receive(:perform_async)
expect(::Projects::DestroyService).not_to receive(:new)
worker.perform
end
it 'does not delete the inactive projects' do
worker.perform
expect(inactive_large_project.reload.pending_delete).to eq(false)
end
it_behaves_like 'worker is running for more than 4 minutes'
it_behaves_like 'worker finishes processing in less than 4 minutes'
worker.perform
end
context 'when feature flag is enabled', :clean_gitlab_redis_shared_state, :sidekiq_inline do
before do
stub_feature_flags(inactive_projects_deletion: true)
it 'does not invoke InactiveProjectsDeletionNotificationWorker for already notified inactive projects' do
Gitlab::Redis::SharedState.with do |redis|
redis.hset('inactive_projects_deletion_warning_email_notified', "project:#{inactive_large_project.id}",
Date.current.to_s)
end
it 'invokes Projects::InactiveProjectsDeletionNotificationWorker for inactive projects' do
Gitlab::Redis::SharedState.with do |redis|
expect(redis).to receive(:hset).with('inactive_projects_deletion_warning_email_notified',
"project:#{inactive_large_project.id}", Date.current)
end
expect(::Projects::InactiveProjectsDeletionNotificationWorker).to receive(:perform_async).with(
inactive_large_project.id, deletion_date).and_call_original
expect(::Projects::DestroyService).not_to receive(:new)
expect(::Projects::InactiveProjectsDeletionNotificationWorker).not_to receive(:perform_async)
expect(::Projects::DestroyService).not_to receive(:new)
worker.perform
end
it 'does not invoke InactiveProjectsDeletionNotificationWorker for already notified inactive projects' do
Gitlab::Redis::SharedState.with do |redis|
redis.hset('inactive_projects_deletion_warning_email_notified', "project:#{inactive_large_project.id}",
Date.current.to_s)
end
expect(::Projects::InactiveProjectsDeletionNotificationWorker).not_to receive(:perform_async)
expect(::Projects::DestroyService).not_to receive(:new)
worker.perform
end
it 'invokes Projects::DestroyService for projects that are inactive even after being notified' do
Gitlab::Redis::SharedState.with do |redis|
redis.hset('inactive_projects_deletion_warning_email_notified', "project:#{inactive_large_project.id}",
15.months.ago.to_date.to_s)
end
expect(::Projects::InactiveProjectsDeletionNotificationWorker).not_to receive(:perform_async)
expect(::Projects::DestroyService).to receive(:new).with(inactive_large_project, admin_user, {})
.at_least(:once).and_call_original
worker.perform
expect(inactive_large_project.reload.pending_delete).to eq(true)
Gitlab::Redis::SharedState.with do |redis|
expect(redis.hget('inactive_projects_deletion_warning_email_notified',
"project:#{inactive_large_project.id}")).to be_nil
end
end
it_behaves_like 'worker is running for more than 4 minutes'
it_behaves_like 'worker finishes processing in less than 4 minutes'
worker.perform
end
it 'invokes Projects::DestroyService for projects that are inactive even after being notified' do
Gitlab::Redis::SharedState.with do |redis|
redis.hset('inactive_projects_deletion_warning_email_notified', "project:#{inactive_large_project.id}",
15.months.ago.to_date.to_s)
end
expect(::Projects::InactiveProjectsDeletionNotificationWorker).not_to receive(:perform_async)
expect(::Projects::DestroyService).to receive(:new).with(inactive_large_project, admin_user, {})
.at_least(:once).and_call_original
worker.perform
expect(inactive_large_project.reload.pending_delete).to eq(true)
Gitlab::Redis::SharedState.with do |redis|
expect(redis.hget('inactive_projects_deletion_warning_email_notified',
"project:#{inactive_large_project.id}")).to be_nil
end
end
it_behaves_like 'worker is running for more than 4 minutes'
it_behaves_like 'worker finishes processing in less than 4 minutes'
it_behaves_like 'an idempotent worker'
end
end

127
yarn.lock
View File

@ -3021,6 +3021,13 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0"
concat-map "0.0.1"
brace-expansion@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
dependencies:
balanced-match "^1.0.0"
braces@^2.3.1:
version "2.3.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729"
@ -3565,16 +3572,11 @@ commander@^6.0.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c"
integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==
commander@^9.4.0:
commander@^9.4.0, commander@~9.4.0:
version "9.4.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.0.tgz#bc4a40918fefe52e22450c111ecd6b7acce6f11c"
integrity sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==
commander@~9.0.0:
version "9.0.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-9.0.0.tgz#86d58f24ee98126568936bd1d3574e0308a99a40"
integrity sha512-JJfP2saEKbQqvW+FI93OYUB4ByV5cizMpFMiiJI8xDbBvQvSkIk0VvQdn1CZ8mqAO8Loq2h0gYTYtDFUZUeERw==
commondir@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
@ -4974,7 +4976,7 @@ enhanced-resolve@^4.5.0:
memory-fs "^0.5.0"
tapable "^1.0.0"
entities@^2.0.0, entities@~2.1.0:
entities@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5"
integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==
@ -5967,7 +5969,7 @@ glob-parent@^6.0.1:
dependencies:
is-glob "^4.0.3"
"glob@5 - 7", glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@~7.2.0:
"glob@5 - 7", glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
version "7.2.0"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
@ -5979,6 +5981,17 @@ glob-parent@^6.0.1:
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@~8.0.3:
version "8.0.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.3.tgz#415c6eb2deed9e502c68fa44a272e6da6eeca42e"
integrity sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^5.0.1"
once "^1.3.0"
global-modules@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780"
@ -6596,10 +6609,10 @@ ini@^1.3.4, ini@^1.3.5:
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
ini@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5"
integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==
ini@~3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/ini/-/ini-3.0.1.tgz#c76ec81007875bc44d544ff7a11a55d12294102d"
integrity sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==
inline-style-parser@0.1.1:
version "0.1.1"
@ -7569,10 +7582,10 @@ json5@^2.1.2, json5@^2.2.1:
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c"
integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
jsonc-parser@~3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22"
integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==
jsonc-parser@~3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.1.0.tgz#73b8f0e5c940b83d03476bc2e51a20ef0932615d"
integrity sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg==
jsonfile@^4.0.0:
version "4.0.0"
@ -7682,13 +7695,6 @@ lines-and-columns@^1.1.6:
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=
linkify-it@^3.0.1:
version "3.0.2"
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.2.tgz#f55eeb8bc1d3ae754049e124ab3bb56d97797fb8"
integrity sha512-gDBO4aHNZS6coiZCKVhSNh43F9ioIL4JwRjLZPkoLIY4yZFwg264Y5lu2x6rb1Js42Gh6Yqm2f6L2AJcnkzinQ==
dependencies:
uc.micro "^1.0.1"
linkify-it@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-4.0.1.tgz#01f1d5e508190d06669982ba31a7d9f56a5751ec"
@ -7991,18 +7997,7 @@ map-visit@^1.0.0:
dependencies:
object-visit "^1.0.0"
markdown-it@12.3.2:
version "12.3.2"
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.3.2.tgz#bf92ac92283fe983fe4de8ff8abfb5ad72cd0c90"
integrity sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==
dependencies:
argparse "^2.0.1"
entities "~2.1.0"
linkify-it "^3.0.1"
mdurl "^1.0.1"
uc.micro "^1.0.5"
markdown-it@^13.0.1:
markdown-it@13.0.1, markdown-it@^13.0.1:
version "13.0.1"
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-13.0.1.tgz#c6ecc431cacf1a5da531423fc6a42807814af430"
integrity sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==
@ -8018,33 +8013,33 @@ markdown-table@^3.0.0:
resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-3.0.2.tgz#9b59eb2c1b22fe71954a65ff512887065a7bb57c"
integrity sha512-y8j3a5/DkJCmS5x4dMCQL+OR0+2EAq3DOtio1COSHsmW2BGXnNCK3v12hJt1LrUz5iZH5g0LmuYOjDdI+czghA==
markdownlint-cli@0.31.0:
version "0.31.0"
resolved "https://registry.yarnpkg.com/markdownlint-cli/-/markdownlint-cli-0.31.0.tgz#a44264a71066475228292b7af19d3d18b827676d"
integrity sha512-UCNA10I2evrEqGWUGM4I6ae6LubLeySkKegP1GQaZSES516BYBgOn8Ai8MXU+5rSIeCvMyKi91alqHyRDuUnYA==
markdownlint-cli@0.32.2:
version "0.32.2"
resolved "https://registry.yarnpkg.com/markdownlint-cli/-/markdownlint-cli-0.32.2.tgz#b7b5c5808039aef4022aef603efaa607caf8e0de"
integrity sha512-xmJT1rGueUgT4yGNwk6D0oqQr90UJ7nMyakXtqjgswAkEhYYqjHew9RY8wDbOmh2R270IWjuKSeZzHDEGPAUkQ==
dependencies:
commander "~9.0.0"
commander "~9.4.0"
get-stdin "~9.0.0"
glob "~7.2.0"
glob "~8.0.3"
ignore "~5.2.0"
js-yaml "^4.1.0"
jsonc-parser "~3.0.0"
markdownlint "~0.25.1"
markdownlint-rule-helpers "~0.16.0"
minimatch "~3.0.4"
run-con "~1.2.10"
jsonc-parser "~3.1.0"
markdownlint "~0.26.2"
markdownlint-rule-helpers "~0.17.2"
minimatch "~5.1.0"
run-con "~1.2.11"
markdownlint-rule-helpers@~0.16.0:
version "0.16.0"
resolved "https://registry.yarnpkg.com/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.16.0.tgz#c327f72782bd2b9475127a240508231f0413a25e"
integrity sha512-oEacRUVeTJ5D5hW1UYd2qExYI0oELdYK72k1TKGvIeYJIbqQWAz476NAc7LNixSySUhcNl++d02DvX0ccDk9/w==
markdownlint-rule-helpers@~0.17.2:
version "0.17.2"
resolved "https://registry.yarnpkg.com/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.17.2.tgz#64d6e8c66e497e631b0e40cf1cef7ca622a0b654"
integrity sha512-XaeoW2NYSlWxMCZM2B3H7YTG6nlaLfkEZWMBhr4hSPlq9MuY2sy83+Xr89jXOqZMZYjvi5nBCGoFh7hHoPKZmA==
markdownlint@~0.25.1:
version "0.25.1"
resolved "https://registry.yarnpkg.com/markdownlint/-/markdownlint-0.25.1.tgz#df04536607ebeeda5ccd5e4f38138823ed623788"
integrity sha512-AG7UkLzNa1fxiOv5B+owPsPhtM4D6DoODhsJgiaNg1xowXovrYgOnLqAgOOFQpWOlHFVQUzjMY5ypNNTeov92g==
markdownlint@~0.26.2:
version "0.26.2"
resolved "https://registry.yarnpkg.com/markdownlint/-/markdownlint-0.26.2.tgz#11d3d03e7f0dd3c2e239753ee8fd064a861d9237"
integrity sha512-2Am42YX2Ex5SQhRq35HxYWDfz1NLEOZWWN25nqd2h3AHRKsGRE+Qg1gt1++exW792eXTrR4jCNHfShfWk9Nz8w==
dependencies:
markdown-it "12.3.2"
markdown-it "13.0.1"
marked@^4.0.18:
version "4.0.18"
@ -8693,12 +8688,12 @@ minimatch@^3.0.4, minimatch@^3.1.2:
dependencies:
brace-expansion "^1.1.7"
minimatch@~3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
minimatch@^5.0.1, minimatch@~5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7"
integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==
dependencies:
brace-expansion "^1.1.7"
brace-expansion "^2.0.1"
minimist-options@4.1.0:
version "4.1.0"
@ -10335,14 +10330,14 @@ route-recognizer@^0.3.3:
resolved "https://registry.yarnpkg.com/route-recognizer/-/route-recognizer-0.3.4.tgz#39ab1ffbce1c59e6d2bdca416f0932611e4f3ca3"
integrity sha512-2+MhsfPhvauN1O8KaXpXAOfR/fwe8dnUXVM+xw7yt40lJRfPVQxV6yryZm0cgRvAj5fMF/mdRZbL2ptwbs5i2g==
run-con@~1.2.10:
version "1.2.10"
resolved "https://registry.yarnpkg.com/run-con/-/run-con-1.2.10.tgz#90de9d43d20274d00478f4c000495bd72f417d22"
integrity sha512-n7PZpYmMM26ZO21dd8y3Yw1TRtGABjRtgPSgFS/nhzfvbJMXFtJhJVyEgayMiP+w/23craJjsnfDvx4W4ue/HQ==
run-con@~1.2.11:
version "1.2.11"
resolved "https://registry.yarnpkg.com/run-con/-/run-con-1.2.11.tgz#0014ed430bad034a60568dfe7de2235f32e3f3c4"
integrity sha512-NEMGsUT+cglWkzEr4IFK21P4Jca45HqiAbIIZIBdX5+UZTB24Mb/21iNGgz9xZa8tL6vbW7CXmq7MFN42+VjNQ==
dependencies:
deep-extend "^0.6.0"
ini "~2.0.0"
minimist "^1.2.5"
ini "~3.0.0"
minimist "^1.2.6"
strip-json-comments "~3.1.1"
run-parallel@^1.1.9: