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-07-22 03:10:34 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-07-22 03:10:34 +0300
commit0e6d9b66698db1e2e14e784fa9c601922e3f1a2c (patch)
treede82b854f1af5218d4ce0e880d119b7032541111
parent6333a892f50d882f007497fd5512a740ba1020e5 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/controllers/projects/issues_controller.rb2
-rw-r--r--app/controllers/projects/settings/ci_cd_controller.rb2
-rw-r--r--app/models/ci/build.rb2
-rw-r--r--app/models/project.rb7
-rw-r--r--app/uploaders/object_storage.rb7
-rw-r--r--app/views/projects/settings/ci_cd/_form.html.haml10
-rw-r--r--db/migrate/20230718111807_add_column_forward_deployment_rollback_allowed_to_ci_cd_setting.rb13
-rw-r--r--db/schema_migrations/202307181118071
-rw-r--r--db/structure.sql3
-rw-r--r--doc/administration/pages/index.md2
-rw-r--r--doc/api/groups.md1
-rw-r--r--doc/api/merge_request_approvals.md2
-rw-r--r--doc/api/projects.md7
-rw-r--r--doc/ci/environments/deployment_safety.md14
-rw-r--r--doc/ci/environments/index.md2
-rw-r--r--doc/ci/pipelines/settings.md1
-rw-r--r--doc/user/ai_features.md8
-rw-r--r--doc/user/project/pages/custom_domains_ssl_tls_certification/index.md12
-rw-r--r--lib/api/entities/project.rb1
-rw-r--r--lib/api/helpers/projects_helpers.rb2
-rw-r--r--locale/gitlab.pot16
-rw-r--r--spec/controllers/projects/settings/ci_cd_controller_spec.rb8
-rw-r--r--spec/factories/projects.rb1
-rw-r--r--spec/features/projects/settings/pipelines_settings_spec.rb22
-rw-r--r--spec/models/ci/build_spec.rb10
-rw-r--r--spec/models/project_spec.rb7
-rw-r--r--spec/requests/api/project_attributes.yml1
-rw-r--r--spec/requests/api/projects_spec.rb3
-rw-r--r--spec/uploaders/object_storage_spec.rb18
29 files changed, 144 insertions, 41 deletions
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 54bee16bb0c..44e55147181 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -52,7 +52,7 @@ class Projects::IssuesController < Projects::ApplicationController
push_frontend_feature_flag(:saved_replies, current_user)
push_frontend_feature_flag(:issues_grid_view)
push_frontend_feature_flag(:service_desk_ticket)
- push_frontend_feature_flag(:issues_list_drawer)
+ push_frontend_feature_flag(:issues_list_drawer, project)
end
before_action only: [:index, :show] do
diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb
index 0e892ef3faa..9a128adb926 100644
--- a/app/controllers/projects/settings/ci_cd_controller.rb
+++ b/app/controllers/projects/settings/ci_cd_controller.rb
@@ -88,7 +88,7 @@ module Projects
:build_timeout_human_readable, :public_builds, :ci_separated_caches,
:auto_cancel_pending_pipelines, :ci_config_path, :auto_rollback_enabled,
auto_devops_attributes: [:id, :domain, :enabled, :deploy_strategy],
- ci_cd_settings_attributes: [:default_git_depth, :forward_deployment_enabled]
+ ci_cd_settings_attributes: [:default_git_depth, :forward_deployment_enabled, :forward_deployment_rollback_allowed]
].tap do |list|
list << :max_artifacts_size if can?(current_user, :update_max_artifacts_size, project)
end
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index bb1bfe8c889..da70361743b 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -431,8 +431,8 @@ module Ci
def outdated_deployment?
strong_memoize(:outdated_deployment) do
deployment_job? &&
- incomplete? &&
project.ci_forward_deployment_enabled? &&
+ (!project.ci_forward_deployment_rollback_allowed? || incomplete?) &&
deployment&.older_than_last_successful_deployment?
end
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 9aeacf23ad9..d3642e7d7d0 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -508,6 +508,7 @@ class Project < ApplicationRecord
with_options prefix: :ci do
delegate :default_git_depth, :default_git_depth=
delegate :forward_deployment_enabled, :forward_deployment_enabled=
+ delegate :forward_deployment_rollback_allowed, :forward_deployment_rollback_allowed=
delegate :inbound_job_token_scope_enabled, :inbound_job_token_scope_enabled=
delegate :allow_fork_pipelines_to_run_in_parent_project, :allow_fork_pipelines_to_run_in_parent_project=
delegate :separated_caches, :separated_caches=
@@ -3048,6 +3049,12 @@ class Project < ApplicationRecord
ci_cd_settings.forward_deployment_enabled?
end
+ def ci_forward_deployment_rollback_allowed?
+ return false unless ci_cd_settings
+
+ ci_cd_settings.forward_deployment_rollback_allowed?
+ end
+
def ci_allow_fork_pipelines_to_run_in_parent_project?
return false unless ci_cd_settings
diff --git a/app/uploaders/object_storage.rb b/app/uploaders/object_storage.rb
index 672433ec534..a8328304e73 100644
--- a/app/uploaders/object_storage.rb
+++ b/app/uploaders/object_storage.rb
@@ -31,7 +31,8 @@ module ObjectStorage
# The direct_upload_final_path is defined which means
# file was uploaded to its final location so no need to move it.
# Now we delete the pending upload entry as the upload is considered complete.
- ObjectStorage::PendingDirectUpload.complete(@uploader.class.storage_location_identifier, file.path)
+ pending_upload_path = @uploader.class.without_bucket_prefix(file.path)
+ ObjectStorage::PendingDirectUpload.complete(@uploader.class.storage_location_identifier, pending_upload_path)
file
end
@@ -196,6 +197,10 @@ module ObjectStorage
File.join([object_store_options.bucket_prefix, path].compact)
end
+ def without_bucket_prefix(path)
+ Pathname.new(path).relative_path_from(object_store_options.bucket_prefix.to_s).to_s
+ end
+
def object_store_config
ObjectStorage::Config.new(object_store_options)
end
diff --git a/app/views/projects/settings/ci_cd/_form.html.haml b/app/views/projects/settings/ci_cd/_form.html.haml
index 6eccbd245af..d51acc5e708 100644
--- a/app/views/projects/settings/ci_cd/_form.html.haml
+++ b/app/views/projects/settings/ci_cd/_form.html.haml
@@ -1,6 +1,7 @@
- help_link_public_pipelines = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'change-which-users-can-view-your-pipelines'), target: '_blank', rel: 'noopener noreferrer'
- help_link_auto_canceling = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'auto-cancel-redundant-pipelines'), target: '_blank', rel: 'noopener noreferrer'
-- help_link_skip_outdated = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'prevent-outdated-deployment-jobs'), target: '_blank', rel: 'noopener noreferrer'
+- help_link_prevent_outdated = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'prevent-outdated-deployment-jobs'), target: '_blank', rel: 'noopener noreferrer'
+- help_link_prevent_outdated_allow_rollback = link_to sprite_icon('question-o'), help_page_path('ci/environments/deployment_safety', anchor: 'job-retries-for-rollback-deployments'), target: '_blank', rel: 'noopener noreferrer'
- help_link_separated_caches = link_to sprite_icon('question-o'), help_page_path('ci/caching/index', anchor: 'cache-key-names'), target: '_blank', rel: 'noopener noreferrer'
.row.gl-mt-3
@@ -23,7 +24,12 @@
.form-group
= f.fields_for :ci_cd_settings_attributes, @project.ci_cd_settings do |form|
= form.gitlab_ui_checkbox_component :forward_deployment_enabled, _("Prevent outdated deployment jobs"),
- help_text: (_('When a deployment job is successful, prevent older deployment jobs that are still pending.') + ' ' + help_link_skip_outdated).html_safe
+ help_text: (_('When a deployment job is successful, prevent older deployment jobs that are still pending.') + ' ' + help_link_prevent_outdated).html_safe
+ .gl-pl-6
+ = f.fields_for :ci_cd_settings_attributes, @project.ci_cd_settings do |form|
+ = form.gitlab_ui_checkbox_component :forward_deployment_rollback_allowed, _("Allow job retries for rollback deployments"),
+ help_text: (_('Allow job retries even if the deployment job is outdated.') + ' ' + help_link_prevent_outdated_allow_rollback).html_safe,
+ checkbox_options: { class: 'gl-pl-6' }
.form-group
= f.gitlab_ui_checkbox_component :ci_separated_caches,
diff --git a/db/migrate/20230718111807_add_column_forward_deployment_rollback_allowed_to_ci_cd_setting.rb b/db/migrate/20230718111807_add_column_forward_deployment_rollback_allowed_to_ci_cd_setting.rb
new file mode 100644
index 00000000000..cfa442f4861
--- /dev/null
+++ b/db/migrate/20230718111807_add_column_forward_deployment_rollback_allowed_to_ci_cd_setting.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddColumnForwardDeploymentRollbackAllowedToCiCdSetting < Gitlab::Database::Migration[2.1]
+ enable_lock_retries!
+
+ def up
+ add_column :project_ci_cd_settings, :forward_deployment_rollback_allowed, :boolean, default: true, null: false
+ end
+
+ def down
+ remove_column :project_ci_cd_settings, :forward_deployment_rollback_allowed
+ end
+end
diff --git a/db/schema_migrations/20230718111807 b/db/schema_migrations/20230718111807
new file mode 100644
index 00000000000..1c0f9dc33bf
--- /dev/null
+++ b/db/schema_migrations/20230718111807
@@ -0,0 +1 @@
+f4a6e21dcacd272de19ee33d4a47c522c819ab867523150b7e4687cfc0af574e \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 93d4451dab7..53a027cb5b5 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -20960,7 +20960,8 @@ CREATE TABLE project_ci_cd_settings (
runner_token_expiration_interval integer,
separated_caches boolean DEFAULT true NOT NULL,
allow_fork_pipelines_to_run_in_parent_project boolean DEFAULT true NOT NULL,
- inbound_job_token_scope_enabled boolean DEFAULT true NOT NULL
+ inbound_job_token_scope_enabled boolean DEFAULT true NOT NULL,
+ forward_deployment_rollback_allowed boolean DEFAULT true NOT NULL
);
CREATE SEQUENCE project_ci_cd_settings_id_seq
diff --git a/doc/administration/pages/index.md b/doc/administration/pages/index.md
index 726307229d6..db3e93e9f66 100644
--- a/doc/administration/pages/index.md
+++ b/doc/administration/pages/index.md
@@ -350,7 +350,7 @@ world. Custom domains are supported, but no TLS.
**Requirements:**
- [Wildcard DNS setup](#dns-configuration)
-- Wildcard TLS certificate
+- TLS certificate. Can be either Wildcard, or any other type meeting the [requirements](../../user/project/pages/custom_domains_ssl_tls_certification/index.md#manual-addition-of-ssltls-certificates).
- Secondary IP
---
diff --git a/doc/api/groups.md b/doc/api/groups.md
index 6c79ead3f9e..4599c211825 100644
--- a/doc/api/groups.md
+++ b/doc/api/groups.md
@@ -470,6 +470,7 @@ Example response:
"open_issues_count":10,
"ci_default_git_depth":50,
"ci_forward_deployment_enabled":true,
+ "ci_forward_deployment_rollback_allowed": true,
"ci_allow_fork_pipelines_to_run_in_parent_project":true,
"public_jobs":true,
"build_timeout":3600,
diff --git a/doc/api/merge_request_approvals.md b/doc/api/merge_request_approvals.md
index 6603a465a08..bb86ec54837 100644
--- a/doc/api/merge_request_approvals.md
+++ b/doc/api/merge_request_approvals.md
@@ -314,7 +314,7 @@ Supported attributes:
| `group_ids` | Array | **{dotted-circle}** No | The IDs of groups as approvers. |
| `protected_branch_ids` | Array | **{dotted-circle}** No | The IDs of protected branches to scope the rule by. To identify the ID, [use the API](protected_branches.md#list-protected-branches). |
| `report_type` | string | **{dotted-circle}** No | The report type required when the rule type is `report_approver`. The supported report types are `license_scanning` [(Deprecated in GitLab 15.9)](../update/deprecations.md#license-check-and-the-policies-tab-on-the-license-compliance-page) and `code_coverage`. |
-| `rule_type` | string | **{dotted-circle}** No | The type of rule. `any_approver` is a pre-configured default rule with `approvals_required` at `0`. Other rules are `regular`. |
+| `rule_type` | string | **{dotted-circle}** No | The type of rule. `any_approver` is a pre-configured default rule with `approvals_required` at `0`. Other rules are `regular` and `report_approver`. |
| `user_ids` | Array | **{dotted-circle}** No | The IDs of users as approvers. |
| `usernames` | string array | **{dotted-circle}** No | The usernames for this rule. |
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 813d0fe35cb..a31f5cb9024 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -233,6 +233,7 @@ When the user is authenticated and `simple` is not set this returns something li
"open_issues_count": 0,
"ci_default_git_depth": 20,
"ci_forward_deployment_enabled": true,
+ "ci_forward_deployment_rollback_allowed": true,
"ci_allow_fork_pipelines_to_run_in_parent_project": true,
"ci_job_token_scope_enabled": false,
"ci_separated_caches": true,
@@ -406,6 +407,7 @@ GET /users/:user_id/projects
"runners_token": "b8547b1dc37721d05889db52fa2f02",
"ci_default_git_depth": 50,
"ci_forward_deployment_enabled": true,
+ "ci_forward_deployment_rollback_allowed": true,
"ci_allow_fork_pipelines_to_run_in_parent_project": true,
"ci_separated_caches": true,
"public_jobs": true,
@@ -524,6 +526,7 @@ GET /users/:user_id/projects
"runners_token": "b8547b1dc37721d05889db52fa2f02",
"ci_default_git_depth": 0,
"ci_forward_deployment_enabled": true,
+ "ci_forward_deployment_rollback_allowed": true,
"ci_allow_fork_pipelines_to_run_in_parent_project": true,
"ci_separated_caches": true,
"public_jobs": true,
@@ -1193,6 +1196,7 @@ GET /projects/:id
"runners_token": "b8bc4a7a29eb76ea83cf79e4908c2b",
"ci_default_git_depth": 50,
"ci_forward_deployment_enabled": true,
+ "ci_forward_deployment_rollback_allowed": true,
"ci_allow_fork_pipelines_to_run_in_parent_project": true,
"ci_separated_caches": true,
"public_jobs": true,
@@ -1689,6 +1693,7 @@ Supported attributes:
| `ci_config_path` | string | **{dotted-circle}** No | The path to CI configuration file. |
| `ci_default_git_depth` | integer | **{dotted-circle}** No | Default number of revisions for [shallow cloning](../ci/pipelines/settings.md#limit-the-number-of-changes-fetched-during-clone). |
| `ci_forward_deployment_enabled` | boolean | **{dotted-circle}** No | Enable or disable [prevent outdated deployment jobs](../ci/pipelines/settings.md#prevent-outdated-deployment-jobs). |
+| `ci_forward_deployment_rollback_allowed` | boolean | **{dotted-circle}** No | Enable or disable [allow job retries for rollback deployments](../ci/pipelines/settings.md#prevent-outdated-deployment-jobs). |
| `ci_allow_fork_pipelines_to_run_in_parent_project` | boolean | **{dotted-circle}** No | Enable or disable [running pipelines in the parent project for merge requests from forks](../ci/pipelines/merge_request_pipelines.md#run-pipelines-in-the-parent-project). _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/325189) in GitLab 15.3.)_ |
| `ci_separated_caches` | boolean | **{dotted-circle}** No | Set whether or not caches should be [separated](../ci/caching/index.md#cache-key-names) by branch protection status. |
| `container_expiration_policy_attributes` | hash | **{dotted-circle}** No | Update the image cleanup policy for this project. Accepts: `cadence` (string), `keep_n` (integer), `older_than` (string), `name_regex` (string), `name_regex_delete` (string), `name_regex_keep` (string), `enabled` (boolean). |
@@ -2290,6 +2295,7 @@ Example response:
"runners_token": "b8bc4a7a29eb76ea83cf79e4908c2b",
"ci_default_git_depth": 50,
"ci_forward_deployment_enabled": true,
+ "ci_forward_deployment_rollback_allowed": true,
"ci_allow_fork_pipelines_to_run_in_parent_project": true,
"ci_separated_caches": true,
"public_jobs": true,
@@ -2421,6 +2427,7 @@ Example response:
"runners_token": "b8bc4a7a29eb76ea83cf79e4908c2b",
"ci_default_git_depth": 50,
"ci_forward_deployment_enabled": true,
+ "ci_forward_deployment_rollback_allowed": true,
"ci_allow_fork_pipelines_to_run_in_parent_project": true,
"ci_separated_caches": true,
"public_jobs": true,
diff --git a/doc/ci/environments/deployment_safety.md b/doc/ci/environments/deployment_safety.md
index e15e09b27c1..fdc28c247e3 100644
--- a/doc/ci/environments/deployment_safety.md
+++ b/doc/ci/environments/deployment_safety.md
@@ -93,15 +93,17 @@ When an older deployment job is manual, the play button is disabled with a messa
Job age is determined by the job start time, not the commit time, so a newer commit
can be prevented in some circumstances.
-### How to rollback to an outdated deployment
+### Job retries for rollback deployments
-> In GitLab 15.6, [rollback via job retry was introduced back](https://gitlab.com/gitlab-org/gitlab/-/issues/378359).
+> - Rollback via job retry [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/378359) in GitLab 15.6.
+> - Job retries for rollback deployments checkbox [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/410427) in GitLab 16.3.
-In some cases, you need to rollback to an outdated deployment.
-This feature explicitly allows rollback via [Environment Rollback](index.md#environment-rollback),
-so that you can quickly rollback in an urgent case.
+You might need to quickly roll back to a stable, outdated deployment.
+By default, pipeline job retries for [deployment rollback](index.md#environment-rollback) are enabled.
-Alternatively, you can run a new pipeline with a previous commit. It contains newer deployment jobs than the latest deployment.
+To disable pipeline retries, clear the **Allow job retries for rollback deployments** checkbox. You should disable pipeline retries in sensitive projects.
+
+When a rollback is required, you must run a new pipeline with a previous commit.
### Example
diff --git a/doc/ci/environments/index.md b/doc/ci/environments/index.md
index 689f92723ee..448bd72df54 100644
--- a/doc/ci/environments/index.md
+++ b/doc/ci/environments/index.md
@@ -355,7 +355,7 @@ To retry or rollback a deployment:
NOTE:
If you have [prevented outdated deployment jobs](deployment_safety.md#prevent-outdated-deployment-jobs) in your project,
the rollback buttons might be hidden or disabled.
-In this case, see [how to rollback to an outdated deployment](deployment_safety.md#how-to-rollback-to-an-outdated-deployment).
+In this case, see [job retries for rollback deployments](deployment_safety.md#job-retries-for-rollback-deployments).
### Environment URL
diff --git a/doc/ci/pipelines/settings.md b/doc/ci/pipelines/settings.md
index fe6c88c9c4d..e589720b6ff 100644
--- a/doc/ci/pipelines/settings.md
+++ b/doc/ci/pipelines/settings.md
@@ -98,6 +98,7 @@ To avoid this scenario:
1. Select **Settings > CI/CD**.
1. Expand **General pipelines**.
1. Select the **Prevent outdated deployment jobs** checkbox.
+1. Optional. Clear the **Allow job retries for rollback deployments** checkbox.
1. Select **Save changes**.
For more information, see [Deployment safety](../environments/deployment_safety.md#prevent-outdated-deployment-jobs).
diff --git a/doc/user/ai_features.md b/doc/user/ai_features.md
index 35a0c33931a..e273c202520 100644
--- a/doc/user/ai_features.md
+++ b/doc/user/ai_features.md
@@ -151,15 +151,11 @@ Only the last 50 messages in the chat history are retained. The chat history exp
### Summarize merge request changes **(ULTIMATE SAAS)**
-> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10400) in GitLab 16.0 as an [Experiment](../policy/experiment-beta-support.md#experiment).
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/10401) in GitLab 16.2 as an [Experiment](../policy/experiment-beta-support.md#experiment).
This feature is an [Experiment](../policy/experiment-beta-support.md) on GitLab.com that is powered by OpenAI's GPT-3. It requires the [group-level third-party AI features setting](group/manage.md#enable-third-party-ai-features) to be enabled.
-You can generate a merge request summary in a merge request comment.
-
-- In a comment, type `/summarize_diff`.
-
-This action posts a comment from a GitLab bot. The comment provides a summary of the changes and the related SHA for when that summary was generated.
+These summaries are automatically generated. They are available on the merge request page in the **Merge request summaries** dialog, the To-Do list, and in email notifications.
Provide feedback on this experimental feature in [issue 408726](https://gitlab.com/gitlab-org/gitlab/-/issues/408726).
diff --git a/doc/user/project/pages/custom_domains_ssl_tls_certification/index.md b/doc/user/project/pages/custom_domains_ssl_tls_certification/index.md
index 0601e236a08..d74cdd7f7ac 100644
--- a/doc/user/project/pages/custom_domains_ssl_tls_certification/index.md
+++ b/doc/user/project/pages/custom_domains_ssl_tls_certification/index.md
@@ -25,6 +25,7 @@ To set up Pages with a custom domain name, read the requirements and steps below
### Prerequisites
+- An administrator has configured the server for [GitLab Pages custom domains](../../../../administration/pages/index.md#advanced-configuration)
- A GitLab Pages website up and running, served under the default Pages domain
(`*.gitlab.io`, for GitLab.com).
- A custom domain name `example.com` or subdomain `subdomain.example.com`.
@@ -32,17 +33,6 @@ To set up Pages with a custom domain name, read the requirements and steps below
- A DNS record (`A`, `ALIAS`, or `CNAME`) pointing your domain to the GitLab Pages server. If
there are multiple DNS records on that name, you must use an `ALIAS` record.
- A DNS `TXT` record to verify your domain's ownership.
-- Set either `external_http` or `external_https` in `/etc/gitlab/gitlab.rb` to the IP and port of
- your [Pages daemon](../../../../administration/pages/index.md#the-gitlab-pages-daemon).
- If you don't have IPv6, you can omit the IPv6 address.
-
- Example:
-
- ```ruby
- # Redirect pages from HTTP to HTTPS
- gitlab_pages['external_http'] = ['192.0.2.2:80', '[2001:db8::2]:80'] # The secondary IPs for the GitLab Pages daemon
- gitlab_pages['external_https'] = ['192.0.2.2:443', '[2001:db8::2]:443'] # The secondary IPs for the GitLab Pages daemon
- ```
### Steps
diff --git a/lib/api/entities/project.rb b/lib/api/entities/project.rb
index 61feacd6586..6a826bcac33 100644
--- a/lib/api/entities/project.rb
+++ b/lib/api/entities/project.rb
@@ -110,6 +110,7 @@ module API
# CI/CD Settings
expose :ci_default_git_depth, documentation: { type: 'integer', example: 20 }
expose :ci_forward_deployment_enabled, documentation: { type: 'boolean' }
+ expose :ci_forward_deployment_rollback_allowed, documentation: { type: 'boolean' }
expose(:ci_job_token_scope_enabled, documentation: { type: 'boolean' }) { |p, _| p.ci_outbound_job_token_scope_enabled? }
expose :ci_separated_caches, documentation: { type: 'boolean' }
expose :ci_allow_fork_pipelines_to_run_in_parent_project, documentation: { type: 'boolean' }
diff --git a/lib/api/helpers/projects_helpers.rb b/lib/api/helpers/projects_helpers.rb
index 642963768f8..46d629c1b21 100644
--- a/lib/api/helpers/projects_helpers.rb
+++ b/lib/api/helpers/projects_helpers.rb
@@ -102,6 +102,7 @@ module API
optional :ci_default_git_depth, type: Integer, desc: 'Default number of revisions for shallow cloning'
optional :keep_latest_artifact, type: Boolean, desc: 'Indicates if the latest artifact should be kept for this project.'
optional :ci_forward_deployment_enabled, type: Boolean, desc: 'Prevent older deployment jobs that are still pending'
+ optional :ci_forward_deployment_rollback_allowed, type: Boolean, desc: 'Allow job retries for rollback deployments'
optional :ci_allow_fork_pipelines_to_run_in_parent_project, type: Boolean, desc: 'Allow fork merge request pipelines to run in parent project'
optional :ci_separated_caches, type: Boolean, desc: 'Enable or disable separated caches based on branch protection.'
optional :restrict_user_defined_variables, type: Boolean, desc: 'Restrict use of user-defined variables when triggering a pipeline'
@@ -139,6 +140,7 @@ module API
:ci_default_git_depth,
:ci_allow_fork_pipelines_to_run_in_parent_project,
:ci_forward_deployment_enabled,
+ :ci_forward_deployment_rollback_allowed,
:ci_separated_caches,
:container_registry_access_level,
:container_expiration_policy_attributes,
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 14c88b24cfb..4ce4fb6fa1c 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -4703,6 +4703,12 @@ msgstr ""
msgid "Allow group owners to manage LDAP-related settings"
msgstr ""
+msgid "Allow job retries even if the deployment job is outdated."
+msgstr ""
+
+msgid "Allow job retries for rollback deployments"
+msgstr ""
+
msgid "Allow new users to create top-level groups"
msgstr ""
@@ -21361,9 +21367,6 @@ msgstr ""
msgid "Go to environments"
msgstr ""
-msgid "Go to environments page to approve or reject"
-msgstr ""
-
msgid "Go to epic"
msgstr ""
@@ -47429,7 +47432,7 @@ msgstr ""
msgid "This job depends on upstream jobs that need to succeed in order for this job to be triggered"
msgstr ""
-msgid "This job deploys to the protected environment \"%{environment}\" which requires approvals."
+msgid "This job deploys to the protected environment \"%{environment}\", which requires approvals. You can approve or reject the deployment on the environment details page."
msgstr ""
msgid "This job does not have a trace."
@@ -50807,6 +50810,9 @@ msgstr ""
msgid "View documentation"
msgstr ""
+msgid "View environment details page"
+msgstr ""
+
msgid "View exposed artifact"
msgid_plural "View %d exposed artifacts"
msgstr[0] ""
@@ -51468,7 +51474,7 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
-msgid "Waiting for approval"
+msgid "Waiting for approvals"
msgstr ""
msgid "Waiting for merge (open and assigned)"
diff --git a/spec/controllers/projects/settings/ci_cd_controller_spec.rb b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
index a1dbd27f49a..63c870eb133 100644
--- a/spec/controllers/projects/settings/ci_cd_controller_spec.rb
+++ b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
@@ -325,6 +325,14 @@ RSpec.describe Projects::Settings::CiCdController, feature_category: :continuous
end
end
+ context 'when changing forward_deployment_rollback_allowed' do
+ let(:params) { { ci_cd_settings_attributes: { forward_deployment_rollback_allowed: false } } }
+
+ it 'changes forward deployment rollback allowed' do
+ expect { subject }.to change { project.reload.ci_forward_deployment_rollback_allowed }.from(true).to(false)
+ end
+ end
+
context 'when max_artifacts_size is specified' do
let(:params) { { max_artifacts_size: 10 } }
diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb
index 6e3e119ddab..bd207bc9a64 100644
--- a/spec/factories/projects.rb
+++ b/spec/factories/projects.rb
@@ -55,6 +55,7 @@ FactoryBot.define do
import_correlation_id { nil }
import_last_error { nil }
forward_deployment_enabled { nil }
+ forward_deployment_rollback_allowed { nil }
restrict_user_defined_variables { nil }
ci_outbound_job_token_scope_enabled { nil }
ci_inbound_job_token_scope_enabled { nil }
diff --git a/spec/features/projects/settings/pipelines_settings_spec.rb b/spec/features/projects/settings/pipelines_settings_spec.rb
index ef1c03f4f27..533434ce0d9 100644
--- a/spec/features/projects/settings/pipelines_settings_spec.rb
+++ b/spec/features/projects/settings/pipelines_settings_spec.rb
@@ -65,6 +65,28 @@ RSpec.describe "Projects > Settings > Pipelines settings", feature_category: :gr
expect(checkbox).not_to be_checked
end
+ it 'updates forward_deployment_rollback_allowed' do
+ visit project_settings_ci_cd_path(project)
+
+ checkbox = find_field('project_ci_cd_settings_attributes_forward_deployment_rollback_allowed')
+ expect(checkbox).to be_checked
+
+ checkbox.set(false)
+
+ page.within '#js-general-pipeline-settings' do
+ click_on 'Save changes'
+ end
+
+ expect(page.status_code).to eq(200)
+
+ page.within '#js-general-pipeline-settings' do
+ expect(page).to have_button('Save changes', disabled: false)
+ end
+
+ checkbox = find_field('project_ci_cd_settings_attributes_forward_deployment_rollback_allowed')
+ expect(checkbox).not_to be_checked
+ end
+
describe 'Auto DevOps' do
context 'when auto devops is turned on instance-wide' do
before do
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index b7f457962a0..d3ef92eafec 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -702,6 +702,16 @@ RSpec.describe Ci::Build, feature_category: :continuous_integration, factory_def
it 'returns false for allowing rollback' do
expect(subject).to be_falsey
end
+
+ context 'when forward_deployment_rollback_allowed option is disabled' do
+ before do
+ project.ci_cd_settings.update!(forward_deployment_rollback_allowed: false)
+ end
+
+ it 'returns true for disallowing rollback' do
+ expect(subject).to eq(true)
+ end
+ end
end
end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 20b78eec17a..e8b72a8d616 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -1091,6 +1091,7 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
'group_runners_enabled' => '',
'default_git_depth' => 'ci_',
'forward_deployment_enabled' => 'ci_',
+ 'forward_deployment_rollback_allowed' => 'ci_',
'keep_latest_artifact' => '',
'restrict_user_defined_variables' => '',
'runner_token_expiration_interval' => '',
@@ -1117,6 +1118,12 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
end
end
+ describe '#ci_forward_deployment_rollback_allowed?' do
+ it_behaves_like 'a ci_cd_settings predicate method', prefix: 'ci_' do
+ let(:delegated_method) { :forward_deployment_rollback_allowed? }
+ end
+ end
+
describe '#ci_allow_fork_pipelines_to_run_in_parent_project?' do
it_behaves_like 'a ci_cd_settings predicate method', prefix: 'ci_' do
let(:delegated_method) { :allow_fork_pipelines_to_run_in_parent_project? }
diff --git a/spec/requests/api/project_attributes.yml b/spec/requests/api/project_attributes.yml
index 86ff739da7e..123c7ae852f 100644
--- a/spec/requests/api/project_attributes.yml
+++ b/spec/requests/api/project_attributes.yml
@@ -98,6 +98,7 @@ ci_cd_settings:
remapped_attributes:
default_git_depth: ci_default_git_depth
forward_deployment_enabled: ci_forward_deployment_enabled
+ forward_deployment_rollback_allowed: ci_forward_deployment_rollback_allowed
job_token_scope_enabled: ci_job_token_scope_enabled
separated_caches: ci_separated_caches
allow_fork_pipelines_to_run_in_parent_project: ci_allow_fork_pipelines_to_run_in_parent_project
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 1ff2adfcbcf..ea791379f01 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -2738,6 +2738,7 @@ RSpec.describe API::Projects, :aggregate_failures, feature_category: :groups_and
expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to eq(project.only_allow_merge_if_all_discussions_are_resolved)
expect(json_response['ci_default_git_depth']).to eq(project.ci_default_git_depth)
expect(json_response['ci_forward_deployment_enabled']).to eq(project.ci_forward_deployment_enabled)
+ expect(json_response['ci_forward_deployment_rollback_allowed']).to eq(project.ci_forward_deployment_rollback_allowed)
expect(json_response['ci_allow_fork_pipelines_to_run_in_parent_project']).to eq(project.ci_allow_fork_pipelines_to_run_in_parent_project)
expect(json_response['ci_separated_caches']).to eq(project.ci_separated_caches)
expect(json_response['merge_method']).to eq(project.merge_method.to_s)
@@ -3081,6 +3082,7 @@ RSpec.describe API::Projects, :aggregate_failures, feature_category: :groups_and
expect(json_response).not_to include(
'ci_default_git_depth',
'ci_forward_deployment_enabled',
+ 'ci_forward_deployment_rollback_allowed',
'ci_job_token_scope_enabled',
'ci_separated_caches',
'ci_allow_fork_pipelines_to_run_in_parent_project',
@@ -4166,6 +4168,7 @@ RSpec.describe API::Projects, :aggregate_failures, feature_category: :groups_and
merge_method: 'ff',
ci_default_git_depth: 20,
ci_forward_deployment_enabled: false,
+ ci_forward_deployment_rollback_allowed: false,
ci_allow_fork_pipelines_to_run_in_parent_project: false,
ci_separated_caches: false,
description: 'new description' }
diff --git a/spec/uploaders/object_storage_spec.rb b/spec/uploaders/object_storage_spec.rb
index a748c544bfd..8c33224968d 100644
--- a/spec/uploaders/object_storage_spec.rb
+++ b/spec/uploaders/object_storage_spec.rb
@@ -1097,19 +1097,31 @@ RSpec.describe ObjectStorage, :clean_gitlab_redis_shared_state, feature_category
let(:fog_config) do
Gitlab.config.uploads.object_store.tap do |config|
config[:remote_directory] = 'main-bucket'
- config[:bucket_prefix] = 'uploads'
+ config[:bucket_prefix] = 'my/uploads'
end
end
let(:bucket) { 'main-bucket' }
- let(:fog_file_path) { "uploads/#{final_path}" }
+ let(:fog_file_path) { "my/uploads/#{final_path}" }
it 'stores the file final path in the db without the prefix' do
expect { subject }.not_to raise_error
- expect(uploader.store_path).to eq("uploads/#{final_path}")
+ expect(uploader.store_path).to eq("my/uploads/#{final_path}")
expect(object.file_final_path).to eq(final_path)
end
+
+ context 'and file is stored' do
+ subject do
+ uploader.store!(uploaded_file)
+ end
+
+ it 'completes the matching pending upload entry' do
+ expect { subject }
+ .to change { ObjectStorage::PendingDirectUpload.exists?(uploader_class.storage_location_identifier, final_path) }
+ .to(false)
+ end
+ end
end
context 'when file is stored' do