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:
-rw-r--r--.gitlab/CODEOWNERS4
-rw-r--r--.rubocop_todo/rspec/verified_doubles.yml1
-rw-r--r--CHANGELOG.md19
-rw-r--r--GITLAB_KAS_VERSION2
-rw-r--r--app/assets/javascripts/lib/graphql.js5
-rw-r--r--app/services/ci/runners/set_runner_associated_projects_service.rb35
-rw-r--r--app/services/discussions/update_diff_position_service.rb2
-rw-r--r--app/views/shared/_broadcast_message.html.haml4
-rw-r--r--app/workers/all_queues.yml9
-rw-r--r--app/workers/ci/create_cross_project_pipeline_worker.rb19
-rw-r--r--config/feature_flags/development/unbatch_graphql_queries.yml8
-rw-r--r--config/sidekiq_queues.yml2
-rw-r--r--db/migrate/20230428134334_delete_create_cross_project_pipeline_worker_job_instances.rb16
-rw-r--r--db/schema_migrations/202304281343341
-rw-r--r--doc/ci/chatops/index.md4
-rw-r--r--doc/development/chatops_on_gitlabcom.md4
-rw-r--r--doc/integration/jira/connect-app.md4
-rw-r--r--doc/integration/jira/img/jira_added_user_to_group.pngbin21646 -> 0 bytes
-rw-r--r--doc/integration/jira/img/jira_create_new_group.pngbin70535 -> 0 bytes
-rw-r--r--doc/integration/jira/img/jira_group_access.pngbin20934 -> 0 bytes
-rw-r--r--doc/integration/jira/jira_server_configuration.md61
-rw-r--r--doc/security/rate_limits.md1
-rw-r--r--doc/user/admin_area/settings/rate_limit_on_projects_api.md4
-rw-r--r--doc/user/admin_area/settings/visibility_and_access_controls.md6
-rw-r--r--doc/user/gitlab_com/index.md16
-rw-r--r--doc/user/group/manage.md4
-rw-r--r--lib/gitlab/gon_helper.rb1
-rw-r--r--lib/gitlab/import_export/group/relation_tree_restorer.rb4
-rw-r--r--lib/gitlab/timeless.rb10
-rw-r--r--lib/gitlab/usage_data_counters/known_events/product_analytics.yml2
-rw-r--r--locale/gitlab.pot3
-rw-r--r--package.json4
-rw-r--r--spec/features/merge_request/user_reverts_merge_request_spec.rb1
-rw-r--r--spec/features/merge_request/user_sees_merge_widget_spec.rb1
-rw-r--r--spec/features/user_sees_revert_modal_spec.rb1
-rw-r--r--spec/graphql/mutations/ci/runner/update_spec.rb108
-rw-r--r--spec/lib/gitlab/timeless_spec.rb37
-rw-r--r--spec/requests/projects/merge_requests_discussions_spec.rb10
-rw-r--r--spec/services/ci/runners/set_runner_associated_projects_service_spec.rb77
-rw-r--r--spec/support/rspec_order_todo.yml1
-rw-r--r--spec/workers/ci/create_cross_project_pipeline_worker_spec.rb37
-rw-r--r--spec/workers/every_sidekiq_worker_spec.rb1
-rw-r--r--yarn.lock25
43 files changed, 297 insertions, 257 deletions
diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS
index fb0c3383fc5..31ddb12c65b 100644
--- a/.gitlab/CODEOWNERS
+++ b/.gitlab/CODEOWNERS
@@ -649,7 +649,7 @@ lib/gitlab/checks/**
/doc/architecture/blueprints/database_scaling/ @aqualls
/doc/ci/ @drcatherinepope
/doc/ci/caching/ @marcel.amirault
-/doc/ci/chatops/ @phillipwells
+/doc/ci/chatops/ @eread
/doc/ci/cloud_deployment/ @phillipwells
/doc/ci/cloud_services/ @marcel.amirault
/doc/ci/directed_acyclic_graph/ @marcel.amirault
@@ -693,7 +693,7 @@ lib/gitlab/checks/**
/doc/development/bulk_import.md @eread
/doc/development/cached_queries.md @jglassman1
/doc/development/cascading_settings.md @jglassman1
-/doc/development/chatops_on_gitlabcom.md @phillipwells
+/doc/development/chatops_on_gitlabcom.md @eread
/doc/development/cicd/ @marcel.amirault
/doc/development/cicd/cicd_tables.md @drcatherinepope
/doc/development/cicd/index.md @drcatherinepope
diff --git a/.rubocop_todo/rspec/verified_doubles.yml b/.rubocop_todo/rspec/verified_doubles.yml
index 479272962da..217b59e0ef0 100644
--- a/.rubocop_todo/rspec/verified_doubles.yml
+++ b/.rubocop_todo/rspec/verified_doubles.yml
@@ -1002,7 +1002,6 @@ RSpec/VerifiedDoubles:
- 'spec/workers/bulk_imports/export_request_worker_spec.rb'
- 'spec/workers/chat_notification_worker_spec.rb'
- 'spec/workers/ci/build_prepare_worker_spec.rb'
- - 'spec/workers/ci/create_cross_project_pipeline_worker_spec.rb'
- 'spec/workers/ci/create_downstream_pipeline_worker_spec.rb'
- 'spec/workers/ci/pipeline_bridge_status_worker_spec.rb'
- 'spec/workers/ci/pipeline_success_unlock_artifacts_worker_spec.rb'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 310cce472d8..b246240e7e9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,13 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
+## 15.11.2 (2023-05-03)
+
+### Security (2 changes)
+
+- [Only maintainers of projects should be able to assign runners to them](gitlab-org/security/gitlab@c52abfffad2c06c2a49788e3db473f14923c3926) ([merge request](gitlab-org/security/gitlab!3234))
+- [Authorize access to vulnerabilitiesCountByDay resolver](gitlab-org/security/gitlab@8e78aecb9a6c248099a043f181de3c8f6d4417ce)
+
## 15.11.1 (2023-05-01)
### Fixed (2 changes)
@@ -836,6 +843,12 @@ entry.
- [Update header section](gitlab-org/gitlab@cf4ab283267d84fa1c0dc90fefb1b6ddd2617b5c) ([merge request](gitlab-org/gitlab!114102)) **GitLab Enterprise Edition**
- [Swap merge_request_user_mentions.note_id to bigint](gitlab-org/gitlab@96baed47326db4f0cc9f60b2e74215211effd814) ([merge request](gitlab-org/gitlab!113928))
+## 15.10.6 (2023-05-03)
+
+### Security (1 change)
+
+- [Only maintainers of projects should be able to assign runners to them](gitlab-org/security/gitlab@a20f5018b757a78a772d2bf1f9f8cdfe95a019ed) ([merge request](gitlab-org/security/gitlab!3235))
+
## 15.10.5 (2023-05-01)
### Security (9 changes)
@@ -1629,6 +1642,12 @@ entry.
- [Update submit buttons to use Pajamas component](gitlab-org/gitlab@4ffb92755e6be3268c78f02e471f5c2a21f437be) ([merge request](gitlab-org/gitlab!114246))
+## 15.9.7 (2023-05-03)
+
+### Security (1 change)
+
+- [Only maintainers of projects should be able to assign runners to them](gitlab-org/security/gitlab@695748314b758ca2d9992df7509025a6ac868000) ([merge request](gitlab-org/security/gitlab!3236))
+
## 15.9.6 (2023-05-01)
### Security (8 changes)
diff --git a/GITLAB_KAS_VERSION b/GITLAB_KAS_VERSION
index 3ac9201d3ac..3b8d94e200f 100644
--- a/GITLAB_KAS_VERSION
+++ b/GITLAB_KAS_VERSION
@@ -1 +1 @@
-v16.0.0-rc1
+v16.0.0-rc2
diff --git a/app/assets/javascripts/lib/graphql.js b/app/assets/javascripts/lib/graphql.js
index 2e6fcbea80d..a4c13f9e40e 100644
--- a/app/assets/javascripts/lib/graphql.js
+++ b/app/assets/javascripts/lib/graphql.js
@@ -123,6 +123,9 @@ function createApolloClient(resolvers = {}, config = {}) {
path = '/api/graphql',
useGet = false,
} = config;
+
+ const shouldUnbatch = gon.features?.unbatchGraphqlQueries;
+
let ac = null;
let uri = `${gon.relative_url_root || ''}${path}`;
@@ -160,7 +163,7 @@ function createApolloClient(resolvers = {}, config = {}) {
};
const requestLink = ApolloLink.split(
- () => useGet,
+ () => useGet || shouldUnbatch,
new HttpLink({ ...httpOptions, fetch: fetchIntervention }),
new BatchHttpLink(httpOptions),
);
diff --git a/app/services/ci/runners/set_runner_associated_projects_service.rb b/app/services/ci/runners/set_runner_associated_projects_service.rb
index 5e33fdae2f4..3608fdfac71 100644
--- a/app/services/ci/runners/set_runner_associated_projects_service.rb
+++ b/app/services/ci/runners/set_runner_associated_projects_service.rb
@@ -33,15 +33,9 @@ module Ci
current_project_ids = runner.projects.ids
# rubocop:enable CodeReuse/ActiveRecord
- unless associate_new_projects(new_project_ids, current_project_ids)
- response = ServiceResponse.error(message: 'failed to assign projects to runner')
- raise ActiveRecord::Rollback, response.errors
- end
-
- unless disassociate_old_projects(new_project_ids, current_project_ids)
- response = ServiceResponse.error(message: 'failed to destroy runner project')
- raise ActiveRecord::Rollback, response.errors
- end
+ response = associate_new_projects(new_project_ids, current_project_ids)
+ response = disassociate_old_projects(new_project_ids, current_project_ids) if response.success?
+ raise ActiveRecord::Rollback, response.errors unless response.success?
end
response
@@ -49,16 +43,29 @@ module Ci
def associate_new_projects(new_project_ids, current_project_ids)
missing_projects = Project.id_in(new_project_ids - current_project_ids)
- missing_projects.all? { |project| runner.assign_to(project, current_user) }
+
+ unless missing_projects.all? { |project| current_user.can?(:register_project_runners, project) }
+ return ServiceResponse.error(message: 'user is not authorized to add runners to project')
+ end
+
+ unless missing_projects.all? { |project| runner.assign_to(project, current_user) }
+ return ServiceResponse.error(message: 'failed to assign projects to runner')
+ end
+
+ ServiceResponse.success
end
def disassociate_old_projects(new_project_ids, current_project_ids)
projects_to_be_deleted = current_project_ids - new_project_ids
- return true if projects_to_be_deleted.empty?
+ return ServiceResponse.success if projects_to_be_deleted.empty?
+
+ all_destroyed =
+ Ci::RunnerProject
+ .destroy_by(project_id: projects_to_be_deleted)
+ .all?(&:destroyed?)
+ return ServiceResponse.success if all_destroyed
- Ci::RunnerProject
- .destroy_by(project_id: projects_to_be_deleted)
- .all?(&:destroyed?)
+ ServiceResponse.error(message: 'failed to destroy runner project')
end
attr_reader :runner, :current_user, :project_ids
diff --git a/app/services/discussions/update_diff_position_service.rb b/app/services/discussions/update_diff_position_service.rb
index 7bdf7711155..31816b46c52 100644
--- a/app/services/discussions/update_diff_position_service.rb
+++ b/app/services/discussions/update_diff_position_service.rb
@@ -25,7 +25,7 @@ module Discussions
Note.transaction do
discussion.notes.each do |note|
- Gitlab::Timeless.timeless(note, &:save)
+ note.save(touch: false)
end
if outdated && current_user
diff --git a/app/views/shared/_broadcast_message.html.haml b/app/views/shared/_broadcast_message.html.haml
index 4d286713cef..a2fed883739 100644
--- a/app/views/shared/_broadcast_message.html.haml
+++ b/app/views/shared/_broadcast_message.html.haml
@@ -9,6 +9,8 @@
= sprite_icon(icon_name)
.gl-broadcast-message-text.js-broadcast-message-preview
- if message.message.present?
+ %h2.gl-sr-only
+ = s_("Admin message")
= render_broadcast_message(message)
- else
= yield
@@ -24,6 +26,8 @@
.broadcast-message.broadcast-notification-message.mt-2{ role: "alert", class: notification_class, data: { qa_selector: 'broadcast_notification_container' } }
= sprite_icon(icon_name, css_class: 'vertical-align-text-top')
- if message.message.present?
+ %h2.gl-sr-only
+ = s_("Admin message")
= render_broadcast_message(message)
- else
= yield
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index 8d100f8b456..29585f5539a 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -1938,15 +1938,6 @@
:weight: 4
:idempotent: true
:tags: []
-- :name: pipeline_default:ci_create_cross_project_pipeline
- :worker_name: Ci::CreateCrossProjectPipelineWorker
- :feature_category: :continuous_integration
- :has_external_dependencies: false
- :urgency: :low
- :resource_boundary: :cpu
- :weight: 3
- :idempotent: false
- :tags: []
- :name: pipeline_default:ci_create_downstream_pipeline
:worker_name: Ci::CreateDownstreamPipelineWorker
:feature_category: :continuous_integration
diff --git a/app/workers/ci/create_cross_project_pipeline_worker.rb b/app/workers/ci/create_cross_project_pipeline_worker.rb
deleted file mode 100644
index 4881ee12e5c..00000000000
--- a/app/workers/ci/create_cross_project_pipeline_worker.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-module Ci
- class CreateCrossProjectPipelineWorker # rubocop:disable Scalability/IdempotentWorker
- include ::ApplicationWorker
- include ::PipelineQueue
-
- sidekiq_options retry: 3
- worker_resource_boundary :cpu
-
- def perform(bridge_id)
- ::Ci::Bridge.find_by_id(bridge_id).try do |bridge|
- ::Ci::CreateDownstreamPipelineService
- .new(bridge.project, bridge.user)
- .execute(bridge)
- end
- end
- end
-end
diff --git a/config/feature_flags/development/unbatch_graphql_queries.yml b/config/feature_flags/development/unbatch_graphql_queries.yml
new file mode 100644
index 00000000000..c5bc8c3033a
--- /dev/null
+++ b/config/feature_flags/development/unbatch_graphql_queries.yml
@@ -0,0 +1,8 @@
+---
+name: unbatch_graphql_queries
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/117407
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/406765
+milestone: '16.0'
+type: development
+group: group::project management
+default_enabled: false
diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml
index f0917c9265b..5a7e0d41e49 100644
--- a/config/sidekiq_queues.yml
+++ b/config/sidekiq_queues.yml
@@ -421,6 +421,8 @@
- 1
- - product_analytics_initialize_snowplow_product_analytics
- 1
+- - product_analytics_post_push
+ - 1
- - project_cache
- 1
- - project_destroy
diff --git a/db/migrate/20230428134334_delete_create_cross_project_pipeline_worker_job_instances.rb b/db/migrate/20230428134334_delete_create_cross_project_pipeline_worker_job_instances.rb
new file mode 100644
index 00000000000..517f85c0c1f
--- /dev/null
+++ b/db/migrate/20230428134334_delete_create_cross_project_pipeline_worker_job_instances.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class DeleteCreateCrossProjectPipelineWorkerJobInstances < Gitlab::Database::Migration[2.1]
+ DEPRECATED_JOB_CLASSES = %w[
+ CreateCrossProjectPipelineWorker
+ ]
+
+ disable_ddl_transaction!
+ def up
+ sidekiq_remove_jobs(job_klasses: DEPRECATED_JOB_CLASSES)
+ end
+
+ def down
+ # This migration removes any instances of deprecated workers and cannot be undone.
+ end
+end
diff --git a/db/schema_migrations/20230428134334 b/db/schema_migrations/20230428134334
new file mode 100644
index 00000000000..96e5841736f
--- /dev/null
+++ b/db/schema_migrations/20230428134334
@@ -0,0 +1 @@
+43d27869d87ec93da96fbc9ea23f50b7588d5f491b1d5c53beeed7a529003e09 \ No newline at end of file
diff --git a/doc/ci/chatops/index.md b/doc/ci/chatops/index.md
index 7be12d0c0fd..6dff87ed1c5 100644
--- a/doc/ci/chatops/index.md
+++ b/doc/ci/chatops/index.md
@@ -1,6 +1,6 @@
---
-stage: Deploy
-group: Environments
+stage: Manage
+group: Import and Integrate
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
type: index, concepts, howto
---
diff --git a/doc/development/chatops_on_gitlabcom.md b/doc/development/chatops_on_gitlabcom.md
index 002470f7325..22f57e8ba43 100644
--- a/doc/development/chatops_on_gitlabcom.md
+++ b/doc/development/chatops_on_gitlabcom.md
@@ -1,6 +1,6 @@
---
-stage: Deploy
-group: Environments
+stage: Manage
+group: Import and Integrate
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
diff --git a/doc/integration/jira/connect-app.md b/doc/integration/jira/connect-app.md
index b40d9707274..e60eeb8fba1 100644
--- a/doc/integration/jira/connect-app.md
+++ b/doc/integration/jira/connect-app.md
@@ -96,7 +96,9 @@ With this method, GitLab.com serves as a proxy for Jira traffic from your instan
If your instance doesn't meet the [prerequisites](#prerequisites) or you don't want to use the official marketplace listing, you can
[install the app manually](#install-the-gitlab-for-jira-cloud-app-manually).
-It's not possible to create branches from Jira for self-managed instances. For more information, see [issue 391432](https://gitlab.com/gitlab-org/gitlab/-/issues/391432).
+With this method, it's not possible to create branches from Jira Cloud for self-managed instances.
+For more information, see [issue 391432](https://gitlab.com/gitlab-org/gitlab/-/issues/391432).
+To create branches from Jira Cloud, [install the app manually](#install-the-gitlab-for-jira-cloud-app-manually).
### Prerequisites
diff --git a/doc/integration/jira/img/jira_added_user_to_group.png b/doc/integration/jira/img/jira_added_user_to_group.png
deleted file mode 100644
index f5120a8d42e..00000000000
--- a/doc/integration/jira/img/jira_added_user_to_group.png
+++ /dev/null
Binary files differ
diff --git a/doc/integration/jira/img/jira_create_new_group.png b/doc/integration/jira/img/jira_create_new_group.png
deleted file mode 100644
index 4ab7a5eae4e..00000000000
--- a/doc/integration/jira/img/jira_create_new_group.png
+++ /dev/null
Binary files differ
diff --git a/doc/integration/jira/img/jira_group_access.png b/doc/integration/jira/img/jira_group_access.png
deleted file mode 100644
index 42a9b4ae564..00000000000
--- a/doc/integration/jira/img/jira_group_access.png
+++ /dev/null
Binary files differ
diff --git a/doc/integration/jira/jira_server_configuration.md b/doc/integration/jira/jira_server_configuration.md
index 2f3b3520a7f..c840e1ebde5 100644
--- a/doc/integration/jira/jira_server_configuration.md
+++ b/doc/integration/jira/jira_server_configuration.md
@@ -6,24 +6,22 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Jira Server credentials **(FREE)**
-To [integrate Jira with GitLab](index.md), you can:
+To [integrate Jira with GitLab](configure.md), you should create a separate Jira user account for your Jira projects
+to access projects in GitLab. This Jira user account must have write access to your Jira projects.
+To create the credentials:
-- Recommended. Create a separate Jira user account for your Jira projects to access projects in GitLab.
-This Jira user account must have write access to your Jira projects. To create the
-credentials, you must:
+1. [Create a Jira Server user](#create-a-jira-server-user).
+1. [Create a Jira Server group for the user](#create-a-jira-server-group-for-the-user).
+1. [Create a permission scheme for the group](#create-a-permission-scheme-for-the-group).
- 1. [Create a Jira Server user](#create-a-jira-server-user).
- 1. [Create a Jira Server group](#create-a-jira-server-group) for the user to belong to.
- 1. [Create a permission scheme for your group](#create-a-permission-scheme-for-your-group).
+Alternatively, you can use an existing Jira user account, provided the user belongs to a Jira group that
+has been granted the **Administer Projects** [permission scheme](#create-a-permission-scheme-for-the-group).
-- Use an existing Jira user account provided the user belongs to a Jira group that
-has been granted the **Administer Projects** [permission scheme](#create-a-permission-scheme-for-your-group).
-
-After you select a Jira user account for the integration, [configure GitLab](configure.md) to use the account.
+After you select a Jira user account, [configure the integration](configure.md#configure-the-integration) in GitLab to use the account.
## Create a Jira Server user
-This process creates a user named `gitlab`:
+To create a Jira Server user:
1. Sign in to your Jira instance as a Jira administrator.
1. On the top bar, in the upper-right corner, select the gear icon, then
@@ -36,55 +34,42 @@ This process creates a user named `gitlab`:
support SSO such as SAML.
1. Select **Create user**.
-After you create the user, create a group for it.
-
-## Create a Jira Server group
+Now that you've created a user named `gitlab`, it's time to create a group for the user.
-After you [create a Jira Server user](#create-a-jira-server-user), create a
-group to assign permissions to the user.
+## Create a Jira Server group for the user
-This process adds the `gitlab` user you created to a new group named `gitlab-developers`:
+To create a Jira Server group for the user:
1. Sign in to your Jira instance as a Jira administrator.
1. On the top bar, in the upper-right corner, select the gear icon, then
select **User Management**.
1. On the left sidebar, select **Groups**.
-
- ![Jira create new user](img/jira_create_new_group.png)
-
1. In the **Add group** section, enter a **Name** for the group (for example,
- `gitlab-developers`), and then select **Add group**.
+ `gitlab-developers`), then select **Add group**.
1. To add the `gitlab` user to the `gitlab-developers` group, select **Edit members**.
- The `gitlab-developers` group should be listed in the leftmost box as a
- selected group.
+ The `gitlab-developers` group appears as a selected group.
<!-- vale gitlab.BadPlurals = NO -->
1. In the **Add members to selected group(s)** section, enter `gitlab`.
1. Select **Add selected users**.
- The `gitlab` user appears in the **Group member(s)**
- section.
+ The `gitlab` user appears as a group member.
<!-- vale gitlab.BadPlurals = YES -->
- ![Jira added user to group](img/jira_added_user_to_group.png)
-
-Next, create a permission scheme for your group.
+Now that you've added the `gitlab` user to a new group named `gitlab-developers`,
+it's time to create a permission scheme for the group.
-## Create a permission scheme for your group
+## Create a permission scheme for the group
-After you [create the group in Jira](#create-a-jira-server-group), grant permissions to the group by creating a permission scheme:
+To create a permission scheme for the group:
1. Sign in to your Jira instance as a Jira administrator.
1. On the top bar, in the upper-right corner, select the gear icon, then
select **Issues**.
1. On the left sidebar, select **Permission Schemes**.
1. Select **Add Permission Scheme**, enter a **Name** and (optionally) a
- **Description**, and then select **Add**.
+ **Description**, then select **Add**.
1. In the permissions scheme list, locate your new permissions scheme, and
select **Permissions**.
1. Next to **Administer Projects**, select **Edit**.
-1. From the **Group** dropdown list, select `gitlab-developers`, and then select **Grant**.
-
- ![Jira group access](img/jira_group_access.png)
+1. From the **Group** dropdown list, select `gitlab-developers`, then select **Grant**.
-Write down the new Jira username and its
-password, as you need them when
-[configuring GitLab](configure.md).
+You need the new Jira username and password when you [configure the integration](configure.md#configure-the-integration) in GitLab.
diff --git a/doc/security/rate_limits.md b/doc/security/rate_limits.md
index fafce3a985e..da267388b7e 100644
--- a/doc/security/rate_limits.md
+++ b/doc/security/rate_limits.md
@@ -44,6 +44,7 @@ You can set these rate limits in the Admin Area of your instance:
- [GitLab Pages rate limits](../administration/pages/index.md#rate-limits)
- [Pipeline rate limits](../user/admin_area/settings/rate_limit_on_pipelines_creation.md)
- [Incident management rate limits](../user/admin_area/settings/incident_management_rate_limits.md)
+- [Unauthenticated access to Projects List API rate limits](../user/admin_area/settings/rate_limit_on_projects_api.md)
You can set these rate limits using the Rails console:
diff --git a/doc/user/admin_area/settings/rate_limit_on_projects_api.md b/doc/user/admin_area/settings/rate_limit_on_projects_api.md
index beed083c484..e82e682b0bb 100644
--- a/doc/user/admin_area/settings/rate_limit_on_projects_api.md
+++ b/doc/user/admin_area/settings/rate_limit_on_projects_api.md
@@ -7,7 +7,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Rate limit on Projects API **(FREE SELF)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/112283) in GitLab 15.10 behind a feature flag, disabled by default.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/112283) in GitLab 15.10 with a [flag](../../../administration/feature_flags.md) named `rate_limit_for_unauthenticated_projects_api_access`. Disabled by default.
+> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/391922) on May 08, 2023.
+> - [Enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/119603) in GitLab 16.0 by default.
You can configure the rate limit per IP address for unauthenticated requests to the [list all projects API](../../../api/projects.md#list-all-projects).
diff --git a/doc/user/admin_area/settings/visibility_and_access_controls.md b/doc/user/admin_area/settings/visibility_and_access_controls.md
index dfb23a4017e..fcad1a31225 100644
--- a/doc/user/admin_area/settings/visibility_and_access_controls.md
+++ b/doc/user/admin_area/settings/visibility_and_access_controls.md
@@ -55,6 +55,8 @@ By default both administrators and anyone with the **Owner** role can delete a p
> - [Enabled for projects in personal namespaces](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/89466) in GitLab 15.1.
> - [Disabled for projects in personal namespaces](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95495) in GitLab 15.3.
> - [Removed option to delete immediately](https://gitlab.com/gitlab-org/gitlab/-/issues/389557) in GitLab 15.11 [with a flag](../../../administration/feature_flags.md) named `always_perform_delayed_deletion`. Disabled by default.
+> - Enabled delayed deletion by default and removed the option to delete immediately [on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/393622) on May 08, 2023.
+> - Enabled delayed deletion by default and removed the option to delete immediately [on self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/119606) in GitLab 16.0.
Instance-level protection against accidental deletion of groups and projects.
@@ -83,7 +85,7 @@ To configure delayed project deletion:
1. On the left sidebar, select **Settings > General**.
1. Expand the **Visibility and access controls** section.
1. Scroll to:
- - (GitLab 15.11 and later with `always_perform_delayed_deletion` feature flag enabled) **Deletion protection** and set the retention period to a value between `1` and `90`.
+ - (In GitLab 15.11 and later with `always_perform_delayed_deletion` feature flag enabled, or GitLab 16.0 and later) **Deletion protection** and set the retention period to a value between `1` and `90`.
- (GitLab 15.1 and later) **Deletion protection** and select keep deleted groups and projects, and select a retention period.
- (GitLab 15.0 and earlier) **Default delayed project protection** and select **Enable delayed project deletion by
default for newly-created groups.** Then set a retention period in **Default deletion delay**.
@@ -100,7 +102,7 @@ In GitLab 15.1, and later this setting is enforced on groups when disabled and i
Groups remain restorable if the retention period is `1` or more days.
In GitLab 15.1 and later, delayed group deletion can be enabled by setting **Deletion projection** to **Keep deleted**.
-In GitLab 15.11 and later with the `always_perform_delayed_deletion` feature flag enabled:
+In GitLab 15.11 and later with the `always_perform_delayed_deletion` feature flag enabled, or in GitLab 16.0 and later:
- The **Keep deleted** option is removed.
- Delayed group deletion is the default.
diff --git a/doc/user/gitlab_com/index.md b/doc/user/gitlab_com/index.md
index 68d1b51ec08..22476d2410c 100644
--- a/doc/user/gitlab_com/index.md
+++ b/doc/user/gitlab_com/index.md
@@ -89,15 +89,21 @@ Similarly, you can clone a project's wiki to back it up. All files
[uploaded after August 22, 2020](../project/wiki/index.md#create-a-new-wiki-page)
are included when cloning.
+## Delayed group deletion **(PREMIUM SAAS)**
+
+After May 08, 2023, all groups have delayed deletion enabled by default.
+
+Groups are permanently deleted after a seven-day delay.
+
+If you are on the Free tier, your groups are immediately deleted, and you will not be able to restore them.
+
## Delayed project deletion **(PREMIUM SAAS)**
-Top-level groups created after August 12, 2021 have delayed project deletion enabled by default.
-Projects are permanently deleted after a seven-day delay.
+After May 08, 2023, all groups have delayed project deletion enabled by default.
-If you are on:
+Projects are permanently deleted after a seven-day delay.
-- Premium tier and above, you can disable this by changing the [group setting](../group/manage.md#enable-delayed-project-deletion).
-- Free tier, you cannot disable this setting or restore projects.
+If you are on the Free tier, your projects are immediately deleted, and you will not be able to restore them.
## Inactive project deletion
diff --git a/doc/user/group/manage.md b/doc/user/group/manage.md
index b867311c81f..bb7862419f2 100644
--- a/doc/user/group/manage.md
+++ b/doc/user/group/manage.md
@@ -402,6 +402,8 @@ To transfer a group:
> - [Instance setting is inherited and enforced when disabled](https://gitlab.com/gitlab-org/gitlab/-/issues/352960) in GitLab 15.1.
> - [User interface changed](https://gitlab.com/gitlab-org/gitlab/-/issues/352961) in GitLab 15.1.
> - [Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/389557) in GitLab 15.11 [with a flag](../../administration/feature_flags.md) named `always_perform_delayed_deletion`. Disabled by default.
+> - Enabled delayed deletion by default and removed the option to delete immediately [on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/393622) on May 08, 2023.
+> - Enabled delayed deletion by default and removed the option to delete immediately [on self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/119606) in GitLab 16.0.
[Delayed project deletion](../project/settings/index.md#delayed-project-deletion) is locked and disabled unless the instance-level settings for
[deletion protection](../admin_area/settings/visibility_and_access_controls.md#deletion-protection) are enabled for either groups only or groups and projects.
@@ -432,7 +434,7 @@ To enable delayed deletion of projects in a group:
In GitLab 13.11 and later, the group setting for delayed project deletion is inherited by subgroups. As discussed in [Cascading settings](../../development/cascading_settings.md), inheritance can be overridden unless enforced by an ancestor.
In GitLab 15.11 with the `always_perform_delayed_deletion` feature flag enabled, this setting is removed
-and all projects are deleted after the [retention period defined by the admin](../admin_area/settings/visibility_and_access_controls.md#retention-period).
+and all projects are deleted after the [retention period defined by the admin](../admin_area/settings/visibility_and_access_controls.md#retention-period). This will be the default behavior in GitLab 16.0 and later.
## Disable email notifications
diff --git a/lib/gitlab/gon_helper.rb b/lib/gitlab/gon_helper.rb
index 62fdf812940..af11bcf06b0 100644
--- a/lib/gitlab/gon_helper.rb
+++ b/lib/gitlab/gon_helper.rb
@@ -67,6 +67,7 @@ module Gitlab
push_frontend_feature_flag(:source_editor_toolbar)
push_frontend_feature_flag(:vscode_web_ide, current_user)
push_frontend_feature_flag(:super_sidebar_peek, current_user)
+ push_frontend_feature_flag(:unbatch_graphql_queries)
end
# Exposes the state of a feature flag to the frontend code.
diff --git a/lib/gitlab/import_export/group/relation_tree_restorer.rb b/lib/gitlab/import_export/group/relation_tree_restorer.rb
index 5825db89201..5453792e904 100644
--- a/lib/gitlab/import_export/group/relation_tree_restorer.rb
+++ b/lib/gitlab/import_export/group/relation_tree_restorer.rb
@@ -135,9 +135,7 @@ module Gitlab
modify_attributes
- Gitlab::Timeless.timeless(@importable) do
- @importable.save!
- end
+ @importable.save!(touch: false)
end
def filter_attributes(params)
diff --git a/lib/gitlab/timeless.rb b/lib/gitlab/timeless.rb
index ed0b7b4ed87..55cd9d7e6fb 100644
--- a/lib/gitlab/timeless.rb
+++ b/lib/gitlab/timeless.rb
@@ -2,17 +2,11 @@
module Gitlab
module Timeless
- def self.timeless(model, &block)
+ def self.timeless(model)
original_record_timestamps = model.record_timestamps
model.record_timestamps = false
- # negative arity means arguments are optional
- if block.arity == 1 || block.arity < 0
- yield(model)
- else
- yield
- end
-
+ yield model
ensure
model.record_timestamps = original_record_timestamps
end
diff --git a/lib/gitlab/usage_data_counters/known_events/product_analytics.yml b/lib/gitlab/usage_data_counters/known_events/product_analytics.yml
new file mode 100644
index 00000000000..b61e2f4e5a2
--- /dev/null
+++ b/lib/gitlab/usage_data_counters/known_events/product_analytics.yml
@@ -0,0 +1,2 @@
+- name: project_created_analytics_dashboard
+ aggregation: weekly
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 367dbcb6a99..286f3aa4f7f 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -2837,6 +2837,9 @@ msgstr ""
msgid "Admin Notifications"
msgstr ""
+msgid "Admin message"
+msgstr ""
+
msgid "Admin mode already enabled"
msgstr ""
diff --git a/package.json b/package.json
index c5bc3767779..155132a8387 100644
--- a/package.json
+++ b/package.json
@@ -113,7 +113,7 @@
"apollo3-cache-persist": "^0.14.1",
"autosize": "^5.0.1",
"axios": "^0.24.0",
- "babel-loader": "^8.2.5",
+ "babel-loader": "^8.3.0",
"babel-plugin-lodash": "^3.3.4",
"bootstrap": "4.6.2",
"browserslist": "^4.21.3",
@@ -217,7 +217,7 @@
"web-streams-polyfill": "^3.2.1",
"web-vitals": "^0.2.4",
"webpack": "^4.46.0",
- "webpack-bundle-analyzer": "^4.6.1",
+ "webpack-bundle-analyzer": "^4.8.0",
"webpack-cli": "^4.10.0",
"webpack-stats-plugin": "^0.3.1",
"worker-loader": "^2.0.0",
diff --git a/spec/features/merge_request/user_reverts_merge_request_spec.rb b/spec/features/merge_request/user_reverts_merge_request_spec.rb
index da48a31abbd..8c782056aa4 100644
--- a/spec/features/merge_request/user_reverts_merge_request_spec.rb
+++ b/spec/features/merge_request/user_reverts_merge_request_spec.rb
@@ -8,6 +8,7 @@ RSpec.describe 'User reverts a merge request', :js, feature_category: :code_revi
let(:user) { create(:user) }
before do
+ stub_feature_flags(unbatch_graphql_queries: false)
project.add_developer(user)
sign_in(user)
diff --git a/spec/features/merge_request/user_sees_merge_widget_spec.rb b/spec/features/merge_request/user_sees_merge_widget_spec.rb
index eb293fbbd20..cb56e79fcc0 100644
--- a/spec/features/merge_request/user_sees_merge_widget_spec.rb
+++ b/spec/features/merge_request/user_sees_merge_widget_spec.rb
@@ -53,6 +53,7 @@ RSpec.describe 'Merge request > User sees merge widget', :js, feature_category:
let!(:deployment) { build.deployment }
before do
+ stub_feature_flags(unbatch_graphql_queries: false)
merge_request.update!(head_pipeline: pipeline)
deployment.update!(status: :success)
visit project_merge_request_path(project, merge_request)
diff --git a/spec/features/user_sees_revert_modal_spec.rb b/spec/features/user_sees_revert_modal_spec.rb
index 1c754943acb..aca32d26bdb 100644
--- a/spec/features/user_sees_revert_modal_spec.rb
+++ b/spec/features/user_sees_revert_modal_spec.rb
@@ -19,6 +19,7 @@ feature_category: :code_review_workflow do
end
before do
+ stub_feature_flags(unbatch_graphql_queries: false)
sign_in(user)
visit(project_merge_request_path(project, merge_request))
page.within('.mr-state-widget') do
diff --git a/spec/graphql/mutations/ci/runner/update_spec.rb b/spec/graphql/mutations/ci/runner/update_spec.rb
index e0c8219e0f6..50351321be8 100644
--- a/spec/graphql/mutations/ci/runner/update_spec.rb
+++ b/spec/graphql/mutations/ci/runner/update_spec.rb
@@ -46,10 +46,17 @@ RSpec.describe Mutations::Ci::Runner::Update, feature_category: :runner_fleet do
end
end
- context 'when user can update runner', :enable_admin_mode do
- let_it_be(:admin_user) { create(:user, :admin) }
+ context 'when user can update runner' do
+ let_it_be(:user) { create(:user) }
- let(:current_ctx) { { current_user: admin_user } }
+ let(:original_projects) { [project1, project2] }
+ let(:projects_with_maintainer_access) { original_projects }
+
+ let(:current_ctx) { { current_user: user } }
+
+ before do
+ projects_with_maintainer_access.each { |project| project.add_maintainer(user) }
+ end
context 'with valid arguments' do
let(:mutation_params) do
@@ -82,27 +89,22 @@ RSpec.describe Mutations::Ci::Runner::Update, feature_category: :runner_fleet do
context 'with associatedProjects argument' do
let_it_be(:project3) { create(:project) }
+ let_it_be(:project4) { create(:project) }
+
+ let(:new_projects) { [project3, project4] }
+ let(:mutation_params) do
+ {
+ id: runner.to_global_id,
+ description: 'updated description',
+ associated_projects: new_projects.map { |project| project.to_global_id.to_s }
+ }
+ end
context 'with id set to project runner' do
- let(:mutation_params) do
- {
- id: runner.to_global_id,
- description: 'updated description',
- associated_projects: [project3.to_global_id.to_s]
- }
- end
+ let(:projects_with_maintainer_access) { original_projects + new_projects }
it 'updates runner attributes and project relationships', :aggregate_failures do
- expect_next_instance_of(
- ::Ci::Runners::SetRunnerAssociatedProjectsService,
- {
- runner: runner,
- current_user: admin_user,
- project_ids: [project3.id]
- }
- ) do |service|
- expect(service).to receive(:execute).and_call_original
- end
+ setup_service_expectations
expected_attributes = mutation_params.except(:id, :associated_projects)
@@ -112,57 +114,32 @@ RSpec.describe Mutations::Ci::Runner::Update, feature_category: :runner_fleet do
expect(response[:runner]).to be_an_instance_of(Ci::Runner)
expect(response[:runner]).to have_attributes(expected_attributes)
expect(runner.reload).to have_attributes(expected_attributes)
- expect(runner.projects).to match_array([project1, project3])
+ expect(runner.projects).to match_array([project1] + new_projects)
end
- context 'with user not allowed to assign runner' do
- before do
- allow(admin_user).to receive(:can?).with(:assign_runner, runner).and_return(false)
- end
+ context 'with missing permissions on one of the new projects' do
+ let(:projects_with_maintainer_access) { original_projects + [project3] }
it 'does not update runner', :aggregate_failures do
- expect_next_instance_of(
- ::Ci::Runners::SetRunnerAssociatedProjectsService,
- {
- runner: runner,
- current_user: admin_user,
- project_ids: [project3.id]
- }
- ) do |service|
- expect(service).to receive(:execute).and_call_original
- end
+ setup_service_expectations
expected_attributes = mutation_params.except(:id, :associated_projects)
response
- expect(response[:errors]).to match_array(['user not allowed to assign runner'])
+ expect(response[:errors]).to match_array(['user is not authorized to add runners to project'])
expect(response[:runner]).to be_nil
expect(runner.reload).not_to have_attributes(expected_attributes)
- expect(runner.projects).to match_array([project1, project2])
+ expect(runner.projects).to match_array(original_projects)
end
end
end
context 'with an empty list of projects' do
- let(:mutation_params) do
- {
- id: runner.to_global_id,
- associated_projects: []
- }
- end
+ let(:new_projects) { [] }
it 'removes project relationships', :aggregate_failures do
- expect_next_instance_of(
- ::Ci::Runners::SetRunnerAssociatedProjectsService,
- {
- runner: runner,
- current_user: admin_user,
- project_ids: []
- }
- ) do |service|
- expect(service).to receive(:execute).and_call_original
- end
+ setup_service_expectations
response
@@ -172,15 +149,9 @@ RSpec.describe Mutations::Ci::Runner::Update, feature_category: :runner_fleet do
end
end
- context 'with id set to instance runner' do
- let(:instance_runner) { create(:ci_runner, :instance) }
- let(:mutation_params) do
- {
- id: instance_runner.to_global_id,
- description: 'updated description',
- associated_projects: [project2.to_global_id.to_s]
- }
- end
+ context 'with id set to instance runner', :enable_admin_mode do
+ let_it_be(:user) { create(:user, :admin) }
+ let_it_be(:runner) { create(:ci_runner, :instance) }
it 'raises error', :aggregate_failures do
expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
@@ -188,6 +159,19 @@ RSpec.describe Mutations::Ci::Runner::Update, feature_category: :runner_fleet do
end
end
end
+
+ def setup_service_expectations
+ expect_next_instance_of(
+ ::Ci::Runners::SetRunnerAssociatedProjectsService,
+ {
+ runner: runner,
+ current_user: user,
+ project_ids: new_projects.map(&:id)
+ }
+ ) do |service|
+ expect(service).to receive(:execute).and_call_original
+ end
+ end
end
context 'with non-existing project ID in associatedProjects argument' do
diff --git a/spec/lib/gitlab/timeless_spec.rb b/spec/lib/gitlab/timeless_spec.rb
new file mode 100644
index 00000000000..d806349d326
--- /dev/null
+++ b/spec/lib/gitlab/timeless_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Timeless, feature_category: :shared do
+ let(:model) { build(:user) }
+
+ it 'disables record_timestamps temporarily' do
+ expect(model.record_timestamps).to eq(true)
+
+ Gitlab::Timeless.timeless(model) do |m|
+ expect(m.record_timestamps).to eq(false)
+ expect(model.record_timestamps).to eq(false)
+ end
+
+ expect(model.record_timestamps).to eq(true)
+ end
+
+ it 'does not record created_at' do
+ Gitlab::Timeless.timeless(model) do
+ model.save!(username: "#{model.username}-a")
+ end
+
+ expect(model.created_at).to be(nil)
+ end
+
+ it 'does not record updated_at' do
+ model.save!
+ previous = model.updated_at
+
+ Gitlab::Timeless.timeless(model) do
+ model.update!(username: "#{model.username}-a")
+ end
+
+ expect(model.updated_at).to eq(previous)
+ end
+end
diff --git a/spec/requests/projects/merge_requests_discussions_spec.rb b/spec/requests/projects/merge_requests_discussions_spec.rb
index 9933bf1545d..caf62c251b6 100644
--- a/spec/requests/projects/merge_requests_discussions_spec.rb
+++ b/spec/requests/projects/merge_requests_discussions_spec.rb
@@ -188,10 +188,10 @@ RSpec.describe 'merge requests discussions', feature_category: :source_code_mana
context 'when the diff note position changes' do
before do
# This replicates a position change wherein timestamps aren't updated
- # which is why `Gitlab::Timeless.timeless` is utilized. This is the
- # same approach being used in Discussions::UpdateDiffPositionService
- # which is responsible for updating the positions of diff discussions
- # when MR updates.
+ # which is why `save(touch: false)` is utilized. This is the same
+ # approach being used in Discussions::UpdateDiffPositionService which
+ # is responsible for updating the positions of diff discussions when
+ # MR updates.
first_note.position = Gitlab::Diff::Position.new(
old_path: first_note.position.old_path,
new_path: first_note.position.new_path,
@@ -200,7 +200,7 @@ RSpec.describe 'merge requests discussions', feature_category: :source_code_mana
diff_refs: first_note.position.diff_refs
)
- Gitlab::Timeless.timeless(first_note, &:save)
+ first_note.save!(touch: false)
end
it_behaves_like 'cache miss' do
diff --git a/spec/services/ci/runners/set_runner_associated_projects_service_spec.rb b/spec/services/ci/runners/set_runner_associated_projects_service_spec.rb
index 9921f9322bd..d952fca25a5 100644
--- a/spec/services/ci/runners/set_runner_associated_projects_service_spec.rb
+++ b/spec/services/ci/runners/set_runner_associated_projects_service_spec.rb
@@ -3,17 +3,19 @@
require 'spec_helper'
RSpec.describe ::Ci::Runners::SetRunnerAssociatedProjectsService, '#execute', feature_category: :runner_fleet do
- subject(:execute) { described_class.new(runner: runner, current_user: user, project_ids: project_ids).execute }
+ subject(:execute) do
+ described_class.new(runner: runner, current_user: user, project_ids: new_projects.map(&:id)).execute
+ end
let_it_be(:owner_project) { create(:project) }
let_it_be(:project2) { create(:project) }
- let_it_be(:original_projects) { [owner_project, project2] }
+ let(:original_projects) { [owner_project, project2] }
let(:runner) { create(:ci_runner, :project, projects: original_projects) }
context 'without user' do
let(:user) { nil }
- let(:project_ids) { [project2.id] }
+ let(:new_projects) { [project2] }
it 'does not call assign_to on runner and returns error response', :aggregate_failures do
expect(runner).not_to receive(:assign_to)
@@ -24,8 +26,8 @@ RSpec.describe ::Ci::Runners::SetRunnerAssociatedProjectsService, '#execute', fe
end
context 'with unauthorized user' do
- let(:user) { build(:user) }
- let(:project_ids) { [project2.id] }
+ let(:user) { create(:user) }
+ let(:new_projects) { [project2] }
it 'does not call assign_to on runner and returns error message' do
expect(runner).not_to receive(:assign_to)
@@ -35,15 +37,19 @@ RSpec.describe ::Ci::Runners::SetRunnerAssociatedProjectsService, '#execute', fe
end
end
- context 'with admin user', :enable_admin_mode do
- let_it_be(:user) { create(:user, :admin) }
+ context 'with authorized user' do
+ let_it_be(:project3) { create(:project) }
+ let_it_be(:project4) { create(:project) }
+
+ let(:projects_with_maintainer_access) { original_projects }
- let(:project3) { create(:project) }
- let(:project4) { create(:project) }
+ before do
+ projects_with_maintainer_access.each { |project| project.add_maintainer(user) }
+ end
- context 'with successful requests' do
+ shared_context 'with successful requests' do
context 'when disassociating a project' do
- let(:project_ids) { [project3.id, project4.id] }
+ let(:new_projects) { [project3, project4] }
it 'reassigns associated projects and returns success response' do
expect(execute).to be_success
@@ -51,12 +57,12 @@ RSpec.describe ::Ci::Runners::SetRunnerAssociatedProjectsService, '#execute', fe
runner.reload
expect(runner.owner_project).to eq(owner_project)
- expect(runner.projects.ids).to match_array([owner_project.id] + project_ids)
+ expect(runner.projects.ids).to match_array([owner_project.id] + new_projects.map(&:id))
end
end
context 'when disassociating no projects' do
- let(:project_ids) { [project2.id, project3.id] }
+ let(:new_projects) { [project2, project3] }
it 'reassigns associated projects and returns success response' do
expect(execute).to be_success
@@ -64,12 +70,12 @@ RSpec.describe ::Ci::Runners::SetRunnerAssociatedProjectsService, '#execute', fe
runner.reload
expect(runner.owner_project).to eq(owner_project)
- expect(runner.projects.ids).to match_array([owner_project.id] + project_ids)
+ expect(runner.projects.ids).to match_array([owner_project.id] + new_projects.map(&:id))
end
end
context 'when disassociating all projects' do
- let(:project_ids) { [] }
+ let(:new_projects) { [] }
it 'reassigns associated projects and returns success response' do
expect(execute).to be_success
@@ -82,28 +88,47 @@ RSpec.describe ::Ci::Runners::SetRunnerAssociatedProjectsService, '#execute', fe
end
end
- context 'with failing assign_to requests' do
- let(:project_ids) { [project3.id, project4.id] }
+ shared_context 'with failing destroy calls' do
+ let(:new_projects) { [project3, project4] }
it 'returns error response and rolls back transaction' do
- expect(runner).to receive(:assign_to).with(project4, user).once.and_return(false)
+ allow_next_found_instance_of(Ci::RunnerProject) do |runner_project|
+ allow(runner_project).to receive(:destroy).and_return(false)
+ end
expect(execute).to be_error
expect(runner.reload.projects).to eq(original_projects)
end
end
- context 'with failing destroy calls' do
- let(:project_ids) { [project3.id, project4.id] }
+ context 'with maintainer user' do
+ let(:user) { create(:user) }
+ let(:projects_with_maintainer_access) { original_projects + new_projects }
- it 'returns error response and rolls back transaction' do
- allow_next_found_instance_of(Ci::RunnerProject) do |runner_project|
- allow(runner_project).to receive(:destroy).and_return(false)
- end
+ it_behaves_like 'with successful requests'
+ it_behaves_like 'with failing destroy calls'
- expect(execute).to be_error
- expect(runner.reload.projects).to eq(original_projects)
+ context 'when associating new projects' do
+ let(:new_projects) { [project3, project4] }
+
+ context 'with missing permissions on one of the new projects' do
+ let(:projects_with_maintainer_access) { original_projects + [project3] }
+
+ it 'returns error response and rolls back transaction' do
+ expect(execute).to be_error
+ expect(execute.errors).to contain_exactly('user is not authorized to add runners to project')
+ expect(runner.reload.projects).to eq(original_projects)
+ end
+ end
end
end
+
+ context 'with admin user', :enable_admin_mode do
+ let(:user) { create(:user, :admin) }
+ let(:projects_with_maintainer_access) { original_projects + new_projects }
+
+ it_behaves_like 'with successful requests'
+ it_behaves_like 'with failing destroy calls'
+ end
end
end
diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml
index 7346ba59cbe..4efcb914173 100644
--- a/spec/support/rspec_order_todo.yml
+++ b/spec/support/rspec_order_todo.yml
@@ -10008,7 +10008,6 @@
- './spec/workers/ci/build_schedule_worker_spec.rb'
- './spec/workers/ci/build_trace_chunk_flush_worker_spec.rb'
- './spec/workers/ci/cancel_pipeline_worker_spec.rb'
-- './spec/workers/ci/create_cross_project_pipeline_worker_spec.rb'
- './spec/workers/ci/create_downstream_pipeline_worker_spec.rb'
- './spec/workers/ci/daily_build_group_report_results_worker_spec.rb'
- './spec/workers/ci/delete_objects_worker_spec.rb'
diff --git a/spec/workers/ci/create_cross_project_pipeline_worker_spec.rb b/spec/workers/ci/create_cross_project_pipeline_worker_spec.rb
deleted file mode 100644
index 6f4bfe897a8..00000000000
--- a/spec/workers/ci/create_cross_project_pipeline_worker_spec.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Ci::CreateCrossProjectPipelineWorker, feature_category: :continuous_integration do
- let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project) }
- let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
-
- let(:bridge) { create(:ci_bridge, user: user, pipeline: pipeline) }
-
- let(:service) { double('pipeline creation service') }
-
- describe '#perform' do
- context 'when bridge exists' do
- it 'calls cross project pipeline creation service' do
- expect(Ci::CreateDownstreamPipelineService)
- .to receive(:new)
- .with(project, user)
- .and_return(service)
-
- expect(service).to receive(:execute).with(bridge)
-
- described_class.new.perform(bridge.id)
- end
- end
-
- context 'when bridge does not exist' do
- it 'does nothing' do
- expect(Ci::CreateDownstreamPipelineService)
- .not_to receive(:new)
-
- described_class.new.perform(non_existing_record_id)
- end
- end
- end
-end
diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb
index 105fbcc55d1..c098ed32f4b 100644
--- a/spec/workers/every_sidekiq_worker_spec.rb
+++ b/spec/workers/every_sidekiq_worker_spec.rb
@@ -156,7 +156,6 @@ RSpec.describe 'Every Sidekiq worker', feature_category: :shared do
'Ci::BuildPrepareWorker' => 3,
'Ci::BuildScheduleWorker' => 3,
'Ci::BuildTraceChunkFlushWorker' => 3,
- 'Ci::CreateCrossProjectPipelineWorker' => 3,
'Ci::CreateDownstreamPipelineWorker' => 3,
'Ci::DailyBuildGroupReportResultsWorker' => 3,
'Ci::DeleteObjectsWorker' => 0,
diff --git a/yarn.lock b/yarn.lock
index b3a8deae813..c225249da86 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1027,10 +1027,10 @@
core-js "^3.6.5"
ramda "^0.27.2"
-"@discoveryjs/json-ext@^0.5.0":
- version "0.5.6"
- resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f"
- integrity sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA==
+"@discoveryjs/json-ext@0.5.7", "@discoveryjs/json-ext@^0.5.0":
+ version "0.5.7"
+ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
+ integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
"@eslint-community/eslint-utils@^4.2.0":
version "4.2.0"
@@ -3224,10 +3224,10 @@ babel-jest@^28.1.3:
graceful-fs "^4.2.9"
slash "^3.0.0"
-babel-loader@^8.2.5:
- version "8.2.5"
- resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.5.tgz#d45f585e654d5a5d90f5350a779d7647c5ed512e"
- integrity sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ==
+babel-loader@^8.3.0:
+ version "8.3.0"
+ resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.3.0.tgz#124936e841ba4fe8176786d6ff28add1f134d6a8"
+ integrity sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==
dependencies:
find-cache-dir "^3.3.1"
loader-utils "^2.0.0"
@@ -12834,11 +12834,12 @@ webidl-conversions@^7.0.0:
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a"
integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==
-webpack-bundle-analyzer@^4.6.1:
- version "4.6.1"
- resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.6.1.tgz#bee2ee05f4ba4ed430e4831a319126bb4ed9f5a6"
- integrity sha512-oKz9Oz9j3rUciLNfpGFjOb49/jEpXNmWdVH8Ls//zNcnLlQdTGXQQMsBbb/gR7Zl8WNLxVCq+0Hqbx3zv6twBw==
+webpack-bundle-analyzer@^4.8.0:
+ version "4.8.0"
+ resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.8.0.tgz#951b8aaf491f665d2ae325d8b84da229157b1d04"
+ integrity sha512-ZzoSBePshOKhr+hd8u6oCkZVwpVaXgpw23ScGLFpR6SjYI7+7iIWYarjN6OEYOfRt8o7ZyZZQk0DuMizJ+LEIg==
dependencies:
+ "@discoveryjs/json-ext" "0.5.7"
acorn "^8.0.4"
acorn-walk "^8.0.0"
chalk "^4.1.0"