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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-12-05 06:13:51 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-12-05 06:13:51 +0300
commitc20abe491ceeb1b8e1350f18f0c91e0a31c73cb5 (patch)
treeb8f9c5888b0ec18b24eb49f790a253ddc7905f1a
parent35850d3d1643a9e2c5328f45b8a9026ac3d86e35 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue20
-rw-r--r--doc/administration/auditor_users.md2
-rw-r--r--doc/administration/backup_restore/index.md168
-rw-r--r--doc/administration/gitaly/configure_gitaly.md47
-rw-r--r--doc/administration/settings/gitaly_timeouts.md70
-rw-r--r--doc/development/mass_insert.md2
-rw-r--r--doc/user/compliance/compliance_center/index.md17
-rw-r--r--doc/user/project/repository/monorepos/index.md2
-rw-r--r--locale/gitlab.pot50
-rw-r--r--spec/frontend/fixtures/merge_requests.rb8
-rw-r--r--spec/frontend/vue_merge_request_widget/components/approvals/approvals_spec.js60
-rw-r--r--spec/lib/gitlab/utils/file_info_spec.rb4
-rw-r--r--spec/requests/api/merge_request_approvals_spec.rb2
-rw-r--r--spec/services/merge_requests/approval_service_spec.rb1
15 files changed, 365 insertions, 90 deletions
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 0b564deaff7..29ada2ea395 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-251acb8c75aa66481893bf775a44cba669ccc3c9
+c0b07ba36fc8fc40830f061cb55a5c951a166e1c
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue b/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue
index a29393d9f93..524f2c045e6 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/approvals/approvals.vue
@@ -1,6 +1,7 @@
<script>
import { GlButton, GlSprintf } from '@gitlab/ui';
import { createAlert } from '~/alert';
+import { visitUrl } from '~/lib/utils/url_utility';
import { STATUS_MERGED } from '~/issues/constants';
import { BV_SHOW_MODAL } from '~/lib/utils/constants';
import { HTTP_STATUS_UNAUTHORIZED } from '~/lib/utils/http_status';
@@ -114,6 +115,13 @@ export default {
return this.userHasApproved && !this.userCanApprove && this.mr.state !== STATUS_MERGED;
},
approvalText() {
+ // Repeating a text of this to keep i18n easier to do (vs, construcing a compound string)
+ if (this.requireSamlAuthToApprove) {
+ return this.isApproved && this.approvedBy.length > 0
+ ? s__('mrWidget|Approve additionally with SAML')
+ : s__('mrWidget|Approve with SAML');
+ }
+
return this.isApproved && this.approvedBy.length > 0
? s__('mrWidget|Approve additionally')
: s__('mrWidget|Approve');
@@ -161,14 +169,20 @@ export default {
.join(', ')
.concat('.');
},
+ requireSamlAuthToApprove() {
+ return this.mr.requireSamlAuthToApprove;
+ },
},
methods: {
approve() {
+ if (this.requireSamlAuthToApprove) {
+ this.approveWithSamlAuth();
+ return;
+ }
if (this.requirePasswordToApprove) {
this.$root.$emit(BV_SHOW_MODAL, this.modalId);
return;
}
-
this.updateApproval(
() => this.service.approveMergeRequest(),
() =>
@@ -179,6 +193,10 @@ export default {
),
);
},
+ approveWithSamlAuth() {
+ // Intentionally direct to SAML Identity Provider for renewed authorization even if SSO session exists
+ visitUrl(this.mr.samlApprovalPath);
+ },
approveWithAuth(data) {
this.updateApproval(
() => this.service.approveMergeRequestWithAuth(data),
diff --git a/doc/administration/auditor_users.md b/doc/administration/auditor_users.md
index 0355f7a3661..f57d09f79b8 100644
--- a/doc/administration/auditor_users.md
+++ b/doc/administration/auditor_users.md
@@ -35,7 +35,7 @@ To create a new user account with auditor access (or change an existing user):
To create a user account with auditor access:
1. On the left sidebar, at the bottom, select **Admin Area**.
-1. On the left sidebar, select **Overview > Users**.
+1. Select **Overview > Users**.
1. Create a new user or edit an existing one. Set **Access Level** to **Auditor**.
1. If you created a user, select **Create user**. For an existing user, select **Save changes**.
diff --git a/doc/administration/backup_restore/index.md b/doc/administration/backup_restore/index.md
index cf7c5c3db9a..d8ee58e42d7 100644
--- a/doc/administration/backup_restore/index.md
+++ b/doc/administration/backup_restore/index.md
@@ -36,6 +36,174 @@ methods to export or back up your data yourself from GitLab.com.
Issues are stored in the database, and can't be stored in Git itself.
+## GitLab backup archive creation process
+
+When working with GitLab backups, you might need to know how GitLab creates backup archives. To create backup archives, GitLab:
+
+1. If creating an incremental backup, extracts the previous backup archive and read its `backup_information.yml` file.
+1. Updates or generates the `backup_information.yml` file.
+1. Runs all backup sub-tasks:
+ - `db` to backup the GitLab PostgreSQL database (not Gitaly Cluster).
+ - `repositories` to back up Git repositories.
+ - `uploads` to back up attachments.
+ - `builds` to back up CI job output logs.
+ - `artifacts` to back up CI job artifacts.
+ - `pages` to back up page content.
+ - `lfs` to back up LFS objects.
+ - `terraform_state` to back up Terraform states.
+ - `registry` to back up container registry images.
+ - `packages` to back up packages.
+ - `ci_secure_files` to back up project-level secure files.
+1. Archives the backup staging area into a tar file.
+1. Optional. Uploads the new backup archive to object-storage.
+1. Cleans up backup staging directory files that are now archived.
+
+## Backup staging directory
+
+The backup staging directory is a place to temporarily:
+
+- Store backup artifacts on disk before the GitLab backup archive is created.
+- Extract backup archives on disk before restoring a backup or creating an incremental backup.
+
+This directory is the same directory where completed GitLab backup archives are created. When creating an untarred backup, the backup artifacts are left in this directory and no
+archive is created.
+
+Example backup staging directory with untarred backup:
+
+```plaintext
+backups/
+├── 1701728344_2023_12_04_16.7.0-pre_gitlab_backup.tar
+├── 1701728447_2023_12_04_16.7.0-pre_gitlab_backup.tar
+├── artifacts.tar.gz
+├── backup_information.yml
+├── builds.tar.gz
+├── ci_secure_files.tar.gz
+├── db
+│ ├── ci_database.sql.gz
+│ └── database.sql.gz
+├── lfs.tar.gz
+├── packages.tar.gz
+├── pages.tar.gz
+├── repositories
+│ ├── manifests/
+│ ├── @hashed/
+│ └── @snippets/
+├── terraform_state.tar.gz
+└── uploads.tar.gz
+```
+
+## `backup_information.yml` file
+
+The `backup_information.yml` file saves all backup inputs that are not included in the backup itself. It includes information such as:
+
+- The time the backup was created.
+- The version of GitLab that generated the backup.
+- Any options that were specified, such as skipped sub-tasks.
+
+This information is used by some sub-tasks to determine how:
+
+- To restore.
+- To link data in the backup with external services (such as server-side repository backups).
+
+This file is saved into the backup staging directory.
+
+## Database backups
+
+Database backups are created and restored by a GitLab backup sub-task called `db`. The database sub-task uses `pg_dump` to create [a SQL dump](https://www.postgresql.org/docs/14/backup-dump.html). The output of `pg_dump` is piped through `gzip` in order to create a compressed SQL file. This file is saved to the backup staging directory.
+
+## Repository backups
+
+Repository backups are created and restored by a GitLab backup sub-task called `repositories`. The repositories sub-task uses a Gitaly command
+[`gitaly-backup`](https://gitlab.com/gitlab-org/gitaly/-/blob/master/doc/gitaly-backup.md) to create Git repository backups:
+
+- GitLab uses its database to tell `gitaly-backup` which repositories to back up.
+- `gitaly-backup` then calls a series of RPCs on Gitaly to collect the repository backup data for each repository. This data is streamed into a directory structure in the GitLab backup staging directory.
+
+```mermaid
+sequenceDiagram
+ box Backup host
+ participant Repositories sub-task
+ participant gitaly-backup
+ end
+
+ Repositories sub-task->>+gitaly-backup: List of repositories
+
+ loop Each repository
+ gitaly-backup->>+Gitaly: ListRefs request
+ Gitaly->>-gitaly-backup: List of Git references
+
+ gitaly-backup->>+Gitaly: CreateBundleFromRefList request
+ Gitaly->>-gitaly-backup: Git bundle file
+
+ gitaly-backup->>+Gitaly: GetCustomHooks request
+ Gitaly->>-gitaly-backup: Custom hooks archive
+ end
+
+ gitaly-backup->>-Repositories sub-task: Success/failure
+```
+
+Storages configured to Gitaly Cluster are backed up the same as standalone Gitaly. When Gitaly Cluster receives the RPC calls from `gitaly-backup`, it is responsible for
+rebuilding its own database. This means that there is no need to backup the Gitaly Cluster database separately. Because backups operate through RPCs, each repository is only backed
+up once no matter the replication factor.
+
+### Server-side repository backups
+
+You can configure repository backups as server-side repository backups. When specified, `gitaly-backup` makes a single RPC call for each repository to create the backup. This RPC
+does not transmit any repository data. Instead, the RPC triggers the Gitaly node that stores that physical repository to upload the backup data directly to object-storage. Because
+the data is no longer transmitted through RPCs from Gitaly, server-side backups require much less network transfer and require no disk storage on the machine that is running the
+backup Rake task. The backups stored on object-storage are linked to the created backup archive by [the backup name](backup_gitlab.md#backup-timestamp).
+
+```mermaid
+sequenceDiagram
+ box Backup host
+ participant Repositories sub-task
+ participant gitaly-backup
+ end
+
+ Repositories sub-task->>+gitaly-backup: List of repositories
+
+ loop Each repository
+ gitaly-backup->>+Gitaly: BackupRepository request
+
+ Gitaly->>+Object-storage: Git references file
+ Object-storage->>-Gitaly: Success/failure
+
+ Gitaly->>+Object-storage: Git bundle file
+ Object-storage->>-Gitaly: Success/failure
+
+ Gitaly->>+Object-storage: Custom hooks archive
+ Object-storage->>-Gitaly: Success/failure
+
+ Gitaly->>+Object-storage: Backup manifest file
+ Object-storage->>-Gitaly: Success/failure
+
+ Gitaly->>-gitaly-backup: Success/failure
+ end
+
+ gitaly-backup->>-Repositories sub-task: Success/failure
+```
+
+## File backups
+
+The following GitLab backup sub-tasks back up files:
+
+- `uploads`
+- `builds`
+- `artifacts`
+- `pages`
+- `lfs`
+- `terraform_state`
+- `registry`
+- `packages`
+- `ci_secure_files`
+
+These file sub-tasks determine a set of files within a directory specific to the task. This set of files is then passed to `tar`
+to create an archive. This archive is piped (not saved to disk) through `gzip` to save a compressed tar file to the backup staging directory.
+
+Because backups are created from live instances, the files that tar is trying to archive can sometimes be modified while creating the backup. In this case, an alternate "copy"
+strategy can be used. When this strategy is used, `rsync` is first used to create a copy of the files to back up. Then, these copies are passed to `tar` as usual. In this case,
+the machine running the backup Rake task must have enough storage for the copied files and the compressed archive.
+
## Related features
- [Geo](../geo/index.md)
diff --git a/doc/administration/gitaly/configure_gitaly.md b/doc/administration/gitaly/configure_gitaly.md
index 891416a7deb..535e35cc012 100644
--- a/doc/administration/gitaly/configure_gitaly.md
+++ b/doc/administration/gitaly/configure_gitaly.md
@@ -1542,50 +1542,3 @@ go_cloud_url = "s3://gitaly-backups?region=minio&endpoint=my.minio.local:8080&di
```
::EndTabs
-
-## Configure negotiation timeouts
-
-> [Introduced](https://gitlab.com/gitlab-org/gitaly/-/issues/5574) in GitLab 16.5.
-
-Gitaly supports configurable negotiation timeouts.
-
-Negotiation timeouts can be configured for the `git-upload-pack(1)` and `git-upload-archive(1)`
-operations, which are invoked by a Gitaly node when you execute the `git fetch` and
-`git archive --remote` commands respectively. You might need to increase the negotiation timeout:
-
-- For particularly large repositories.
-- When performing these commands in parallel.
-
-These timeouts affect only the [negotiation phase](https://git-scm.com/docs/pack-protocol/2.2.3#_packfile_negotiation) of
-remote Git operations, not the entire transfer.
-
-Valid values for timeouts follow the format of [`ParseDuration`](https://pkg.go.dev/time#ParseDuration) in Go.
-
-How you configure negotiation timeouts depends on the type of installation you have:
-
-::Tabs
-
-:::TabTitle Linux package (Omnibus)
-
-Edit `/etc/gitlab/gitlab.rb`:
-
-```ruby
-gitaly['configuration'] = {
- timeout: {
- upload_pack_negotiation: '10m', # 10 minutes
- upload_archive_negotiation: '20m', # 20 minutes
- }
-}
-```
-
-:::TabTitle Self-compiled (source)
-
-Edit `/home/git/gitaly/config.toml`:
-
-```toml
-[timeout]
-upload_pack_negotiation = "10m"
-upload_archive_negotiation = "20m"
-```
-
-::EndTabs
diff --git a/doc/administration/settings/gitaly_timeouts.md b/doc/administration/settings/gitaly_timeouts.md
index b60cf141cf6..93db0467d70 100644
--- a/doc/administration/settings/gitaly_timeouts.md
+++ b/doc/administration/settings/gitaly_timeouts.md
@@ -6,23 +6,75 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Gitaly timeouts **(FREE SELF)**
-[Gitaly](../gitaly/index.md) timeouts are configurable. The timeouts can be
-configured to make sure that long-running Gitaly calls don't needlessly take up resources.
+[Gitaly](../gitaly/index.md) provides two types of configurable timeouts:
-To access Gitaly timeout settings:
+- Call timeouts, configured by using the GitLab UI.
+- Negotiation timeouts, configured by using Gitaly configuration files.
+
+## Configure the call timeouts
+
+Configure the following call timeouts to make sure that long-running Gitaly calls don't needlessly take up resources. To
+configure the call timeouts:
1. On the left sidebar, at the bottom, select **Admin Area**.
1. Select **Settings > Preferences**.
1. Expand the **Gitaly timeouts** section.
+1. Set each timeout as required.
-## Available timeouts
+### Available call timeouts
-The following timeouts are available.
+Different call timeouts are available for different Gitaly operations.
| Timeout | Default | Description |
|:--------|:-----------|:------------|
-| Default | 55 seconds | Timeout for most Gitaly calls (not enforced for `git` `fetch` and `push` operations, or Sidekiq jobs). For example, checking if a repository exists on disk. Makes sure that Gitaly calls made within a web request cannot exceed the entire request timeout. It should be shorter than the [worker timeout](../operations/puma.md#change-the-worker-timeout) that can be configured for [Puma](../../install/requirements.md#puma-settings). If a Gitaly call timeout exceeds the worker timeout, the remaining time from the worker timeout is used to avoid having to terminate the worker. |
-| Fast | 10 seconds | Timeout for fast Gitaly operations used within requests, sometimes multiple times. For example, checking if a repository exists on disk. If fast operations exceed this threshold, there may be a problem with a storage shard. Failing fast can help maintain the stability of the GitLab instance. |
-| Medium | 30 seconds | Timeout for Gitaly operations that should be fast (possibly within requests) but preferably not used multiple times within a request. For example, loading blobs. Timeout that should be set between Default and Fast. |
+| Default | 55 seconds | Timeout for most Gitaly calls (not enforced for `git` `fetch` and `push` operations, or Sidekiq jobs). For example, checking if a repository exists on disk. Makes sure that Gitaly calls made in a web request cannot exceed the entire request timeout. It should be shorter than the [worker timeout](../operations/puma.md#change-the-worker-timeout) that can be configured for [Puma](../../install/requirements.md#puma-settings). If a Gitaly call timeout exceeds the worker timeout, the remaining time from the worker timeout is used to avoid having to terminate the worker. |
+| Fast | 10 seconds | Timeout for fast Gitaly operations used in requests, sometimes multiple times. For example, checking if a repository exists on disk. If fast operations exceed this threshold, there may be a problem with a storage shard. Failing fast can help maintain the stability of the GitLab instance. |
+| Medium | 30 seconds | Timeout for Gitaly operations that should be fast (possibly in requests) but preferably not used multiple times in a request. For example, loading blobs. Timeout that should be set between Default and Fast. |
+
+## Configure the negotiation timeouts
+
+> [Introduced](https://gitlab.com/gitlab-org/gitaly/-/issues/5574) in GitLab 16.5.
+
+You might need to increase the negotiation timeout:
+
+- For particularly large repositories.
+- When performing these commands in parallel.
+
+You can configure negotiation timeouts for:
+
+- `git-upload-pack(1)`, which is invoked by a Gitaly node when you execute `git fetch`.
+- `git-upload-archive(1)`, which is invoked by a Gitaly node when you execute `git archive --remote`.
+
+To configure these timeouts:
+
+::Tabs
+
+:::TabTitle Linux package (Omnibus)
+
+Edit `/etc/gitlab/gitlab.rb`:
+
+```ruby
+gitaly['configuration'] = {
+ timeout: {
+ upload_pack_negotiation: '10m', # 10 minutes
+ upload_archive_negotiation: '20m', # 20 minutes
+ }
+}
+```
+
+:::TabTitle Self-compiled (source)
+
+Edit `/home/git/gitaly/config.toml`:
+
+```toml
+[timeout]
+upload_pack_negotiation = "10m"
+upload_archive_negotiation = "20m"
+```
+
+::EndTabs
+
+For the values, use the format of [`ParseDuration`](https://pkg.go.dev/time#ParseDuration) in Go.
-You can also [configure negotiation timeouts](../gitaly/configure_gitaly.md#configure-negotiation-timeouts).
+These timeouts affect only the [negotiation phase](https://git-scm.com/docs/pack-protocol/2.2.3#_packfile_negotiation) of
+remote Git operations, not the entire transfer.
diff --git a/doc/development/mass_insert.md b/doc/development/mass_insert.md
index e16f162abfa..412639927a7 100644
--- a/doc/development/mass_insert.md
+++ b/doc/development/mass_insert.md
@@ -15,5 +15,5 @@ the following snippet in the rails console.
```ruby
u = User.find(1)
-Project.last(100).each { |p| p.set_timestamps_for_create && p.add_maintainer(u, current_user: u) } # Change 100 to whatever number of projects you need access to
+Project.last(100).each { |p| p.send(:set_timestamps_for_create) && p.add_maintainer(u, current_user: u) } # Change 100 to whatever number of projects you need access to
```
diff --git a/doc/user/compliance/compliance_center/index.md b/doc/user/compliance/compliance_center/index.md
index 0f2cce67721..df1883f95d9 100644
--- a/doc/user/compliance/compliance_center/index.md
+++ b/doc/user/compliance/compliance_center/index.md
@@ -188,8 +188,8 @@ To export a report of merge request compliance violations for projects in a grou
1. On the left sidebar, select **Search or go to** and find your group.
1. On the left sidebar, select **Secure > Compliance center**.
-1. On the page, select the **Violations** tab.
-1. On the Violations tab, select the **Export full report as CSV** action in the top right corner
+1. Select the **Export** action in the top right corner
+1. Select **Export violations report**
A report is compiled and delivered to your email inbox as an attachment.
@@ -235,7 +235,8 @@ To generate the Chain of Custody report:
1. On the left sidebar, select **Search or go to** and find your group.
1. On the left sidebar, select **Secure > Compliance center**.
-1. Select **List of all merge commits**.
+1. Select the **Export** action in the top right corner
+1. Select **Export chain of custody report**
Depending on your version of GitLab, the Chain of Custody report is either sent through email or available for download.
@@ -251,9 +252,9 @@ To generate a commit-specific Chain of Custody report:
1. On the left sidebar, select **Search or go to** and find your group.
1. On the left sidebar, select **Secure > Compliance center**.
-1. At the top of the compliance report, to the right of **List of all commits**, select the down arrow
- (**{chevron-lg-down}**).
-1. Enter the commit SHA, and then select **Export commit custody report**.
+1. Select the **Export** action in the top right corner
+1. Select **Export custody report of a specific commit**
+1. Enter the commit SHA, and then select **Export custody report**.
Depending on your version of GitLab, the Chain of Custody report is either sent through email or available for download.
@@ -358,8 +359,8 @@ To export a report of compliance frameworks on projects in a group:
1. On the left sidebar, select **Search or go to** and find your group.
1. On the left sidebar, select **Secure > Compliance center**.
-1. On the page, select the **Projects** tab.
-1. On the Frameworks tab, select the **Export as CSV** action in the top right corner
+1. Select the **Export** action in the top right corner
+1. Select **Export list of project frameworks**
A report is compiled and delivered to your email inbox as an attachment.
diff --git a/doc/user/project/repository/monorepos/index.md b/doc/user/project/repository/monorepos/index.md
index 144f46cd7d5..b73757a952e 100644
--- a/doc/user/project/repository/monorepos/index.md
+++ b/doc/user/project/repository/monorepos/index.md
@@ -189,7 +189,7 @@ You might experience a `fatal: the remote end hung up unexpectedly` error when a
- The same large repository in parallel.
You can attempt to mitigate this issue by increasing the default negotiation timeout values. For more information, see
-[Configure negotiation timeouts](../../../../administration/gitaly/configure_gitaly.md#configure-negotiation-timeouts).
+[Configure the negotiation timeouts](../../../../administration/settings/gitaly_timeouts.md#configure-the-negotiation-timeouts).
## Optimize your repository
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index aa789f786a3..b6cafab7c4d 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -1439,9 +1439,6 @@ msgstr ""
msgid "(leave blank if you don't want to change it)"
msgstr ""
-msgid "(max size 15 MB)"
-msgstr ""
-
msgid "(no user)"
msgstr ""
@@ -6111,6 +6108,9 @@ msgstr ""
msgid "Approval options"
msgstr ""
+msgid "Approval rejected."
+msgstr ""
+
msgid "Approval rules"
msgstr ""
@@ -6272,7 +6272,7 @@ msgstr ""
msgid "ApprovalSettings|Remove approvals by Code Owners if their files changed"
msgstr ""
-msgid "ApprovalSettings|Require user password to approve"
+msgid "ApprovalSettings|Require user re-authentication (password or SAML) to approve"
msgstr ""
msgid "ApprovalSettings|There was an error loading merge request approval settings."
@@ -12429,13 +12429,34 @@ msgstr ""
msgid "Completed in %{duration_seconds} seconds (%{relative_time})"
msgstr ""
-msgid "Compliance Center|Export full report as CSV"
+msgid "Compliance Center Export|(limited to 15 MB)"
+msgstr ""
+
+msgid "Compliance Center Export|Example: 2dc6aa3"
+msgstr ""
+
+msgid "Compliance Center Export|Export as CSV"
+msgstr ""
+
+msgid "Compliance Center Export|Export chain of custody report"
+msgstr ""
+
+msgid "Compliance Center Export|Export custody report"
+msgstr ""
+
+msgid "Compliance Center Export|Export custody report of a specific commit"
msgstr ""
-msgid "Compliance Center|Export merge request violations as CSV. You will be emailed after the export is processed."
+msgid "Compliance Center Export|Export list of project frameworks"
msgstr ""
-msgid "Compliance Center|Export projects as CSV. You will be emailed after the export is processed."
+msgid "Compliance Center Export|Export violations report"
+msgstr ""
+
+msgid "Compliance Center Export|Invalid hash"
+msgstr ""
+
+msgid "Compliance Center Export|Send email of the chosen report as CSV"
msgstr ""
msgid "Compliance Center|Frameworks"
@@ -19975,9 +19996,6 @@ msgstr ""
msgid "Export as CSV"
msgstr ""
-msgid "Export commit custody report"
-msgstr ""
-
msgid "Export group"
msgstr ""
@@ -25935,9 +25953,6 @@ msgstr ""
msgid "Invalid format selected"
msgstr ""
-msgid "Invalid hash"
-msgstr ""
-
msgid "Invalid input, please avoid emoji"
msgstr ""
@@ -28695,9 +28710,6 @@ msgstr ""
msgid "List available repositories"
msgstr ""
-msgid "List of all commits"
-msgstr ""
-
msgid "List of suitable GCP locations"
msgstr ""
@@ -57854,6 +57866,12 @@ msgstr ""
msgid "mrWidget|Approve additionally"
msgstr ""
+msgid "mrWidget|Approve additionally with SAML"
+msgstr ""
+
+msgid "mrWidget|Approve with SAML"
+msgstr ""
+
msgid "mrWidget|Approved by"
msgstr ""
diff --git a/spec/frontend/fixtures/merge_requests.rb b/spec/frontend/fixtures/merge_requests.rb
index a1896a6470b..e8272a1f93a 100644
--- a/spec/frontend/fixtures/merge_requests.rb
+++ b/spec/frontend/fixtures/merge_requests.rb
@@ -2,7 +2,13 @@
require 'spec_helper'
-RSpec.describe Projects::MergeRequestsController, '(JavaScript fixtures)', type: :controller do
+RSpec
+ .describe(
+ Projects::MergeRequestsController,
+ '(JavaScript fixtures)',
+ type: :controller,
+ feature_category: :code_review_workflow
+ ) do
include JavaScriptFixturesHelpers
let(:namespace) { create(:namespace, name: 'frontend-fixtures') }
diff --git a/spec/frontend/vue_merge_request_widget/components/approvals/approvals_spec.js b/spec/frontend/vue_merge_request_widget/components/approvals/approvals_spec.js
index 2aed037be6f..c81f4328d2a 100644
--- a/spec/frontend/vue_merge_request_widget/components/approvals/approvals_spec.js
+++ b/spec/frontend/vue_merge_request_widget/components/approvals/approvals_spec.js
@@ -4,6 +4,7 @@ import { GlButton, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { createMockSubscription as createMockApolloSubscription } from 'mock-apollo-client';
import approvedByCurrentUser from 'test_fixtures/graphql/merge_requests/approvals/approvals.query.graphql.json';
+import { visitUrl } from '~/lib/utils/url_utility';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
@@ -28,6 +29,10 @@ jest.mock('~/alert', () => ({
dismiss: mockAlertDismiss,
})),
}));
+jest.mock('~/lib/utils/url_utility', () => ({
+ ...jest.requireActual('~/lib/utils/url_utility'),
+ visitUrl: jest.fn(),
+}));
const TEST_HELP_PATH = 'help/path';
const testApprovedBy = () => [1, 7, 10].map((id) => ({ id }));
@@ -113,6 +118,7 @@ describe('MRWidget approvals', () => {
targetProjectFullPath: 'gitlab-org/gitlab',
id: 1,
iid: '1',
+ requireSamlAuthToApprove: false,
};
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
@@ -172,6 +178,22 @@ describe('MRWidget approvals', () => {
category: 'primary',
});
});
+
+ describe('with SAML auth requried for approval', () => {
+ beforeEach(async () => {
+ const response = createCanApproveResponse();
+ mr.requireSamlAuthToApprove = true;
+ createComponent({}, { query: response });
+ await waitForPromises();
+ });
+ it('approve action is rendered with correct text', () => {
+ expect(findActionData()).toEqual({
+ variant: 'confirm',
+ text: 'Approve with SAML',
+ category: 'primary',
+ });
+ });
+ });
});
describe('and MR is approved', () => {
@@ -194,6 +216,25 @@ describe('MRWidget approvals', () => {
});
});
+ describe('with approvers, with SAML auth requried for approval', () => {
+ beforeEach(async () => {
+ canApproveResponse.data.project.mergeRequest.approvedBy.nodes =
+ approvedByCurrentUser.data.project.mergeRequest.approvedBy.nodes;
+ canApproveResponse.data.project.mergeRequest.approvedBy.nodes[0].id = 69;
+ mr.requireSamlAuthToApprove = true;
+ createComponent({}, { query: canApproveResponse });
+ await waitForPromises();
+ });
+
+ it('approve additionally action is rendered with correct text', () => {
+ expect(findActionData()).toEqual({
+ variant: 'confirm',
+ text: 'Approve additionally with SAML',
+ category: 'secondary',
+ });
+ });
+ });
+
describe('with approvers', () => {
beforeEach(async () => {
canApproveResponse.data.project.mergeRequest.approvedBy.nodes =
@@ -215,6 +256,25 @@ describe('MRWidget approvals', () => {
});
});
+ describe('when SAML auth is required and user clicks Approve with SAML', () => {
+ const fakeGroupSamlPath = '/example_group_saml';
+
+ beforeEach(async () => {
+ mr.requireSamlAuthToApprove = true;
+ mr.samlApprovalPath = fakeGroupSamlPath;
+
+ createComponent({}, { query: createCanApproveResponse() });
+ await waitForPromises();
+ });
+
+ it('redirects the user to the group SAML path', async () => {
+ const action = findAction();
+ action.vm.$emit('click');
+ await nextTick();
+ expect(visitUrl).toHaveBeenCalledWith(fakeGroupSamlPath);
+ });
+ });
+
describe('when approve action is clicked', () => {
beforeEach(async () => {
createComponent({}, { query: canApproveResponse });
diff --git a/spec/lib/gitlab/utils/file_info_spec.rb b/spec/lib/gitlab/utils/file_info_spec.rb
index 480036b2fd0..1f52fcb48b6 100644
--- a/spec/lib/gitlab/utils/file_info_spec.rb
+++ b/spec/lib/gitlab/utils/file_info_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe Gitlab::Utils::FileInfo, feature_category: :shared do
describe '.linked?' do
it 'raises an error when file does not exist' do
- expect { subject.linked?('foo') }.to raise_error(Errno::ENOENT)
+ expect { subject.linked?("#{tmpdir}/foo") }.to raise_error(Errno::ENOENT)
end
shared_examples 'identifies a linked file' do
@@ -56,7 +56,7 @@ RSpec.describe Gitlab::Utils::FileInfo, feature_category: :shared do
describe '.shares_hard_link?' do
it 'raises an error when file does not exist' do
- expect { subject.shares_hard_link?('foo') }.to raise_error(Errno::ENOENT)
+ expect { subject.shares_hard_link?("#{tmpdir}/foo") }.to raise_error(Errno::ENOENT)
end
shared_examples 'identifies a file that shares a hard link' do
diff --git a/spec/requests/api/merge_request_approvals_spec.rb b/spec/requests/api/merge_request_approvals_spec.rb
index df2b20c62c3..2de59750273 100644
--- a/spec/requests/api/merge_request_approvals_spec.rb
+++ b/spec/requests/api/merge_request_approvals_spec.rb
@@ -8,8 +8,6 @@ RSpec.describe API::MergeRequestApprovals, feature_category: :source_code_manage
let_it_be(:bot) { create(:user, :project_bot) }
let_it_be(:project) { create(:project, :public, :repository, creator: user, namespace: user.namespace) }
let_it_be(:approver) { create :user }
- let_it_be(:group) { create :group }
-
let(:merge_request) { create(:merge_request, :simple, author: user, source_project: project) }
describe 'GET :id/merge_requests/:merge_request_iid/approvals' do
diff --git a/spec/services/merge_requests/approval_service_spec.rb b/spec/services/merge_requests/approval_service_spec.rb
index e7fe5c19fa3..8761aba432f 100644
--- a/spec/services/merge_requests/approval_service_spec.rb
+++ b/spec/services/merge_requests/approval_service_spec.rb
@@ -13,6 +13,7 @@ RSpec.describe MergeRequests::ApprovalService, feature_category: :code_review_wo
before do
project.add_developer(user)
+ stub_feature_flags ff_require_saml_auth_to_approve: false
end
context 'with invalid approval' do