From 0e6d9b66698db1e2e14e784fa9c601922e3f1a2c Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Sat, 22 Jul 2023 00:10:34 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- app/controllers/projects/issues_controller.rb | 2 +- .../projects/settings/ci_cd_controller.rb | 2 +- app/models/ci/build.rb | 2 +- app/models/project.rb | 7 ++++++ app/uploaders/object_storage.rb | 7 +++++- .../projects/settings/ci_cd/_form.html.haml | 10 +++++++-- ...yment_rollback_allowed_to_ci_cd_setting.rb | 13 +++++++++++ db/schema_migrations/20230718111807 | 1 + db/structure.sql | 3 ++- doc/administration/pages/index.md | 2 +- doc/api/groups.md | 1 + doc/api/merge_request_approvals.md | 2 +- doc/api/projects.md | 7 ++++++ doc/ci/environments/deployment_safety.md | 14 +++++++----- doc/ci/environments/index.md | 2 +- doc/ci/pipelines/settings.md | 1 + doc/user/ai_features.md | 8 ++----- .../index.md | 12 +--------- lib/api/entities/project.rb | 1 + lib/api/helpers/projects_helpers.rb | 2 ++ locale/gitlab.pot | 16 +++++++++----- .../settings/ci_cd_controller_spec.rb | 8 +++++++ spec/factories/projects.rb | 1 + .../settings/pipelines_settings_spec.rb | 22 +++++++++++++++++++ spec/models/ci/build_spec.rb | 10 +++++++++ spec/models/project_spec.rb | 7 ++++++ spec/requests/api/project_attributes.yml | 1 + spec/requests/api/projects_spec.rb | 3 +++ spec/uploaders/object_storage_spec.rb | 18 ++++++++++++--- 29 files changed, 144 insertions(+), 41 deletions(-) create mode 100644 db/migrate/20230718111807_add_column_forward_deployment_rollback_allowed_to_ci_cd_setting.rb create mode 100644 db/schema_migrations/20230718111807 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