Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-12-17 18:11:12 +00:00
parent e303f963d0
commit d70200a2d3
44 changed files with 469 additions and 406 deletions

View File

@ -1,8 +1,9 @@
---
GraphQL/OrderedArguments:
Exclude:
- app/graphql/mutations/jira_import/start.rb
- app/graphql/mutations/merge_requests/accept.rb
- app/graphql/resolvers/base_issues_resolver.rb
- app/graphql/resolvers/design_management/designs_resolver.rb
- app/graphql/resolvers/design_management/version/design_at_version_resolver.rb
- app/graphql/resolvers/design_management/version/designs_at_version_resolver.rb
- app/graphql/resolvers/design_management/version_in_collection_resolver.rb
- app/graphql/resolvers/group_milestones_resolver.rb

View File

@ -57,14 +57,17 @@ export default {
};
},
computed: {
trimmedUsername() {
return this.username.trim();
},
modalTitle() {
return sprintf(this.title, { username: this.username }, false);
return sprintf(this.title, { username: this.trimmedUsername }, false);
},
secondaryButtonLabel() {
return s__('AdminUsers|Block user');
},
canSubmit() {
return this.enteredUsername === this.username;
return this.enteredUsername === this.trimmedUsername;
},
obstacles() {
try {
@ -104,7 +107,7 @@ export default {
<p>
<gl-sprintf :message="content">
<template #username>
<strong>{{ username }}</strong>
<strong>{{ trimmedUsername }}</strong>
</template>
<template #strong="props">
<strong>{{ props.content }}</strong>
@ -115,13 +118,13 @@ export default {
<user-deletion-obstacles-list
v-if="obstacles.length"
:obstacles="obstacles"
:user-name="username"
:user-name="trimmedUsername"
/>
<p>
<gl-sprintf :message="s__('AdminUsers|To confirm, type %{username}')">
<template #username>
<code class="gl-white-space-pre-wrap">{{ username }}</code>
<code class="gl-white-space-pre-wrap">{{ trimmedUsername }}</code>
</template>
</gl-sprintf>
</p>

View File

@ -14,15 +14,15 @@ module Mutations
null: true,
description: 'Jira import data after mutation.'
argument :project_path, GraphQL::Types::ID,
required: true,
description: 'Project to import the Jira project into.'
argument :jira_project_key, GraphQL::Types::String,
required: true,
description: 'Project key of the importer Jira project.'
argument :jira_project_name, GraphQL::Types::String,
required: false,
description: 'Project name of the importer Jira project.'
argument :project_path, GraphQL::Types::ID,
required: true,
description: 'Project to import the Jira project into.'
argument :users_mapping,
[Types::JiraUsersMappingInputType],
required: false,

View File

@ -26,12 +26,12 @@ module Mutations
argument :commit_message, ::GraphQL::Types::String,
required: false,
description: 'Custom merge commit message.'
argument :squash_commit_message, ::GraphQL::Types::String,
required: false,
description: 'Custom squash commit message (if squash is true).'
argument :sha, ::GraphQL::Types::String,
required: true,
description: 'HEAD SHA at the time when this merge was requested.'
argument :squash_commit_message, ::GraphQL::Types::String,
required: false,
description: 'Custom squash commit message (if squash is true).'
argument :should_remove_source_branch, ::GraphQL::Types::Boolean,
required: false,

View File

@ -27,6 +27,7 @@ class User < ApplicationRecord
include HasUserType
include Gitlab::Auth::Otp::Fortinet
include RestrictedSignup
include StripAttribute
DEFAULT_NOTIFICATION_LEVEL = :participating
@ -466,6 +467,8 @@ class User < ApplicationRecord
scope :by_provider_and_extern_uid, ->(provider, extern_uid) { joins(:identities).merge(Identity.with_extern_uid(provider, extern_uid)) }
scope :get_ids_by_username, -> (username) { where(username: username).pluck(:id) }
strip_attributes! :name
def preferred_language
read_attribute('preferred_language') ||
I18n.default_locale.to_s.presence_in(Gitlab::I18n.available_locales) ||

View File

@ -24,7 +24,7 @@ module Ci
# rubocop:disable CodeReuse/ActiveRecord
def builds_for_group_runner
if strategy.use_denormalized_namespace_traversal_ids?
if strategy.use_denormalized_data_strategy?
strategy.builds_for_group_runner
else
# Workaround for weird Rails bug, that makes `runner.groups.to_sql` to return `runner_id = NULL`

View File

@ -57,15 +57,7 @@ module Ci
relation.pluck(:id)
end
def use_denormalized_shared_runners_data?
false
end
def use_denormalized_minutes_data?
false
end
def use_denormalized_namespace_traversal_ids?
def use_denormalized_data_strategy?
false
end

View File

@ -23,7 +23,7 @@ module Ci
end
def builds_matching_tag_ids(relation, ids)
if ::Feature.enabled?(:ci_queueing_denormalize_tags_information, runner, default_enabled: :yaml)
if use_denormalized_data_strategy?
relation.for_tags(runner.tags_ids)
else
relation.merge(CommitStatus.matches_tag_ids(ids, table: 'ci_pending_builds', column: 'build_id'))
@ -31,7 +31,7 @@ module Ci
end
def builds_with_any_tags(relation)
if ::Feature.enabled?(:ci_queueing_denormalize_tags_information, runner, default_enabled: :yaml)
if use_denormalized_data_strategy?
relation.where('cardinality(tag_ids) > 0')
else
relation.merge(CommitStatus.with_any_tags(table: 'ci_pending_builds', column: 'build_id'))
@ -50,22 +50,14 @@ module Ci
relation.pluck(:build_id)
end
def use_denormalized_shared_runners_data?
::Feature.enabled?(:ci_queueing_denormalize_shared_runners_information, runner, type: :development, default_enabled: :yaml)
end
def use_denormalized_minutes_data?
::Feature.enabled?(:ci_queueing_denormalize_ci_minutes_information, runner, type: :development, default_enabled: :yaml)
end
def use_denormalized_namespace_traversal_ids?
::Feature.enabled?(:ci_queueing_denormalize_namespace_traversal_ids, runner, type: :development, default_enabled: :yaml)
def use_denormalized_data_strategy?
::Feature.enabled?(:ci_queuing_use_denormalized_data_strategy, default_enabled: :yaml)
end
private
def builds_available_for_shared_runners
if use_denormalized_shared_runners_data?
if use_denormalized_data_strategy?
new_builds.with_instance_runners
else
new_builds

View File

@ -130,10 +130,7 @@ module Projects
destroy_events!
destroy_web_hooks!
destroy_project_bots!
if ::Feature.enabled?(:ci_optimize_project_records_destruction, project, default_enabled: :yaml)
destroy_ci_records!
end
destroy_ci_records!
# Rails attempts to load all related records into memory before
# destroying: https://github.com/rails/rails/issues/22510

View File

@ -178,7 +178,7 @@
.card-header
%strong= @group.name
= _('group members')
%span.badge.badge-pill= @group_members.size
= gl_badge_tag @group_members.size
= render 'shared/members/manage_access_button', path: group_group_members_path(@group)
%ul.content-list.members-list
= render partial: 'shared/members/member',
@ -195,7 +195,7 @@
.card-header
%strong= @project.name
= _('project members')
%span.badge.badge-pill= @project.users.size
= gl_badge_tag @project.users.size
= render 'shared/members/manage_access_button', path: project_project_members_path(@project)
%ul.content-list.project_members.members-list
= render partial: 'shared/members/member',

View File

@ -1,8 +0,0 @@
---
name: ci_queueing_denormalize_ci_minutes_information
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66962
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338290
milestone: '14.2'
type: development
group: 'group::pipeline execution'
default_enabled: false

View File

@ -1,8 +0,0 @@
---
name: ci_queueing_denormalize_namespace_traversal_ids
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70162
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340930
milestone: '14.3'
type: development
group: group::pipeline execution
default_enabled: false

View File

@ -1,8 +0,0 @@
---
name: ci_queueing_denormalize_shared_runners_information
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66082
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338289
milestone: '14.2'
type: development
group: group::pipeline execution
default_enabled: false

View File

@ -1,8 +0,0 @@
---
name: ci_queueing_denormalize_tags_information
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65648
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338366
milestone: '14.1'
type: development
group: group::pipeline execution
default_enabled: false

View File

@ -1,8 +1,8 @@
---
name: ci_optimize_project_records_destruction
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71342
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/341936
milestone: '14.4'
name: ci_queuing_use_denormalized_data_strategy
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76543
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/332951
milestone: '14.6'
type: development
group: group::pipeline execution
default_enabled: false
default_enabled: true

View File

@ -1,8 +0,0 @@
---
name: linear_groups_template_finder_extended_group_search_ancestors_scopes
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74599
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/345786
milestone: '14.6'
type: development
group: group::access
default_enabled: false

View File

@ -0,0 +1,14 @@
---
# Suggestion: gitlab.Dropdown
#
# Catches many ways the phrase 'dropdown list' can be fumbled.
#
# For a list of all options, see https://errata-ai.github.io/vale/styles/
extends: existence
message: 'Use "dropdown list".'
link: https://docs.gitlab.com/ee/development/documentation/styleguide/word_list.html#dropdown-list
level: suggestion
ignorecase: true
tokens:
- drop-down( [\w]*)?
- dropdown(?! list)

View File

@ -2,17 +2,19 @@
stage: Enablement
group: Geo
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
type: howto
---
# Geo **(PREMIUM SELF)**
Geo is the solution for widely distributed development teams and for providing a warm-standby as part of a disaster recovery strategy.
Geo is the solution for widely distributed development teams and for providing
a warm-standby as part of a disaster recovery strategy.
## Overview
WARNING:
Geo undergoes significant changes from release to release. Upgrades **are** supported and [documented](#updating-geo), but you should ensure that you're using the right version of the documentation for your installation.
Geo undergoes significant changes from release to release. Upgrades are
supported and [documented](#updating-geo), but you should ensure that you're
using the right version of the documentation for your installation.
Fetching large repositories can take a long time for teams located far from a single GitLab instance.
@ -69,8 +71,9 @@ Keep in mind that:
- **Secondary** sites talk to the **primary** site to:
- Get user data for logins (API).
- Replicate repositories, LFS Objects, and Attachments (HTTPS + JWT).
- In GitLab Premium 10.0 and later, the **primary** site no longer talks to **secondary** sites to notify for changes (API).
- Pushing directly to a **secondary** site (for both HTTP and SSH, including Git LFS) was [introduced](https://about.gitlab.com/releases/2018/09/22/gitlab-11-3-released/) in [GitLab Premium](https://about.gitlab.com/pricing/#self-managed) 11.3.
- The **primary** site doesn't talk to **secondary** sites to notify for changes (API).
- You can push directly to a **secondary** site (for both HTTP and SSH,
including Git LFS).
- There are [limitations](#limitations) when using Geo.
### Architecture
@ -111,21 +114,18 @@ In **secondary** sites, there is an additional daemon: [Geo Log Cursor](#geo-log
The following are required to run Geo:
- An operating system that supports OpenSSH 6.9+ (needed for
- An operating system that supports OpenSSH 6.9 or later (needed for
[fast lookup of authorized SSH keys in the database](../operations/fast_ssh_key_lookup.md))
The following operating systems are known to ship with a current version of OpenSSH:
- [CentOS](https://www.centos.org) 7.4+
- [Ubuntu](https://ubuntu.com) 16.04+
- PostgreSQL 12+ with [Streaming Replication](https://wiki.postgresql.org/wiki/Streaming_Replication)
- Git 2.9+
- Git-lfs 2.4.2+ on the user side when using LFS
- [CentOS](https://www.centos.org) 7.4 or later
- [Ubuntu](https://ubuntu.com) 16.04 or later
- PostgreSQL 12 or later with [Streaming Replication](https://wiki.postgresql.org/wiki/Streaming_Replication)
- Git 2.9 or later
- Git-lfs 2.4.2 or later on the user side when using LFS
- All sites must run the same GitLab version.
Additionally, check the GitLab [minimum requirements](../../install/requirements.md),
and we recommend you use:
- At least GitLab Enterprise Edition 10.0 for basic Geo features.
- The latest version for a better experience.
and we recommend you use the latest version of GitLab for a better experience.
### Firewall rules
@ -311,7 +311,8 @@ For answers to common questions, see the [Geo FAQ](replication/faq.md).
## Log files
In GitLab 9.5 and later, Geo stores structured log messages in a `geo.log` file. For Omnibus installations, this file is at `/var/log/gitlab/gitlab-rails/geo.log`.
Geo stores structured log messages in a `geo.log` file. For Omnibus GitLab
installations, this file is at `/var/log/gitlab/gitlab-rails/geo.log`.
This file contains information about when Geo attempts to sync repositories and files. Each line in the file contains a separate JSON entry that can be ingested into. For example, Elasticsearch or Splunk.

View File

@ -29,6 +29,40 @@ many organizations.
| Up to 500 | 4 vCPU, 3.6 GB memory | `n1-highcpu-4` | `c5.xlarge` | `F4s v2` |
| Up to 1,000 | 8 vCPU, 7.2 GB memory | `n1-highcpu-8` | `c5.2xlarge` | `F8s v2` |
```plantuml
@startuml 1k
card "**Prometheus + Grafana**" as monitor #7FFFD4
package "GitLab Single Server" as gitlab-single-server {
together {
card "**GitLab Rails**" as gitlab #32CD32
card "**Gitaly**" as gitaly #FF8C00
card "**PostgreSQL**" as postgres #4EA7FF
card "**Redis**" as redis #FF6347
card "**Sidekiq**" as sidekiq #ff8dd1
}
card "Local Storage" as local_storage #white
}
gitlab -[#32CD32]--> gitaly
gitlab -[#32CD32]--> postgres
gitlab -[#32CD32]--> redis
gitlab -[#32CD32]--> sidekiq
gitaly -[#32CD32]--> local_storage
postgres -[#32CD32]--> local_storage
sidekiq -[#32CD32]--> local_storage
gitlab -[#32CD32]--> local_storage
monitor .[#7FFFD4]u-> gitlab
monitor .[#7FFFD4]u-> sidekiq
monitor .[#7FFFD4]-> postgres
monitor .[#7FFFD4]-> gitaly
monitor .[#7FFFD4,norank]--> redis
@enduml
```
The diagram above shows that while GitLab can be installed on a single server, it is internally composed of multiple services. As a GitLab instance is scaled, each of these services are broken out and independently scaled according to the demands placed on them. In some cases PaaS can be leveraged for some services (e.g. Cloud Object Storage for some file systems). For the sake of redundancy some of the services become clusters of nodes storing the same data. In a horizontal configuration of GitLab there are various ancillary services required to coordinate clusters or discover of resources (e.g. PgBouncer for Postgres connection management, Consul for Prometheus end point discovery).
## Requirements
Before starting, you should take note of the following requirements / guidance for this reference architecture.

View File

@ -209,14 +209,18 @@ Note the following about the testing process:
- Testing is done publicly and all results are shared.
Τhe following table details the testing done against the reference architectures along with the frequency and results.
Testing is continuously evaluated and iterated on, so the table is constantly updated.
| Reference architecture size | GCP | AWS | Azure |
|-----------------------------|-----------------------------------------------------------------------------------------------------|-----|-------|
| 1k | [Omnibus - Daily](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/1k) | - | - |
| 2k | [Omnibus - Daily](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/2k) | - | - |
| 3k | [Omnibus - Weekly](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/3k) | - | - |
| 5k | [Omnibus - Weekly](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/5k) | - | - |
| 10k | [Omnibus - Daily](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/10k) <br/> [Omnibus (inc Cloud Services) - Ad-Hoc](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/10k) <br/> [Cloud Native Hybrid - Ad-Hoc](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/10k-Cloud-Native-Hybrid) | [Omnibus (inc Cloud Services) - Ad-Hoc](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/10k) | [Omnibus - Ad-Hoc](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/10k) |
| 25k | [Omnibus - Weekly](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/25k) | - | [Omnibus - Ad-Hoc](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/25k) |
| 50k | [Omnibus - Weekly](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/50k) | [Omnibus (inc Cloud Services) - Ad-Hoc](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/50k) | - |
| Reference Architecture | Tests Run<sup>1</sup> |
|------------------------|----------------------------------------------------------------------------------------------------------------------|
| 1k | [Omnibus - Daily (GCP)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/1k)<sup>2</sup> |
| 2k | [Omnibus - Daily (GCP)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/2k)<sup>2</sup> |
| 3k | [Omnibus - Weekly (GCP)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/3k)<sup>2</sup> |
| 5k | [Omnibus - Weekly (GCP)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/5k)<sup>2</sup> |
| 10k | [Omnibus - Daily (GCP)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/10k)<sup>2</sup><br/>[Omnibus - Ad-Hoc (GCP, AWS, Azure)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/10k)<br/><br/>[Cloud Native Hybrid - Ad-Hoc (GCP, AWS)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/10k-Cloud-Native-Hybrid) |
| 25k | [Omnibus - Weekly (GCP)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/25k)<sup>2</sup><br/>[Omnibus - Ad-Hoc (Azure)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/25k) |
| 50k | [Omnibus - Weekly (GCP)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/50k)<sup>2</sup><br/>[Omnibus - Ad-Hoc (AWS)](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/50k) |
Note that:
1. The list above is non exhaustive. Additional testing is continuously evaluated and iterated on, and the table is updated regularly.
1. The Omnibus reference architectures are VM-based only and testing has shown that they perform similarly on equivalently specced hardware regardless of Cloud Provider or if run on premises.

View File

@ -824,28 +824,28 @@ conflicting_permanent_redirects.destroy_all
### Close a merge request properly (if merged but still marked as open)
```ruby
p = Project.find_by_full_path('<full/path/to/project>')
m = p.merge_requests.find_by(iid: <iid>)
u = User.find_by_username('<username>')
MergeRequests::PostMergeService.new(p, u).execute(m)
p = Project.find_by_full_path('<namespace/project>')
m = p.merge_requests.find_by(iid: <iid>)
MergeRequests::PostMergeService.new(project: p, current_user: u).execute(m)
```
### Delete a merge request
```ruby
u = User.find_by_username('<username>')
p = Project.find_by_full_path('<group>/<project>')
m = p.merge_requests.find_by(iid: <IID>)
Issuable::DestroyService.new(m.project, u).execute(m)
p = Project.find_by_full_path('<namespace/project>')
m = p.merge_requests.find_by(iid: <iid>)
Issuable::DestroyService.new(project: m.project, current_user: u).execute(m)
```
### Rebase manually
```ruby
p = Project.find_by_full_path('<project_path>')
m = project.merge_requests.find_by(iid: )
u = User.find_by_username('<username>')
MergeRequests::RebaseService.new(m.target_project, u).execute(m)
p = Project.find_by_full_path('<namespace/project>')
m = p.merge_requests.find_by(iid: <iid>)
MergeRequests::RebaseService.new(project: m.target_project, current_user: u).execute(m)
```
## CI
@ -1264,6 +1264,9 @@ registry.replicator.send(:sync_repository)
## Generate Service Ping
The [Service Ping Guide](../../development/service_ping/index.md) in our developer documentation
has more information about Service Ping.
### Generate or get the cached Service Ping
```ruby
@ -1286,6 +1289,12 @@ Generates Service Ping data in JSON format.
rake gitlab:usage_data:generate
```
Generates Service Ping data in YAML format:
```shell
rake gitlab:usage_data:dump_sql_in_yaml
```
### Generate and send Service Ping
Prints the metrics saved in `conversational_development_index_metrics`.

View File

@ -1406,7 +1406,6 @@ Supported attributes:
| `jobs_enabled` | boolean | **{dotted-circle}** No | _(Deprecated)_ Enable jobs for this project. Use `builds_access_level` instead. |
| `lfs_enabled` | boolean | **{dotted-circle}** No | Enable LFS. |
| `merge_commit_template` | string | **{dotted-circle}** No | [Template](../user/project/merge_requests/commit_templates.md) used to create merge commit message in merge requests. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/20263) in GitLab 14.5.)_ |
| `squash_commit_template` | string | **{dotted-circle}** No | [Template](../user/project/merge_requests/commit_templates.md) used to create squash commit message in merge requests. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345275) in GitLab 14.6.)_ |
| `merge_method` | string | **{dotted-circle}** No | Set the [merge method](#project-merge-method) used. |
| `merge_pipelines_enabled` | boolean | **{dotted-circle}** No | Enable or disable merge pipelines. |
| `merge_requests_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, or `enabled`. |
@ -1426,6 +1425,7 @@ Supported attributes:
| `requirements_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, `enabled` or `public` |
| `restrict_user_defined_variables` | boolean | **{dotted-circle}** No | Allow only users with the [Maintainer role](../user/permissions.md) to pass user-defined variables when triggering a pipeline. For example when the pipeline is triggered in the UI, with the API, or by a trigger token. |
| `path` | string | **{dotted-circle}** No | Custom repository name for the project. By default generated based on name. |
| `printing_merge_request_link_enabled` | boolean | **{dotted-circle}** No | Show link to create/view merge request when pushing from the command line. |
| `public_builds` | boolean | **{dotted-circle}** No | If `true`, jobs can be viewed by non-project members. |
| `remove_source_branch_after_merge` | boolean | **{dotted-circle}** No | Enable `Delete source branch` option by default for all new merge requests. |
| `repository_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, or `enabled`. |
@ -1437,6 +1437,7 @@ Supported attributes:
| `show_default_award_emojis` | boolean | **{dotted-circle}** No | Show default award emojis. |
| `snippets_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, or `enabled`. |
| `snippets_enabled` | boolean | **{dotted-circle}** No | _(Deprecated)_ Enable snippets for this project. Use `snippets_access_level` instead. |
| `squash_commit_template` | string | **{dotted-circle}** No | [Template](../user/project/merge_requests/commit_templates.md) used to create squash commit message in merge requests. _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345275) in GitLab 14.6.)_ |
| `squash_option` | string | **{dotted-circle}** No | One of `never`, `always`, `default_on`, or `default_off`. |
| `suggestion_commit_message` | string | **{dotted-circle}** No | The commit message used to apply merge request suggestions. |
| `tag_list` | array | **{dotted-circle}** No | _([Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/328226) in GitLab 14.0)_ The list of tags for a project; put array of tags, that should be finally assigned to a project. Use `topics` instead. |

View File

@ -402,7 +402,7 @@ curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://git
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
| `name` | string | yes | The name of the branch |
## Require code owner approvals for a single branch
## Require code owner approvals for a single branch **(PREMIUM)**
Update the "code owner approval required" option for the given protected branch.
@ -411,11 +411,11 @@ PATCH /projects/:id/protected_branches/:name
```
```shell
curl --request PATCH --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/protected_branches/feature-branch"
curl --request PATCH --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/protected_branches/feature-branch?code_owner_approval_required=true"
```
| Attribute | Type | Required | Description |
| -------------------------------------------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
| `name` | string | yes | The name of the branch |
| `code_owner_approval_required` **(PREMIUM)** | boolean | no | Prevent pushes to this branch if it matches an item in the [`CODEOWNERS` file](../user/project/code_owners.md). (defaults: false)|
| `code_owner_approval_required` | boolean | no | Prevent pushes to this branch if it matches an item in the [`CODEOWNERS` file](../user/project/code_owners.md). (defaults: false)|

View File

@ -117,7 +117,7 @@ trigger_pipeline:
```
If you use the `CI_PIPELINE_SOURCE` [predefined CI/CD variable](../variables/predefined_variables.md)
in a pipeline triggered this way, [the value is `pipeline` (not `triggered`)](../triggers/index.md#authentication-tokens).
in a pipeline triggered this way, [the value is `pipeline` (not `triggered`)](../triggers/index.md#configure-cicd-jobs-to-run-in-triggered-pipelines).
## Download an artifact from a different pipeline **(PREMIUM)**

View File

@ -225,7 +225,7 @@ check the value of the `$CI_PIPELINE_SOURCE` variable:
| `pipeline` | For [multi-project pipelines](../pipelines/multi_project_pipelines.md) created by [using the API with `CI_JOB_TOKEN`](../pipelines/multi_project_pipelines.md#create-multi-project-pipelines-by-using-the-api), or the [`trigger`](../yaml/index.md#trigger) keyword. |
| `push` | For pipelines triggered by a `git push` event, including for branches and tags. |
| `schedule` | For [scheduled pipelines](../pipelines/schedules.md). |
| `trigger` | For pipelines created by using a [trigger token](../triggers/index.md#authentication-tokens). |
| `trigger` | For pipelines created by using a [trigger token](../triggers/index.md#configure-cicd-jobs-to-run-in-triggered-pipelines). |
| `web` | For pipelines created by using **Run pipeline** button in the GitLab UI, from the project's **CI/CD > Pipelines** section. |
| `webide` | For pipelines created by using the [WebIDE](../../user/project/web_ide/index.md). |
@ -335,7 +335,7 @@ to control when to add jobs to pipelines.
In the following example, `job` runs only for:
- Git tags
- [Triggers](../triggers/index.md#authentication-tokens)
- [Triggers](../triggers/index.md#configure-cicd-jobs-to-run-in-triggered-pipelines)
- [Scheduled pipelines](../pipelines/schedules.md)
```yaml

View File

@ -78,7 +78,7 @@ There are some high level differences between the products worth mentioning:
- on [schedule](../pipelines/schedules.md)
- from the [GitLab UI](../pipelines/index.md#run-a-pipeline-manually)
- by [API call](../triggers/index.md)
- by [webhook](../triggers/index.md#triggering-a-pipeline-from-a-webhook)
- by [webhook](../triggers/index.md#use-a-webhook)
- by [ChatOps](../chatops/index.md)
- You can control which jobs run in which cases, depending on how they are triggered,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

View File

@ -5,131 +5,121 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: tutorial
---
# Triggering pipelines through the API **(FREE)**
# Trigger pipelines by using the API **(FREE)**
Triggers can be used to force a pipeline rerun of a specific `ref` (branch or
tag) with an API call.
To trigger a pipeline for a specific branch or tag, you can use an API call
to the [pipeline triggers API endpoint](../../api/pipeline_triggers.md).
## Authentication tokens
When authenticating with the API, you can use:
The following methods of authentication are supported:
- A [trigger token](#create-a-trigger-token) to trigger a branch or tag pipeline.
- A [CI/CD job token](../jobs/ci_job_token.md) to trigger a [multi-project pipeline](../pipelines/multi_project_pipelines.md#create-multi-project-pipelines-by-using-the-api).
- Trigger tokens: A unique trigger token can be obtained when [adding a new trigger](#adding-a-new-trigger).
- [CI job tokens](../jobs/ci_job_token.md).
## Create a trigger token
If using the `$CI_PIPELINE_SOURCE` [predefined CI/CD variable](../variables/predefined_variables.md)
to limit which jobs run in a pipeline, the value could be either `pipeline` or `trigger`,
depending on which trigger method is used.
You can trigger a pipeline for a branch or tag by generating a trigger token and using it
to authenticate an API call. The token impersonates a user's project access and permissions.
| `$CI_PIPELINE_SOURCE` value | Trigger method |
|-----------------------------|----------------|
| `pipeline` | Using the `trigger` keyword in the CI/CD configuration file, or using the trigger API with `$CI_JOB_TOKEN`. |
| `trigger` | Using the trigger API using a generated trigger token |
Prerequisite:
This also applies when using the `pipelines` or `triggers` keywords with the legacy [`only/except` basic syntax](../yaml/index.md#only--except).
- You must have at least the [Maintainer role](../../user/permissions.md) for the project.
## Adding a new trigger
To create a trigger token:
Go to your
**Settings > CI/CD** under **Triggers** to add a new trigger. The **Add trigger** button creates
a new token which you can then use to trigger a rerun of this
particular project's pipeline.
Every new trigger you create, gets assigned a different token which you can
then use inside your scripts or `.gitlab-ci.yml`. You also have a nice
overview of the time the triggers were last used.
![Triggers page overview](img/triggers_page.png)
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand **Pipeline triggers**.
1. Enter a description and select **Add trigger**.
- You can view and copy the full token for all triggers you have created.
- You can only see the first 4 characters for tokens created by other project members.
WARNING:
Passing plain text tokens in public projects is a security issue. Potential
attackers can impersonate the user that exposed their trigger token publicly in
their `.gitlab-ci.yml` file. Use [CI/CD variables](../variables/index.md)
to protect trigger tokens.
It is a security risk to save tokens in plain text in public projects. Potential
attackers could use a trigger token exposed in the `.gitlab-ci.yml` file to impersonate
the user that created the token. Use [masked CI/CD variables](../variables/index.md#mask-a-cicd-variable)
to improve the security of trigger tokens.
## Revoking a trigger
## Trigger a pipeline
You can revoke a trigger any time by going at your project's
**Settings > CI/CD** under **Triggers** and hitting the **Revoke** button.
The action is irreversible.
After you [create a trigger token](#create-a-trigger-token), you can use it to trigger
pipelines with a tool that can access the API, or a webhook.
## Triggering a pipeline
### Use cURL
To trigger a pipeline you need to send a `POST` request to the GitLab API endpoint:
You can use cURL to trigger pipelines with the [pipeline triggers API endpoint](../../api/pipeline_triggers.md).
For example:
```plaintext
POST /projects/:id/trigger/pipeline
```
- Use a multiline cURL command:
The required parameters are the [trigger's `token`](#authentication-tokens)
and the Git `ref` on which the trigger is performed. Valid refs are
branches or tags. The `:id` of a project can be found by
[querying the API](../../api/projects.md) or by visiting the **CI/CD**
settings page which provides self-explanatory examples.
```shell
curl --request POST \
--form token=<token> \
--formref=<ref_name> \
"https://gitlab.example.com/api/v4/projects/<project_id>/trigger/pipeline"
```
When a rerun of a pipeline is triggered, jobs are labeled as `triggered` in
**CI/CD > Jobs**.
- Use cURL and pass the `<token>` and `<ref_name>` in the query string:
You can see which trigger caused a job to run by visiting the single job page.
A part of the trigger's token is exposed in the UI as you can see from the image
below.
```shell
curl --request POST \
"https://gitlab.example.com/api/v4/projects/<project_id>/trigger/pipeline?token=<token>&ref=<ref_name>"
```
![Marked as triggered on a single job page](img/trigger_single_job.png)
In each example, replace:
By using cURL you can trigger a pipeline rerun with minimal effort, for example:
- The URL with `https://gitlab.com` or the URL of your instance.
- `<token>` with your trigger token.
- `<ref_name>` with a branch or tag name, like `main`.
- `<project_id>` with your project ID, like `123456`. The project ID is displayed
at the top of every project's landing page.
```shell
curl --request POST \
--form token=TOKEN \
--form ref=main \
"https://gitlab.example.com/api/v4/projects/9/trigger/pipeline"
```
### Use a CI/CD job
In this case, the pipeline for the project with ID `9` runs on the `main` branch.
You can use a CI/CD job with a triggers token to trigger pipelines when another pipeline
runs.
Alternatively, you can pass the `token` and `ref` arguments in the query string:
```shell
curl --request POST \
"https://gitlab.example.com/api/v4/projects/9/trigger/pipeline?token=TOKEN&ref=main"
```
You can also benefit by using triggers in your `.gitlab-ci.yml`. Let's say that
you have two projects, A and B, and you want to trigger a pipeline on the `main`
branch of project B whenever a tag on project A is created. This is the job you
need to add in project A's `.gitlab-ci.yml`:
For example, to trigger a pipeline on the `main` branch of `project-B` when a tag
is created in `project-A`, add the following job to project A's `.gitlab-ci.yml` file:
```yaml
trigger_pipeline:
stage: deploy
script:
- 'curl --request POST --form token=TOKEN --form ref=main "https://gitlab.example.com/api/v4/projects/9/trigger/pipeline"'
- 'curl --fail --request POST --form token=$MY_TRIGGER_TOKEN --form ref=main "https://gitlab.example.com/api/v4/projects/123456/trigger/pipeline"'
rules:
- if: $CI_COMMIT_TAG
```
This means that whenever a new tag is pushed on project A, the job runs and the
`trigger_pipeline` job is executed, triggering the pipeline for project B. The
`stage: deploy` ensures that this job runs only after all jobs with
`stage: test` complete successfully.
In this example:
NOTE:
You [cannot use the API to start `when:manual` trigger jobs](https://gitlab.com/gitlab-org/gitlab/-/issues/284086).
- `1234` is the project ID for `project-B`. The project ID is displayed at the top
of every project's landing page.
- The [`rules`](../yaml/index.md#rules) cause the job to run every time a tag is added to `project-A`.
- `MY_TRIGGER_TOKEN` is a [masked CI/CD variables](../variables/index.md#mask-a-cicd-variable)
that contains the trigger token.
## Triggering a pipeline from a webhook
### Use a webhook
To trigger a job from a webhook of another project you need to add the following
webhook URL for Push and Tag events (change the project ID, ref and token):
To trigger a pipeline from another project's webhook, use a webhook URL like the following
for push and tag events:
```plaintext
https://gitlab.example.com/api/v4/projects/9/ref/main/trigger/pipeline?token=TOKEN
```
You should pass `ref` as part of the URL, to take precedence over `ref` from
the webhook body that designates the branch ref that fired the trigger in the
source repository. Be sure to URL-encode `ref` if it contains slashes.
Replace:
### Using webhook payload in the triggered pipeline
- The URL with `https://gitlab.com` or the URL of your instance.
- `<token>` with your trigger token.
- `<ref_name>` with a branch or tag name, like `main`.
- `<project_id>` with your project ID, like `123456`. The project ID is displayed
at the top of the project's landing page.
The `ref` in the URL takes precedence over the `ref` in the webhook payload. The
payload `ref` is the branch that fired the trigger in the source repository.
You must URL-encode `ref` if it contains slashes.
#### Use a webhook payload
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31197) in GitLab 13.9.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/321027) in GitLab 13.11.
@ -139,94 +129,68 @@ the `TRIGGER_PAYLOAD` [predefined CI/CD variable](../variables/predefined_variab
The payload is exposed as a [file-type variable](../variables/index.md#cicd-variable-types),
so you can access the data with `cat $TRIGGER_PAYLOAD` or a similar command.
## Making use of trigger variables
### Pass CI/CD variables in the API call
You can pass any number of arbitrary variables in the trigger API call and they
are available in GitLab CI/CD so that they can be used in your `.gitlab-ci.yml`
file. The parameter is of the form:
You can pass any number of [CI/CD variables](../variables/index.md) in the trigger API call.
These variables have the [highest precedence](../variables/index.md#cicd-variable-precedence),
and override all variables with the same name.
```plaintext
variables[key]=value
```
This information is also exposed in the UI. _Values_ are only viewable by users with the Owner and Maintainer role.
![Job variables in UI](img/trigger_variables.png)
Using trigger variables can be proven useful for a variety of reasons:
- Identifiable jobs. Since the variable is exposed in the UI you can know
why the pipeline was triggered if you pass a variable that explains the
purpose.
- Conditional job processing. You can have conditional jobs that run whenever
a certain variable is present.
Consider the following `.gitlab-ci.yml` where we set three
[stages](../yaml/index.md#stages) and the `upload_package` job is run only
when all jobs from the test and build stages pass. When the `UPLOAD_TO_S3`
variable is non-zero, `make upload` is run.
```yaml
stages:
- test
- build
- package
run_tests:
stage: test
script:
- make test
build_package:
stage: build
script:
- make build
upload_package:
stage: package
script:
- if [ -n "${UPLOAD_TO_S3}" ]; then make upload; fi
```
You can then trigger a pipeline while you pass the `UPLOAD_TO_S3` variable
and the script of the `upload_package` job is run:
The parameter is of the form `variables[key]=value`, for example:
```shell
curl --request POST \
--form token=TOKEN \
--form ref=main \
--form "variables[UPLOAD_TO_S3]=true" \
"https://gitlab.example.com/api/v4/projects/9/trigger/pipeline"
"https://gitlab.example.com/api/v4/projects/123456/trigger/pipeline"
```
Trigger variables have the [highest priority](../variables/index.md#cicd-variable-precedence)
of all types of variables.
CI/CD variables in triggered pipelines display on each job's page, but only
users with the Owner and Maintainer role can view the values.
## Using cron to trigger nightly pipelines
![Job variables in UI](img/trigger_variables.png)
Whether you craft a script or just run cURL directly, you can trigger jobs
in conjunction with cron. The example below triggers a job on the `main` branch
of project with ID `9` every night at `00:30`:
## Revoke a trigger token
```shell
30 0 * * * curl --request POST --form token=TOKEN --form ref=main "https://gitlab.example.com/api/v4/projects/9/trigger/pipeline"
```
To revoke a trigger token:
This behavior can also be achieved through the GitLab UI with
[pipeline schedules](../pipelines/schedules.md).
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand **Pipeline triggers**.
1. To the left of the trigger token you want to revoke, select **Revoke** (**{remove}**).
## Legacy triggers
A revoked trigger token cannot be added back.
Old triggers, created before GitLab 9.0 are marked as legacy.
## Configure CI/CD jobs to run in triggered pipelines
Triggers with the legacy label do not have an associated user and only have
access to the current project. They are considered deprecated and might be
removed with one of the future versions of GitLab.
To [configure when to run jobs](../jobs/job_control.md) in triggered pipelines:
- Use [`rules`](../yaml/index.md#rules) with the `$CI_PIPELINE_SOURCE` [predefined CI/CD variable](../variables/predefined_variables.md).
- Use [`only`/`except`](../yaml/index.md#onlyrefs--exceptrefs) keywords.
| `$CI_PIPELINE_SOURCE` value | `only`/`except` keywords | Trigger method |
|-----------------------------|--------------------------|---------------------|
| `trigger` | `triggers` | In pipelines triggered with the [pipeline triggers API](../../api/pipeline_triggers.md) by using a [trigger token](#create-a-trigger-token). |
| `pipeline` | `pipelines` | In [multi-project pipelines](../pipelines/multi_project_pipelines.md#create-multi-project-pipelines-by-using-the-api) triggered with the [pipeline triggers API](../../api/pipeline_triggers.md) by using the [`$CI_JOB_TOKEN`](../jobs/ci_job_token.md), or by using the [`trigger`](../yaml/index.md#trigger) keyword in the CI/CD configuration file. |
Additionally, the `$CI_PIPELINE_TRIGGERED` predefined CI/CD variable is set to `true`
in pipelines triggered with a trigger token.
## See which trigger token was used
You can see which trigger caused a job to run by visiting the single job page.
A part of the trigger's token displays on the right of the page, under the job details:
![Marked as triggered on a single job page](img/trigger_single_job.png)
In pipelines triggered with a trigger token, jobs are labeled as `triggered` in
**CI/CD > Jobs**.
## Troubleshooting
### '404 not found' when triggering a pipeline
### `404 not found` when triggering a pipeline
A response of `{"message":"404 Not Found"}` when triggering a pipeline might be caused
by using a Personal Access Token instead of a trigger token. [Add a new trigger](#adding-a-new-trigger)
and use that token to authenticate when triggering a pipeline.
by using a [personal access token](../../user/profile/personal_access_tokens.md)
instead of a trigger token. [Create a new trigger token](#create-a-trigger-token)
and use it instead of the personal access token.

View File

@ -612,7 +612,7 @@ which variables take precedence.
The order of precedence for variables is (from highest to lowest):
1. [Trigger variables](../triggers/index.md#making-use-of-trigger-variables),
1. [Trigger variables](../triggers/index.md#pass-cicd-variables-in-the-api-call),
[scheduled pipeline variables](../pipelines/schedules.md#using-variables),
and [manual pipeline run variables](#override-a-variable-when-running-a-pipeline-manually).
1. Project [variables](#custom-cicd-variables).
@ -646,7 +646,7 @@ You can override the value of a variable when you:
1. Create a pipeline by using [the API](../../api/pipelines.md#create-a-new-pipeline).
1. Run a job manually in the UI.
1. Use [push options](../../user/project/push_options.md#push-options-for-gitlab-cicd).
1. Trigger a pipeline by using [the API](../triggers/index.md#making-use-of-trigger-variables).
1. Trigger a pipeline by using [the API](../triggers/index.md#pass-cicd-variables-in-the-api-call).
1. Pass variables to a downstream pipeline [by using the `variable` keyword](../pipelines/multi_project_pipelines.md#pass-cicd-variables-to-a-downstream-pipeline-by-using-the-variables-keyword)
or [by using variable inheritance](../pipelines/multi_project_pipelines.md#pass-cicd-variables-to-a-downstream-pipeline-by-using-variable-inheritance).

View File

@ -77,7 +77,7 @@ There are also a number of [variables you can use to configure runner behavior](
| `CI_PAGES_URL` | 11.8 | all | The URL for a GitLab Pages site. Always a subdomain of `CI_PAGES_DOMAIN`. |
| `CI_PIPELINE_ID` | 8.10 | all | The instance-level ID of the current pipeline. This ID is unique across all projects on the GitLab instance. |
| `CI_PIPELINE_IID` | 11.0 | all | The project-level IID (internal ID) of the current pipeline. This ID is unique only within the current project. |
| `CI_PIPELINE_SOURCE` | 10.0 | all | How the pipeline was triggered. Can be `push`, `web`, `schedule`, `api`, `external`, `chat`, `webide`, `merge_request_event`, `external_pull_request_event`, `parent_pipeline`, [`trigger`, or `pipeline`](../triggers/index.md#authentication-tokens). |
| `CI_PIPELINE_SOURCE` | 10.0 | all | How the pipeline was triggered. Can be `push`, `web`, `schedule`, `api`, `external`, `chat`, `webide`, `merge_request_event`, `external_pull_request_event`, `parent_pipeline`, [`trigger`, or `pipeline`](../triggers/index.md#configure-cicd-jobs-to-run-in-triggered-pipelines). |
| `CI_PIPELINE_TRIGGERED` | all | all | `true` if the job was [triggered](../triggers/index.md). |
| `CI_PIPELINE_URL` | 11.1 | 0.5 | The URL for the pipeline details. |
| `CI_PIPELINE_CREATED_AT` | 13.10 | all | The UTC datetime when the pipeline was created, in [ISO 8601](https://tools.ietf.org/html/rfc3339#appendix-A) format. |
@ -124,7 +124,7 @@ There are also a number of [variables you can use to configure runner behavior](
| `GITLAB_USER_ID` | 8.12 | all | The ID of the user who started the job. |
| `GITLAB_USER_LOGIN` | 10.0 | all | The username of the user who started the job. |
| `GITLAB_USER_NAME` | 10.0 | all | The name of the user who started the job. |
| `TRIGGER_PAYLOAD` | 13.9 | all | The webhook payload. Only available when a pipeline is [triggered with a webhook](../triggers/index.md#using-webhook-payload-in-the-triggered-pipeline). |
| `TRIGGER_PAYLOAD` | 13.9 | all | The webhook payload. Only available when a pipeline is [triggered with a webhook](../triggers/index.md#use-a-webhook-payload). |
## Predefined variables for merge request pipelines

View File

@ -238,7 +238,7 @@ In `include` sections in your `.gitlab-ci.yml` file, you can use:
In GitLab 14.5 and later, you can also use:
- [Trigger variables](../triggers/index.md#making-use-of-trigger-variables).
- [Trigger variables](../triggers/index.md#pass-cicd-variables-in-the-api-call).
- [Scheduled pipeline variables](../pipelines/schedules.md#using-variables).
- [Manual pipeline run variables](../variables/index.md#override-a-variable-when-running-a-pipeline-manually).
- Pipeline [predefined variables](../variables/predefined_variables.md).

View File

@ -2369,7 +2369,7 @@ pipeline based on branch names or pipeline types.
| `pushes` | For pipelines triggered by a `git push` event, including for branches and tags. |
| `schedules` | For [scheduled pipelines](../pipelines/schedules.md). |
| `tags` | When the Git reference for a pipeline is a tag. |
| `triggers` | For pipelines created by using a [trigger token](../triggers/index.md#authentication-tokens). |
| `triggers` | For pipelines created by using a [trigger token](../triggers/index.md#configure-cicd-jobs-to-run-in-triggered-pipelines). |
| `web` | For pipelines created by selecting **Run pipeline** in the GitLab UI, from the project's **CI/CD > Pipelines** section. |
**Example of `only:refs` and `except:refs`**:
@ -3635,6 +3635,7 @@ trigger_job:
- Jobs with `trigger` can only use a [limited set of keywords](../pipelines/multi_project_pipelines.md#define-multi-project-pipelines-in-your-gitlab-ciyml-file).
For example, you can't run commands with [`script`](#script), [`before_script`](#before_script),
or [`after_script`](#after_script).
- You [cannot use the API to start `when:manual` trigger jobs](https://gitlab.com/gitlab-org/gitlab/-/issues/284086).
- 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`.
@ -3645,8 +3646,8 @@ trigger_job:
- [Multi-project pipeline configuration examples](../pipelines/multi_project_pipelines.md#define-multi-project-pipelines-in-your-gitlab-ciyml-file).
- [Child pipeline configuration examples](../pipelines/parent_child_pipelines.md#examples).
- To force a rebuild of a specific branch, tag, or commit, you can
[use an API call with a trigger token](../triggers/index.md).
- 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:strategy`

View File

@ -79,7 +79,7 @@ cop](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49771).
## Scores, Order, Performance
To see how the rules get evaluated into a judgment, it is useful in a console to use `policy.debug(:some_ability)`. This prints the rules in the order they are evaluated.
To see how the rules get evaluated into a judgment, open a Rails console and run: `policy.debug(:some_ability)`. This prints the rules in the order they are evaluated.
For example, let's say you wanted to debug `IssuePolicy`. You might run
the debugger in this way:
@ -222,7 +222,7 @@ delegation would end up with only children whose parents enjoy green vegetables
eating it. But a parent may well give their child broccoli, even if they dislike
it themselves, because it is good for their child.
The solution it to override the `:eat_broccoli` ability in the child policy:
The solution is to override the `:eat_broccoli` ability in the child policy:
```ruby
class ChildPolicy < BasePolicy

View File

@ -81,6 +81,7 @@ sudo docker run --detach \
--volume $GITLAB_HOME/config:/etc/gitlab \
--volume $GITLAB_HOME/logs:/var/log/gitlab \
--volume $GITLAB_HOME/data:/var/opt/gitlab \
--shm-size 256m \
gitlab/gitlab-ee:latest
```
@ -99,6 +100,7 @@ sudo docker run --detach \
--volume $GITLAB_HOME/config:/etc/gitlab:Z \
--volume $GITLAB_HOME/logs:/var/log/gitlab:Z \
--volume $GITLAB_HOME/data:/var/opt/gitlab:Z \
--shm-size 256m \
gitlab/gitlab-ee:latest
```
@ -155,6 +157,7 @@ install, and upgrade your Docker-based GitLab installation:
- '$GITLAB_HOME/config:/etc/gitlab'
- '$GITLAB_HOME/logs:/var/log/gitlab'
- '$GITLAB_HOME/data:/var/opt/gitlab'
shm_size: '256m'
```
1. Make sure you are in the same directory as `docker-compose.yml` and start
@ -188,6 +191,7 @@ web:
- '$GITLAB_HOME/config:/etc/gitlab'
- '$GITLAB_HOME/logs:/var/log/gitlab'
- '$GITLAB_HOME/data:/var/opt/gitlab'
shm_size: '256m'
```
This is the same as using `--publish 8929:8929 --publish 2224:22`.
@ -221,6 +225,7 @@ Here's an example that deploys GitLab with four runners as a [stack](https://doc
- $GITLAB_HOME/data:/var/opt/gitlab
- $GITLAB_HOME/logs:/var/log/gitlab
- $GITLAB_HOME/config:/etc/gitlab
shm_size: '256m'
environment:
GITLAB_OMNIBUS_CONFIG: "from_file('/omnibus_config.rb')"
configs:
@ -325,6 +330,7 @@ sudo docker run --detach \
--volume $GITLAB_HOME/config:/etc/gitlab \
--volume $GITLAB_HOME/logs:/var/log/gitlab \
--volume $GITLAB_HOME/data:/var/opt/gitlab \
--shm-size 256m \
gitlab/gitlab-ee:latest
```
@ -361,6 +367,7 @@ sudo docker run --detach \
--volume $GITLAB_HOME/config:/etc/gitlab \
--volume $GITLAB_HOME/logs:/var/log/gitlab \
--volume $GITLAB_HOME/data:/var/opt/gitlab \
--shm-size 256m \
gitlab/gitlab-ee:latest
```
@ -388,6 +395,7 @@ port `2289`:
--volume $GITLAB_HOME/config:/etc/gitlab \
--volume $GITLAB_HOME/logs:/var/log/gitlab \
--volume $GITLAB_HOME/data:/var/opt/gitlab \
--shm-size 256m \
gitlab/gitlab-ee:latest
```
@ -477,6 +485,7 @@ To update GitLab that was [installed using Docker Engine](#install-gitlab-using-
--volume $GITLAB_HOME/config:/etc/gitlab \
--volume $GITLAB_HOME/logs:/var/log/gitlab \
--volume $GITLAB_HOME/data:/var/opt/gitlab \
--shm-size 256m \
gitlab/gitlab-ee:latest
```

View File

@ -339,6 +339,11 @@ Below is a list of Mattermost versions for GitLab 11.10 and later:
| 14.2 | 5.37 |
| 14.3 | 5.38 |
| 14.4 | 5.39 |
| 14.5 | 5.39 |
| 14.6 | 6.1 |
- GitLab 14.5 remained on Mattermost 5.39
- GitLab 14.6 updates to Mattermost 6.1 instead of 6.0
NOTE:
When upgrading the Mattermost version, it is essential to check the
@ -364,6 +369,21 @@ If this is not the case, there are two options:
For a complete list of upgrade notices and special considerations for older versions, see the [Mattermost documentation](https://docs.mattermost.com/administration/important-upgrade-notes.html).
## Upgrading GitLab Mattermost to 14.6
GitLab 14.6 includes Mattermost 6.1, and also includes the migrations for Mattermost 6.0. For information about upgrading and for ways to reduce the downtime of those migrations, read the [Important Upgrade Notes](https://docs.mattermost.com/administration/important-upgrade-notes.html) for both versions.
NOTE:
The Mattermost upgrade notes refer to different impacts when used with a PostgreSQL versus a MySQL database. The GitLab Mattermost included with the GitLab Linux packages uses a PostgreSQL database.
If you need to connect in the database to perform any manual migrations, run the following:
```console
sudo gitlab-psql -d mattermost_production
```
You can then run the necessary queries that are described in the [Important Upgrade Notes](https://docs.mattermost.com/administration/important-upgrade-notes.html).
## Upgrading GitLab Mattermost from versions prior to 11.0
With version 11.0, GitLab introduced breaking changes which affected Mattermost configuration.

View File

@ -1422,6 +1422,13 @@ after which users must reactivate 2FA.
DELETE FROM ci_variables;
```
1. If you know the specific group or project from which you wish to delete variables, you can include a `WHERE` statement to specify that in your `DELETE`:
```sql
DELETE FROM ci_group_variables WHERE group_id = <GROUPID>;
DELETE FROM ci_variables WHERE project_id = <PROJECTID>;
```
You may need to reconfigure or restart GitLab for the changes to take effect.
#### Reset runner registration tokens

View File

@ -9,7 +9,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Cron syntax is used to schedule when jobs should run.
You may need to use a cron syntax string to
[trigger nightly pipelines](../../ci/triggers/index.md#using-cron-to-trigger-nightly-pipelines),
create a [pipeline schedule](../../api/pipeline_schedules.md#create-a-new-pipeline-schedule),
or to prevent unintentional releases by setting a
[deploy freeze](../../user/project/releases/index.md#prevent-unintentional-releases-by-setting-a-deploy-freeze).

View File

@ -219,30 +219,9 @@ sudo -u git -H bundle exec rake gitlab:elastic:list_pending_migrations
See [how to retry a halted migration](../integration/elasticsearch.md#retry-a-halted-migration).
## Upgrade paths
## Upgrading without downtime
Upgrading across multiple GitLab versions in one go is *only possible by accepting downtime*.
The following examples assume downtime is acceptable while upgrading.
If you don't want any downtime, read how to [upgrade with zero downtime](zero_downtime.md).
Find where your version sits in the upgrade path below, and upgrade GitLab
accordingly, while also consulting the
[version-specific upgrade instructions](#version-specific-upgrading-instructions):
`8.11.Z` -> `8.12.0` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> [`11.11.8`](#1200) -> `12.0.12` -> [`12.1.17`](#1210) -> `12.10.14` -> `13.0.14` -> [`13.1.11`](#1310) -> [`13.8.8`](#1388) -> [`13.12.15`](https://about.gitlab.com/releases/categories/releases/) -> [latest `14.0.Z`](#1400) -> [latest `14.1.Z`](#1410) -> [latest `14.Y.Z`](https://about.gitlab.com/releases/categories/releases/)
The following table, while not exhaustive, shows some examples of the supported
upgrade paths.
| Target version | Your version | Supported upgrade path | Note |
| -------------- | ------------ | ---------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `14.1.6` | `13.9.2` | `13.9.2` -> `13.12.12` -> `14.0.11` -> `14.1.6` | Two intermediate versions are required: `13.12` and `14.0`, then `14.1`. |
| `13.12.10` | `12.9.2` | `12.9.2` -> `12.10.14` -> `13.0.14` -> `13.1.11` -> `13.8.8` -> `13.12.10` | Four intermediate versions are required: `12.10`, `13.0`, `13.1` and `13.8.8`, then `13.12.10`. |
| `13.2.10` | `11.5.0` | `11.5.0` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` -> `13.0.14` -> `13.1.11` -> `13.2.10` | Six intermediate versions are required: `11.11`, `12.0`, `12.1`, `12.10`, `13.0` and `13.1`, then `13.2.10`. |
| `12.10.14` | `11.3.4` | `11.3.4` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` | Three intermediate versions are required: `11.11`, `12.0` and `12.1`, then `12.10.14`. |
| `12.9.5` | `10.4.5` | `10.4.5` -> `10.8.7` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.9.5` | Four intermediate versions are required: `10.8`, `11.11`, `12.0` and `12.1`, then `12.9.5`. |
| `12.2.5` | `9.2.6` | `9.2.6` -> `9.5.10` -> `10.8.7` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.2.5` | Five intermediate versions are required: `9.5`, `10.8`, `11.11`, `12.0`, `12.1`, then `12.2.5`. |
| `11.3.4` | `8.13.4` | `8.13.4` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> `11.3.4` | `8.17.7` is the last version in version 8, `9.5.10` is the last version in version 9, `10.8.7` is the last version in version 10. |
Read how to [upgrade without downtime](zero_downtime.md).
## Upgrading to a new major version
@ -254,8 +233,9 @@ cannot guarantee that upgrading between major versions is seamless.
It is required to follow the following upgrade steps to ensure a successful *major* version upgrade:
1. Upgrade to the latest minor version of the preceding major version.
1. Upgrade to the first minor version (`X.0.Z`) of the target major version.
1. Proceed with upgrading to a newer release.
1. Upgrade to the next major version (`X.0.Z`).
1. Upgrade to its first minor version (`X.1.Z`).
1. Proceed with upgrading to a newer releases of that major version.
Identify a [supported upgrade path](#upgrade-paths).
@ -273,9 +253,32 @@ If your GitLab instance has any runners associated with it, it is very
important to upgrade GitLab Runner to match the GitLab minor version that was
upgraded to. This is to ensure [compatibility with GitLab versions](https://docs.gitlab.com/runner/#gitlab-runner-versions).
## Upgrading without downtime
## Upgrade paths
Read how to [upgrade without downtime](zero_downtime.md).
Upgrading across multiple GitLab versions in one go is *only possible by accepting downtime*.
The following examples assume downtime is acceptable while upgrading.
If you don't want any downtime, read how to [upgrade with zero downtime](zero_downtime.md).
Find where your version sits in the upgrade path below, and upgrade GitLab
accordingly, while also consulting the
[version-specific upgrade instructions](#version-specific-upgrading-instructions):
`8.11.Z` -> `8.12.0` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> [`11.11.8`](#1200) -> `12.0.12` -> [`12.1.17`](#1210) -> `12.10.14` -> `13.0.14` -> [`13.1.11`](#1310) -> [`13.8.8`](#1388) -> [latest `13.12.Z`](https://about.gitlab.com/releases/categories/releases/) -> [latest `14.0.Z`](#1400) -> [latest `14.1.Z`](#1410) -> [latest `14.Y.Z`](https://about.gitlab.com/releases/categories/releases/)
The following table, while not exhaustive, shows some examples of the supported
upgrade paths.
Additional steps between the mentioned versions are possible. We list the minimally necessary steps only.
| Target version | Your version | Supported upgrade path | Note |
| -------------- | ------------ | ---------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `14.2.6` | `13.10.2` | `13.10.2` -> `13.12.12` -> `14.0.11` -> `14.1.8` -> `14.2.6` | Three intermediate versions are required: `13.12`, `14.0`, and `14.1`, then `14.2.6`. |
| `14.1.8` | `13.9.2` | `13.9.2` -> `13.12.12` -> `14.0.11` -> `14.1.8` | Two intermediate versions are required: `13.12` and `14.0`, then `14.1.8`. |
| `13.12.10` | `12.9.2` | `12.9.2` -> `12.10.14` -> `13.0.14` -> `13.1.11` -> `13.8.8` -> `13.12.10` | Four intermediate versions are required: `12.10`, `13.0`, `13.1` and `13.8.8`, then `13.12.10`. |
| `13.2.10` | `11.5.0` | `11.5.0` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` -> `13.0.14` -> `13.1.11` -> `13.2.10` | Six intermediate versions are required: `11.11`, `12.0`, `12.1`, `12.10`, `13.0` and `13.1`, then `13.2.10`. |
| `12.10.14` | `11.3.4` | `11.3.4` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` | Three intermediate versions are required: `11.11`, `12.0` and `12.1`, then `12.10.14`. |
| `12.9.5` | `10.4.5` | `10.4.5` -> `10.8.7` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.9.5` | Four intermediate versions are required: `10.8`, `11.11`, `12.0` and `12.1`, then `12.9.5`. |
| `12.2.5` | `9.2.6` | `9.2.6` -> `9.5.10` -> `10.8.7` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.2.5` | Five intermediate versions are required: `9.5`, `10.8`, `11.11`, `12.0`, and `12.1`, then `12.2.5`. |
| `11.3.4` | `8.13.4` | `8.13.4` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> `11.3.4` | `8.17.7` is the last version in version 8, `9.5.10` is the last version in version 9, `10.8.7` is the last version in version 10. |
## Upgrading between editions

View File

@ -159,7 +159,7 @@ install GitLab for the first time or update it.
To download and install GitLab:
1. Visit the [official repository](#upgrade-using-the-official-repositories) of your package.
1. Filter the list by searching for the version you want to install (for example 14.1.6).
1. Filter the list by searching for the version you want to install (for example 14.1.8).
Multiple packages may exist for a single version, one for each supported distribution
and architecture. Next to the filename is a label indicating the distribution,
as the filenames may be the same.

View File

@ -78,3 +78,83 @@ exports[`User Operation confirmation modal renders modal with form included 1`]
</gl-button-stub>
</div>
`;
exports[`User Operation confirmation modal when user's name has leading and trailing whitespace displays user's name without whitespace 1`] = `
<div>
<p>
content
</p>
<user-deletion-obstacles-list-stub
obstacles="schedule1,policy1"
username="John Smith"
/>
<p>
To confirm, type
<code
class="gl-white-space-pre-wrap"
>
John Smith
</code>
</p>
<form
action="delete-url"
method="post"
>
<input
name="_method"
type="hidden"
value="delete"
/>
<input
name="authenticity_token"
type="hidden"
value="csrf"
/>
<gl-form-input-stub
autocomplete="off"
autofocus=""
name="username"
type="text"
value=""
/>
</form>
<gl-button-stub
buttontextclasses=""
category="primary"
icon=""
size="medium"
variant="default"
>
Cancel
</gl-button-stub>
<gl-button-stub
buttontextclasses=""
category="secondary"
disabled="true"
icon=""
size="medium"
variant="danger"
>
secondaryAction
</gl-button-stub>
<gl-button-stub
buttontextclasses=""
category="primary"
disabled="true"
icon=""
size="medium"
variant="danger"
>
action
</gl-button-stub>
</div>
`;

View File

@ -1,4 +1,4 @@
import { GlButton, GlFormInput } from '@gitlab/ui';
import { GlButton, GlFormInput, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import DeleteUserModal from '~/admin/users/components/modals/delete_user_modal.vue';
import UserDeletionObstaclesList from '~/vue_shared/components/user_deletion_obstacles/user_deletion_obstacles_list.vue';
@ -35,7 +35,7 @@ describe('User Operation confirmation modal', () => {
const badUsername = 'bad_username';
const userDeletionObstacles = '["schedule1", "policy1"]';
const createComponent = (props = {}) => {
const createComponent = (props = {}, stubs = {}) => {
wrapper = shallowMount(DeleteUserModal, {
propsData: {
username,
@ -51,6 +51,7 @@ describe('User Operation confirmation modal', () => {
},
stubs: {
GlModal: ModalStub,
...stubs,
},
});
};
@ -150,6 +151,30 @@ describe('User Operation confirmation modal', () => {
});
});
describe("when user's name has leading and trailing whitespace", () => {
beforeEach(() => {
createComponent(
{
username: ' John Smith ',
},
{ GlSprintf },
);
});
it("displays user's name without whitespace", () => {
expect(wrapper.element).toMatchSnapshot();
});
it("shows enabled buttons when user's name is entered without whitespace", async () => {
setUsername('John Smith');
await wrapper.vm.$nextTick();
expect(findPrimaryButton().attributes('disabled')).toBeUndefined();
expect(findSecondaryButton().attributes('disabled')).toBeUndefined();
});
});
describe('Related user-deletion-obstacles list', () => {
it('does NOT render the list when user has no related obstacles', () => {
createComponent({ userDeletionObstacles: '[]' });

View File

@ -1080,6 +1080,16 @@ RSpec.describe User do
end
end
context 'strip attributes' do
context 'name' do
let(:user) { User.new(name: ' John Smith ') }
it 'strips whitespaces on validation' do
expect { user.valid? }.to change { user.name }.to('John Smith')
end
end
end
describe 'Respond to' do
it { is_expected.to respond_to(:admin?) }
it { is_expected.to respond_to(:name) }

View File

@ -740,17 +740,17 @@ module Ci
stub_feature_flags(ci_pending_builds_queue_source: true)
end
context 'with ci_queueing_denormalize_shared_runners_information enabled' do
context 'with ci_queuing_use_denormalized_data_strategy enabled' do
before do
stub_feature_flags(ci_queueing_denormalize_shared_runners_information: true)
stub_feature_flags(ci_queuing_use_denormalized_data_strategy: true)
end
include_examples 'handles runner assignment'
end
context 'with ci_queueing_denormalize_shared_runners_information disabled' do
context 'with ci_queuing_use_denormalized_data_strategy disabled' do
before do
stub_feature_flags(ci_queueing_denormalize_shared_runners_information: false)
stub_feature_flags(ci_queuing_use_denormalized_data_strategy: false)
end
around do |example|
@ -762,37 +762,9 @@ module Ci
include_examples 'handles runner assignment'
end
context 'with ci_queueing_denormalize_tags_information enabled' do
context 'with ci_queuing_use_denormalized_data_strategy enabled' do
before do
stub_feature_flags(ci_queueing_denormalize_tags_information: true)
end
include_examples 'handles runner assignment'
end
context 'with ci_queueing_denormalize_tags_information disabled' do
before do
stub_feature_flags(ci_queueing_denormalize_tags_information: false)
end
around do |example|
allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/332952') do
example.run
end
end
include_examples 'handles runner assignment'
end
context 'with ci_queueing_denormalize_namespace_traversal_ids disabled' do
before do
stub_feature_flags(ci_queueing_denormalize_namespace_traversal_ids: false)
end
around do |example|
allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/332952') do
example.run
end
stub_feature_flags(ci_queuing_use_denormalized_data_strategy: true)
end
include_examples 'handles runner assignment'

View File

@ -55,32 +55,16 @@ RSpec.describe Projects::DestroyService, :aggregate_failures do
.and change { Ci::Pipeline.count }.by(-1)
end
context 'with ci_optimize_project_records_destruction disabled' do
stub_feature_flags(ci_optimize_project_records_destruction: false)
it 'avoids N+1 queries' do
recorder = ActiveRecord::QueryRecorder.new { destroy_project(project, user, {}) }
it 'avoids N+1 queries' do
recorder = ActiveRecord::QueryRecorder.new { destroy_project(project, user, {}) }
project = create(:project, :repository, namespace: user.namespace)
pipeline = create(:ci_pipeline, project: project)
builds = create_list(:ci_build, 3, :artifacts, pipeline: pipeline)
create(:ci_pipeline_artifact, pipeline: pipeline)
create_list(:ci_build_trace_chunk, 3, build: builds[0])
project = create(:project, :repository, namespace: user.namespace)
pipeline = create(:ci_pipeline, project: project)
builds = create_list(:ci_build, 3, :artifacts, pipeline: pipeline)
create_list(:ci_build_trace_chunk, 3, build: builds[0])
expect { destroy_project(project, project.owner, {}) }.not_to exceed_query_limit(recorder)
end
end
context 'with ci_optimize_project_records_destruction enabled' do
it 'avoids N+1 queries' do
recorder = ActiveRecord::QueryRecorder.new { destroy_project(project, user, {}) }
project = create(:project, :repository, namespace: user.namespace)
pipeline = create(:ci_pipeline, project: project)
builds = create_list(:ci_build, 3, :artifacts, pipeline: pipeline)
create_list(:ci_build_trace_chunk, 3, build: builds[0])
expect { destroy_project(project, project.owner, {}) }.not_to exceed_query_limit(recorder)
end
expect { destroy_project(project, project.owner, {}) }.not_to exceed_query_limit(recorder)
end
it_behaves_like 'deleting the project'
@ -116,11 +100,11 @@ RSpec.describe Projects::DestroyService, :aggregate_failures do
destroy_project(project, user, {})
end
context 'with running pipelines to be aborted' do
context 'with running pipelines' do
let!(:pipelines) { create_list(:ci_pipeline, 3, :running, project: project) }
let(:destroy_pipeline_service) { double('DestroyPipelineService', execute: nil) }
it 'executes DestroyPipelineService for project ci pipelines' do
it 'bulks-fails with AbortPipelineService and then executes DestroyPipelineService for each pipelines' do
allow(::Ci::DestroyPipelineService).to receive(:new).and_return(destroy_pipeline_service)
expect(::Ci::AbortPipelinesService)
@ -128,33 +112,11 @@ RSpec.describe Projects::DestroyService, :aggregate_failures do
.with(project.all_pipelines, :project_deleted)
pipelines.each do |pipeline|
expect(destroy_pipeline_service)
.to receive(:execute)
.with(pipeline)
expect(destroy_pipeline_service).to receive(:execute).with(pipeline)
end
destroy_project(project, user, {})
end
context 'with ci_optimize_project_records_destruction disabled' do
before do
stub_feature_flags(ci_optimize_project_records_destruction: false)
end
it 'bulk-fails project ci pipelines' do
expect(::Ci::AbortPipelinesService)
.to receive_message_chain(:new, :execute)
.with(project.all_pipelines, :project_deleted)
destroy_project(project, user, {})
end
it 'does not destroy CI records via DestroyPipelineService' do
expect(::Ci::DestroyPipelineService).not_to receive(:new)
destroy_project(project, user, {})
end
end
end
context 'when project has remote mirrors' do