From 001c23394e75d0e797261527779294ad11542f6d Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Mon, 4 Sep 2023 15:08:40 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- GITALY_SERVER_VERSION | 2 +- .../components/action_buttons.vue | 55 ++++------ .../components/extensions/base.vue | 6 +- .../components/extensions/child_content.vue | 1 - .../components/widget/dynamic_content.vue | 1 - .../components/widget/widget.vue | 1 - .../components/widget/widget_content_row.vue | 6 +- app/models/organizations/organization.rb | 1 + app/models/project.rb | 1 + config/gitlab_loose_foreign_keys.yml | 4 + ...0230822064649_add_organization_id_to_project.rb | 11 ++ ...2064841_prepare_index_for_org_id_on_projects.rb | 13 +++ db/schema_migrations/20230822064649 | 1 + db/schema_migrations/20230822064841 | 1 + db/structure.sql | 3 +- .../cells/impacted_features/your-work.md | 2 +- .../blueprints/remote_development/index.md | 49 ++++++--- doc/development/documentation/review_apps.md | 1 + doc/development/integrations/jenkins.md | 2 +- doc/integration/jenkins.md | 19 ++-- doc/tutorials/plan_and_track.md | 2 - doc/update/versions/gitlab_15_changes.md | 118 ++++++++++++++++++++- doc/user/analytics/index.md | 49 ++++----- locale/gitlab.pot | 4 +- qa/gdk/Dockerfile.gdk | 2 +- scripts/trigger-build.rb | 2 + spec/db/schema_spec.rb | 3 +- ...user_closes_reopens_merge_request_state_spec.rb | 81 +++++--------- .../components/action_buttons.js | 43 -------- .../components/action_buttons_spec.js | 61 +++++++++++ .../components/states/mr_widget_merged_spec.js | 6 +- spec/lib/gitlab/import_export/all_models.yml | 1 + spec/models/organizations/organization_spec.rb | 1 + spec/models/project_spec.rb | 8 ++ spec/requests/api/project_attributes.yml | 1 + spec/scripts/trigger-build_spec.rb | 12 +++ spec/support/capybara_wait_for_all_requests.rb | 12 +-- .../capybara_wait_for_all_requests_spec.rb | 16 +-- 38 files changed, 378 insertions(+), 224 deletions(-) create mode 100644 db/migrate/20230822064649_add_organization_id_to_project.rb create mode 100644 db/post_migrate/20230822064841_prepare_index_for_org_id_on_projects.rb create mode 100644 db/schema_migrations/20230822064649 create mode 100644 db/schema_migrations/20230822064841 delete mode 100644 spec/frontend/vue_merge_request_widget/components/action_buttons.js create mode 100644 spec/frontend/vue_merge_request_widget/components/action_buttons_spec.js diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index ea0b31f76d6..5edeb65a718 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -e1b67571f0e4f74773573628ebe047cba9e0702a +8a092fc4eaed286f00897967cd571449013e41c1 diff --git a/app/assets/javascripts/vue_merge_request_widget/components/action_buttons.vue b/app/assets/javascripts/vue_merge_request_widget/components/action_buttons.vue index 952ff9b18e9..c49c1316b1b 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/action_buttons.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/action_buttons.vue @@ -4,32 +4,26 @@ import { GlPopover, GlSprintf, GlLink, - GlDropdown, - GlDropdownItem, + GlDisclosureDropdown, GlTooltipDirective, } from '@gitlab/ui'; -import { sprintf, __ } from '~/locale'; export default { + name: 'ActionButtons', components: { GlButton, GlPopover, GlSprintf, GlLink, - GlDropdown, - GlDropdownItem, + GlDisclosureDropdown, }, directives: { GlTooltip: GlTooltipDirective, }, props: { - widget: { - type: String, - required: false, - default: '', - }, tertiaryButtons: { type: Array, + // fix `spec/frontend/vue_merge_request_widget/mr_widget_options_spec.js` before making this required required: false, default: () => [], }, @@ -41,17 +35,26 @@ export default { }; }, computed: { - dropdownLabel() { - if (!this.widget) return undefined; - - return sprintf(__('%{widget} options'), { widget: this.widget }); - }, hasOneOption() { return this.tertiaryButtons.length === 1; }, hasMultipleOptions() { return this.tertiaryButtons.length > 1; }, + dropdownItems() { + return this.tertiaryButtons.map((item) => { + return { + ...item, + text: item.text, + href: item.href, + extraAttrs: { + dataClipboardText: item.dataClipboardText, + dataMethod: item.dataMethod, + target: item.target, + }, + }; + }); + }, }, methods: { onClickAction(action) { @@ -135,32 +138,18 @@ export default { - +
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/widget/widget_content_row.vue b/app/assets/javascripts/vue_merge_request_widget/components/widget/widget_content_row.vue index e67924d28ab..bb82da7796a 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/widget/widget_content_row.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/widget/widget_content_row.vue @@ -128,11 +128,7 @@ export default { > - +
diff --git a/app/models/organizations/organization.rb b/app/models/organizations/organization.rb index 489fd6e0da7..893b08d7872 100644 --- a/app/models/organizations/organization.rb +++ b/app/models/organizations/organization.rb @@ -10,6 +10,7 @@ module Organizations has_many :namespaces has_many :groups + has_many :projects has_one :settings, class_name: "OrganizationSetting" diff --git a/app/models/project.rb b/app/models/project.rb index cb1468a8d0c..4e69cdeff13 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -165,6 +165,7 @@ class Project < ApplicationRecord # Relations belongs_to :pool_repository belongs_to :creator, class_name: 'User' + belongs_to :organization, class_name: 'Organizations::Organization' belongs_to :group, -> { where(type: Group.sti_name) }, foreign_key: 'namespace_id' belongs_to :namespace # Sync deletion via DB Trigger to ensure we do not have diff --git a/config/gitlab_loose_foreign_keys.yml b/config/gitlab_loose_foreign_keys.yml index 6bd6f99a134..c12a2dfda7b 100644 --- a/config/gitlab_loose_foreign_keys.yml +++ b/config/gitlab_loose_foreign_keys.yml @@ -287,6 +287,10 @@ pages_deployments: - table: p_ci_builds column: ci_build_id on_delete: async_nullify +projects: + - table: organizations + column: organization_id + on_delete: async_nullify requirements_management_test_reports: - table: ci_builds column: build_id diff --git a/db/migrate/20230822064649_add_organization_id_to_project.rb b/db/migrate/20230822064649_add_organization_id_to_project.rb new file mode 100644 index 00000000000..9607f711981 --- /dev/null +++ b/db/migrate/20230822064649_add_organization_id_to_project.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class AddOrganizationIdToProject < Gitlab::Database::Migration[2.1] + DEFAULT_ORGANIZATION_ID = 1 + + enable_lock_retries! + + def change + add_column :projects, :organization_id, :bigint, default: DEFAULT_ORGANIZATION_ID, null: true # rubocop:disable Migration/AddColumnsToWideTables + end +end diff --git a/db/post_migrate/20230822064841_prepare_index_for_org_id_on_projects.rb b/db/post_migrate/20230822064841_prepare_index_for_org_id_on_projects.rb new file mode 100644 index 00000000000..1f822a440a4 --- /dev/null +++ b/db/post_migrate/20230822064841_prepare_index_for_org_id_on_projects.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class PrepareIndexForOrgIdOnProjects < Gitlab::Database::Migration[2.1] + INDEX_NAME = 'index_projects_on_organization_id' + + def up + prepare_async_index :projects, :organization_id, name: INDEX_NAME + end + + def down + unprepare_async_index :projects, :organization_id, name: INDEX_NAME + end +end diff --git a/db/schema_migrations/20230822064649 b/db/schema_migrations/20230822064649 new file mode 100644 index 00000000000..449dd984431 --- /dev/null +++ b/db/schema_migrations/20230822064649 @@ -0,0 +1 @@ +b892940441125e854d08e24906e4b6287f8359b4ad374be5b141b43cfdcc1354 \ No newline at end of file diff --git a/db/schema_migrations/20230822064841 b/db/schema_migrations/20230822064841 new file mode 100644 index 00000000000..2922af9c573 --- /dev/null +++ b/db/schema_migrations/20230822064841 @@ -0,0 +1 @@ +e025eb64ab8b9ece1a18c845024db272a1859757734948609c134f6dfee93884 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 9c1fc3b5500..805745d4470 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -21836,7 +21836,8 @@ CREATE TABLE projects ( autoclose_referenced_issues boolean, suggestion_commit_message character varying(255), project_namespace_id bigint, - hidden boolean DEFAULT false NOT NULL + hidden boolean DEFAULT false NOT NULL, + organization_id bigint DEFAULT 1 ); CREATE SEQUENCE projects_id_seq diff --git a/doc/architecture/blueprints/cells/impacted_features/your-work.md b/doc/architecture/blueprints/cells/impacted_features/your-work.md index 413c8a42d9d..5a72d50fbea 100644 --- a/doc/architecture/blueprints/cells/impacted_features/your-work.md +++ b/doc/architecture/blueprints/cells/impacted_features/your-work.md @@ -44,7 +44,7 @@ Your Work will be scoped to an Organization, giving the user an overview of all - Issue, Merge request and To-Do list counts will refer to the selected Organization. - The URL will reference the Organization with the following URL structure `/-/organizations//dashboard`. -- The default URL `/dashboard` will refer to the default Organization. +- The default URL `/dashboard` will refer to the [Home Organization](../impacted_features/user-profile.md#3-proposal). ## 4. Evaluation diff --git a/doc/architecture/blueprints/remote_development/index.md b/doc/architecture/blueprints/remote_development/index.md index c7d1ec29add..d64fbfc8b55 100644 --- a/doc/architecture/blueprints/remote_development/index.md +++ b/doc/architecture/blueprints/remote_development/index.md @@ -485,7 +485,11 @@ RestartRequested -left-> Running : status=Running ## Injecting environment variables and files into a workspace -Like CI, there is a need to inject environment variables and files into a workspace. These environment variables and files will be frozen in time during workspace creation to ensure the same values are injected into the workspace every time it starts/restarts. Thus, a new database table, on the lines of `ci_job_variables` will be required. This table will contain the following columns - +Like CI, there is a need to inject environment variables and files into a workspace. +These environment variables and files will be frozen in time during workspace creation to ensure the same values +are injected into the workspace every time it starts/restarts. +Thus, a new database table, on the lines of `ci_job_variables` will be required. +This table will contain the following columns - - `key` - To store the name of the environment variable or the file. - `encrypted_value` - To store the encrypted value of the environment variable or the file. @@ -493,29 +497,40 @@ Like CI, there is a need to inject environment variables and files into a worksp - `workspace_id` - To reference the workspace the environment variable or the file is to be injected into. - `variable_type` - To store whether this data is to be injected as an environment variable or a file. -To perform the encryption, a secret key would be required. This would be uniquely generated for each workpsace upon creation. -Having a unique secret key which is used for encrypting the corresponding workspace's environment variable and file data in the workspace, improves the security profile. +To perform the encryption, the GitLab instance level secret key is used. The data about the environment variables +and files will only be sent to the Agent when required i.e. -Because of the nature of reconciliation loop between Agent and Rails, it is not scalable to decrypt these values at Rails side for each request. -Instead, the `key`, `encrypted_value` and `encrypted_value_iv` of each environment variable of the workspace are sent to the Agent along with the workspace's `secret_key` -for the Agent to decrypt them in place. +- When new workspace creation request has been received from the user and an Agent initiates a Partial Reconciliation request +- When an Agent initiates a Full Reconciliation request -To optimize this further, the data about the environment variables and files along with the secret key will only be sent when required i.e. +More details about the implementation details can be found in this [epic](https://gitlab.com/groups/gitlab-org/-/epics/10882). -- When new workspace creation request has been received from the user and an Agent initiates a Partial Reonciliation request -- When an Agent initiates a Full Reconciliation request +We need to keep in mind potential performance concerns of decrypting workspace variables on the Rails side, +and perform benchmarks of what scale we will reach unacceptably long request times for a reconcile request. -When a workspace is created from a project, it will inherit all the variables from the group/subgroup/project hierarchy which are defined under -[`Settings > CI/CD > Variables`](../../../ci/variables/index.md#define-a-cicd-variable-in-the-ui). This aspect will be generalized to allow for defining `Variables` -which will be inherited in both CI/CD and Workspaces. +e.g. a reconcile request for 100 workspaces with 20 encrypted values each == 2000 decryptions in a single request. -A user will also be able to define, at a user level, environment variables and files to be injected into each workspace created by them. +More details about the benchmarking can be found in this [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/421504). -When a new workspace is created, a new personal access token associated to the user who created the workspace will be generated. -This personal access token will be tied to the lifecycle of the workspace and will be injected into the workspace as an environment variable or a file -to allow for cloning private projects and supporting transparent Git operations from within the workspace out-of-the-box among other things. +When a workspace is created from a project, it will inherit all the variables from the group/subgroup/project hierarchy +which are defined under [`Settings > CI/CD > Variables`](../../../ci/variables/index.md#define-a-cicd-variable-in-the-ui). +This aspect will be generalized to allow for defining `Variables` which will be inherited in both CI/CD and Workspaces. +A user will also be able to define, at a user level, environment variables and files to be injected into each +workspace created by them. While creating a workspace, a user would be able to override any environment variable +or file that is inherited from the group/subgroup/project/user hierarchy. -More details about the implementation details can be found in this [epic](https://gitlab.com/groups/gitlab-org/-/epics/10882). +## Git operations from within a workspace + +When a new workspace is created, a new personal access token associated to the user who created the workspace +will be generated. This personal access token will be tied to the lifecycle of the workspace and will be injected +into the workspace as a file to allow for cloning private projects and supporting transparent Git operations from +within the workspace out-of-the-box among other things using a +[custom Git credential helper](https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage). + +[Investigation](https://gitlab.com/gitlab-org/gitlab/-/issues/421289#note_1511631931) into using +ephemeral tokens(JWTs/OAuth/OIDC/etc.) instead of Personal Access Tokens revealed the need to have a common +JWT Authentication/Authorization layer at GitLab which can be tracked in this [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/421983). +Once such a feature is available, Personal Access Tokens for each workspace would be replaced with JWT tokens. ## Workspace user traffic authentication and authorization diff --git a/doc/development/documentation/review_apps.md b/doc/development/documentation/review_apps.md index adc9d727844..483145d1f44 100644 --- a/doc/development/documentation/review_apps.md +++ b/doc/development/documentation/review_apps.md @@ -16,6 +16,7 @@ Review apps are enabled for the following projects: - [Omnibus GitLab](https://gitlab.com/gitlab-org/omnibus-gitlab) - [GitLab Runner](https://gitlab.com/gitlab-org/gitlab-runner) - [GitLab Charts](https://gitlab.com/gitlab-org/charts/gitlab) +- [GitLab Operator](https://gitlab.com/gitlab-org/cloud-native/gitlab-operator) Alternatively, check the [`gitlab-docs` development guide](https://gitlab.com/gitlab-org/gitlab-docs/blob/main/README.md#development-when-contributing-to-gitlab-documentation) or [the GDK documentation](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/main/doc/howto/gitlab_docs.md) diff --git a/doc/development/integrations/jenkins.md b/doc/development/integrations/jenkins.md index 73b77051d9c..2f88abda21a 100644 --- a/doc/development/integrations/jenkins.md +++ b/doc/development/integrations/jenkins.md @@ -55,7 +55,7 @@ To set up the Jenkins project you intend to run your build on, read You can configure your integration between Jenkins and GitLab: -- With the [recommended approach for Jenkins integration](../../integration/jenkins.md#configure-a-jenkins-integration-recommended). +- With the [recommended approach for Jenkins integration](../../integration/jenkins.md#configure-a-jenkins-integration). - [Using a webhook](../../integration/jenkins.md#configure-a-webhook). ## Test your setup diff --git a/doc/integration/jenkins.md b/doc/integration/jenkins.md index 462e9137c9d..e01541f5317 100644 --- a/doc/integration/jenkins.md +++ b/doc/integration/jenkins.md @@ -113,10 +113,10 @@ Set up the Jenkins project you intend to run your build on. Configure the GitLab integration with Jenkins in one of the following ways. -### Configure a Jenkins integration (recommended) +### Configure a Jenkins integration -GitLab recommends this approach for Jenkins integrations because it is easier to configure -than the [webhook integration](#configure-a-webhook). +You should use this approach for Jenkins integrations if you can provide GitLab +with your Jenkins server URL and authentication information. 1. On the left sidebar, select **Search or go to** and find your project. 1. Select **Settings > Integrations**. @@ -129,25 +129,24 @@ than the [webhook integration](#configure-a-webhook). 1. Enter the **Jenkins server URL**. 1. Optional. Clear the **Enable SSL verification** checkbox to disable [SSL verification](../user/project/integrations/index.md#manage-ssl-verification). 1. Enter the **Project name**. - The project name should be URL-friendly, where spaces are replaced with underscores. To ensure the project name is valid, copy it from your browser's address bar while viewing the Jenkins project. -1. If your Jenkins server requires - authentication, enter the **Username** and **Password**. +1. If your Jenkins server requires authentication, enter the **Username** and **Password**. 1. Optional. Select **Test settings**. 1. Select **Save changes**. ### Configure a webhook -If you are unable to provide GitLab with your Jenkins server login, you can use this option -to integrate GitLab and Jenkins. +If you cannot [provide GitLab with your Jenkins server URL and authentication information](#configure-a-jenkins-integration), you can configure a webhook to integrate GitLab and Jenkins. 1. In the configuration of your Jenkins job, in the GitLab configuration section, select **Advanced**. 1. Under **Secret Token**, select **Generate**. 1. Copy the token, and save the job configuration. -1. In GitLab, create a webhook for your project, enter the trigger URL - (such as `https://JENKINS_URL/project/YOUR_JOB`) and paste the token in **Secret Token**. +1. In GitLab: + - [Create a webhook for your project](../user/project/integrations/webhooks.md#configure-a-webhook-in-gitlab). + - Enter the trigger URL (such as `https://JENKINS_URL/project/YOUR_JOB`). + - Paste the token in **Secret Token**. 1. To test the webhook, select **Test**. ## Related topics diff --git a/doc/tutorials/plan_and_track.md b/doc/tutorials/plan_and_track.md index 7dcafbd26ce..c5c2919cac7 100644 --- a/doc/tutorials/plan_and_track.md +++ b/doc/tutorials/plan_and_track.md @@ -12,8 +12,6 @@ issues, epics, and more. | Topic | Description | Good for beginners | |-------|-------------|--------------------| | [GitLab Agile Project Management](https://levelup.gitlab.com/courses/gitlab-agile-project-management) | Learn how to use planning features to manage your projects in this self-paced course. | **{star}** | -| [Create a project from a template](https://gitlab.com/projects/new#create_from_template) | Choose a project template and create a project with files to get you started. | | -| [Migrate to GitLab](../user/project/import/index.md) | If you are coming to GitLab from another platform, you can import or convert your projects. | | | [Build a protected workflow for your project](protected_workflow/index.md) | Set up a workflow for your teams, and enforce protections with approval rules. | | | [Run an agile iteration](agile_sprint/index.md) | Use group, projects, and iterations to run an agile development iteration. | | [Set up a single project for issue triage](issue_triage/index.md) | Use labels to set up a project for issue triage. | **{star}** | diff --git a/doc/update/versions/gitlab_15_changes.md b/doc/update/versions/gitlab_15_changes.md index 672c7b1bd81..6ebbeeb1d32 100644 --- a/doc/update/versions/gitlab_15_changes.md +++ b/doc/update/versions/gitlab_15_changes.md @@ -21,6 +21,18 @@ For more information about upgrading GitLab Helm Chart, see [the release notes f - **Upgrade to patch release 15.11.3 or later**. This avoids [issue 408304](https://gitlab.com/gitlab-org/gitlab/-/issues/408304) when upgrading from 15.5.0 and earlier. +### Linux package installations + +In GitLab 15.11, PostgreSQL will automatically be upgraded to 13.x except for the following cases: + +- You are running the database in high availability using Patroni. +- Your database nodes are part of a GitLab Geo configuration. +- You have specifically [opted out](https://docs.gitlab.com/omnibus/settings/database.html#opt-out-of-automatic-postgresql-upgrades) from automatically upgrading PostgreSQL. +- You have `postgresql['version'] = 12` in your `/etc/gitlab/gitlab.rb`. + +Fault-tolerant and Geo installations support manual upgrades to PostgreSQL 13, +see [Packaged PostgreSQL deployed in an HA/Geo Cluster](https://docs.gitlab.com/omnibus/settings/database.html#packaged-postgresql-deployed-in-an-hageo-cluster). + ### Geo installations **(PREMIUM SELF)** - Some project imports do not initialize wiki repositories on project creation. See @@ -385,6 +397,14 @@ For more information about upgrading GitLab Helm Chart, see [the release notes f to GitLab 15.6.2. The issue can also be worked around: [read about how to create these indexes](https://gitlab.com/gitlab-org/gitlab/-/issues/378343#note_1199863087). +### Linux package installations + +In GitLab 15.6, the [PostgreSQL versions shipped with `omnibus-gitlab` packages](../../administration/package_information/postgresql_versions.md) +have been upgraded to 12.12 and 13.8. Unless +[explicitly opted out](https://docs.gitlab.com/omnibus/settings/database.html#automatic-restart-when-the-postgresql-version-changes), +this can cause an automatic restart of the PostgreSQL service, and can +potentially cause downtime. + ### Geo installations **(PREMIUM SELF)** - `pg_upgrade` fails to upgrade the bundled PostregSQL database to version 13. See @@ -682,8 +702,6 @@ A [license caching issue](https://gitlab.com/gitlab-org/gitlab/-/issues/376706) - The [certificate-based Kubernetes integration (DEPRECATED)](../../user/infrastructure/clusters/index.md#certificate-based-kubernetes-integration-deprecated) is disabled by default, but you can be re-enable it through the [`certificate_based_clusters` feature flag](../../administration/feature_flags.md#how-to-enable-and-disable-features-behind-flags) until GitLab 16.0. - When you use the GitLab Helm Chart project with a custom `serviceAccount`, ensure it has `get` and `list` permissions for the `serviceAccount` and `secret` resources. - The `FF_GITLAB_REGISTRY_HELPER_IMAGE` [feature flag](../../administration/feature_flags.md#enable-or-disable-the-feature) is removed and helper images are always pulled from GitLab Registry. -- The `AES256-GCM-SHA384` SSL cipher is no longer allowed by NGINX. - See how you can [add the cipher back](https://docs.gitlab.com/omnibus/update/gitlab_15_changes.html#aes256-gcm-sha384-ssl-cipher-no-longer-allowed-by-default-by-nginx) to the allow list. ### Linux package installations @@ -693,6 +711,102 @@ A [license caching issue](https://gitlab.com/gitlab-org/gitlab/-/issues/376706) than `/`. - Use `gitaly['custom_hooks_dir']` in `gitlab.rb` ([introduced in 14.3](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/4208)) for Omnibus GitLab. This replaces `gitlab_shell['custom_hooks_dir']`. +- PostgreSQL 13.6 is being shipped as the default version for fresh installs and + 12.10 for upgrades. You can manually upgrade to PostgreSQL 13.6 following the + [upgrade docs](https://docs.gitlab.com/omnibus/settings/database.html#gitlab-150-and-later). + Because of underlying structural changes, the running PostgreSQL process + **_must_** be restarted when it is upgraded before running database + migrations. If automatic restart is skipped, you must run the following + command before migrations are run: + + ```shell + # If using PostgreSQL + sudo gitlab-ctl restart postgresql + + # If using Patroni for Database replication + sudo gitlab-ctl restart patroni + ``` + + If PostgreSQL is not restarted, you might face + [errors related to loading libraries](https://docs.gitlab.com/omnibus/settings/database.html#could-not-load-library-plpgsqlso). + +- Starting with GitLab 15.0, `postgresql` and `geo-postgresql` services are + automatically restarted when the PostgreSQL version changes. Restarting + PostgreSQL services causes downtime due to the temporary unavailability of the + database for operations. While this restart is mandatory for proper functioning + of the Database services, you might want more control over when the PostgreSQL + is restarted. For that purpose, you can choose to skip the automatic restarts as + part of `gitlab-ctl reconfigure` and manually restart the services. + + To skip automatic restarts as part of GitLab 15.0 upgrade, perform the following + steps before the upgrade: + + 1. Edit `/etc/gitlab/gitlab.rb` and add the following line: + + ```ruby + # For PostgreSQL/Patroni + postgresql['auto_restart_on_version_change'] = false + + # For Geo PostgreSQL + geo_postgresql['auto_restart_on_version_change'] = false + ``` + + 1. Reconfigure GitLab: + + ```shell + sudo gitlab-ctl reconfigure + ``` + + NOTE: + It is mandatory to restart PostgreSQL when underlying version changes, to avoid + errors like the [one related to loading necessary libraries](https://docs.gitlab.com/omnibus/settings/database.html#could-not-load-library-plpgsqlso) + that can cause downtime. So, if you skip the automatic restarts using the above + method, ensure that you restart the services manually before upgrading to GitLab + 15.0. + +- Starting with GitLab 15.0, the `AES256-GCM-SHA384` SSL cipher will not be allowed by + NGINX by default. If you require this cipher (for example, if you use + [AWS's Classic Load Balancer](https://docs.aws.amazon.com/en_en/elasticloadbalancing/latest/classic/elb-ssl-security-policy.html#ssl-ciphers)), + you can add the cipher back to the allow list by following the steps below: + + 1. Edit `/etc/gitlab/gitlab.rb` and add the following line: + + ```ruby + nginx['ssl_ciphers'] = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:AES256-GCM-SHA384" + ``` + + 1. Reconfigure GitLab: + + ```shell + sudo gitlab-ctl reconfigure + ``` + +- Support for Gitaly's internal socket path is removed. + In GitLab 14.10, Gitaly introduced a new directory that holds all runtime + data Gitaly requires to operate correctly. This new directory replaces the + old internal socket directory, and consequentially the usage of + `gitaly['internal_socket_dir']` was deprecated in favor of + `gitaly['runtime_dir']`. + + The old `gitaly['internal_socket_dir']` configuration was removed in this release. + +- Background uploads settings for object storage are removed. + Object storage now preferentially uses direct uploads. + + The following keys are no longer supported in `/etc/gitlab/gitlab.rb`: + + - `gitlab_rails['artifacts_object_store_direct_upload']` + - `gitlab_rails['artifacts_object_store_background_upload']` + - `gitlab_rails['external_diffs_object_store_direct_upload']` + - `gitlab_rails['external_diffs_object_store_background_upload']` + - `gitlab_rails['lfs_object_store_direct_upload']` + - `gitlab_rails['lfs_object_store_background_upload']` + - `gitlab_rails['uploads_object_store_direct_upload']` + - `gitlab_rails['uploads_object_store_background_upload']` + - `gitlab_rails['packages_object_store_direct_upload']` + - `gitlab_rails['packages_object_store_background_upload']` + - `gitlab_rails['dependency_proxy_object_store_direct_upload']` + - `gitlab_rails['dependency_proxy_object_store_background_upload']` ### Self-compiled installations diff --git a/doc/user/analytics/index.md b/doc/user/analytics/index.md index 9e99d9aeaaf..023c1cd81fc 100644 --- a/doc/user/analytics/index.md +++ b/doc/user/analytics/index.md @@ -6,57 +6,52 @@ info: To determine the technical writer assigned to the Stage/Group associated w # Analyze GitLab usage **(FREE ALL)** -## Instance-level analytics +GitLab provides different types of analytics insights at the instance, group, and project level. -Instance-level analytics make it possible to aggregate analytics across -GitLab, so that users can view information across multiple projects and groups -in one place. +## Instance-level analytics -For more information, see [instance-level analytics](../admin_area/analytics/index.md). +Use [instance-level analytics](../../administration/analytics/index.md) to aggregate analytics across GitLab, +so that you can view information across multiple projects and groups in one place. ## Group-level analytics > Moved to GitLab Premium in 13.9. -GitLab provides several analytics features at the group level. Some of these features require you to use a higher tier than GitLab Free. +Use group-level analytics to get insights into your groups': -- [Application Security](../application_security/security_dashboard/index.md) -- [Contribution](../group/contribution_analytics/index.md) -- [DevOps Adoption](../group/devops_adoption/index.md) +- [Security Dashboards](../application_security/security_dashboard/index.md) +- [Contribution analytics](../group/contribution_analytics/index.md) +- [DevOps adoption](../group/devops_adoption/index.md) - [Insights](../group/insights/index.md) -- [Issue](../group/issues_analytics/index.md) -- [Productivity](productivity_analytics.md) -- [Repositories](../group/repositories_analytics/index.md) -- [Value Stream Management Analytics](../group/value_stream_analytics/index.md), and [Value Stream Management Dashboard](value_streams_dashboard.md) +- [Issue analytics](../group/issues_analytics/index.md) +- [Productivity analytics](productivity_analytics.md) +- [Repositories analytics](../group/repositories_analytics/index.md) +- [Value Stream Management Analytics](../group/value_stream_analytics/index.md) and [Value Stream Management Dashboard](value_streams_dashboard.md) ## Project-level analytics -You can use GitLab to review analytics at the project level. Some of these features require you to use a higher tier than GitLab Free. +Use project-level analytics to get insights into your projects': - [Analytics dashboards](analytics_dashboards.md), enabled with the `combined_analytics_dashboards_editor` [feature flag](../../development/feature_flags/index.md#enabling-a-feature-flag-locally-in-development) -- [Application Security](../application_security/security_dashboard/index.md) -- [CI/CD & DORA](ci_cd_analytics.md) -- [Code Review](code_review_analytics.md) +- [Security Dashboards](../application_security/security_dashboard/index.md) +- [CI/CD analytics and DORA metrics](ci_cd_analytics.md) +- [Code review analytics](code_review_analytics.md) - [Contributor statistics](../../user/analytics/contributor_statistics.md) - [Insights](../project/insights/index.md) -- [Issue](../../user/analytics/issue_analytics.md) -- [Merge Request](merge_request_analytics.md), enabled with the `project_merge_request_analytics` +- [Issue analytics](../../user/analytics/issue_analytics.md) +- [Merge request analytics](merge_request_analytics.md), enabled with the `project_merge_request_analytics` [feature flag](../../development/feature_flags/index.md#enabling-a-feature-flag-locally-in-development) -- [Repository](repository_analytics.md) -- [Value Stream Management Analytics](../group/value_stream_analytics/index.md), and [Value Stream Management Dashboard](value_streams_dashboard.md) +- [Repository analytics](repository_analytics.md) +- [Value Stream Management Analytics](../group/value_stream_analytics/index.md) and [Value Stream Management Dashboard](value_streams_dashboard.md) ## User-configurable analytics -The following analytics features are available for users to create personalized views: - -- [Application Security](../application_security/security_dashboard/index.md#security-center) - -Be sure to review the documentation page for this feature for GitLab tier requirements. +View vulnerabilities of your selected projects in the [Security Center](../application_security/security_dashboard/index.md#security-center). ## Value streams management -You can use the following analytics features to analyze and visualize the performance of your projects and groups: +Analyze and visualize the performance of your projects and groups with: - [Value stream analytics for projects and groups](../group/value_stream_analytics/index.md) - [Value streams dashboard](value_streams_dashboard.md) diff --git a/locale/gitlab.pot b/locale/gitlab.pot index e12cb02bd03..aee93e8788c 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -30823,10 +30823,10 @@ msgstr "" msgid "NamespaceStorage|You have used %{used_storage_percentage} of the storage quota for %{name_with_link} (%{current_size} of %{limit})." msgstr "" -msgid "NamespaceStorage|You have used %{used_storage_percentage} of the storage quota for %{name} (%{current_size} of %{limit})." +msgid "NamespaceStorage|You have used %{used_storage_percentage} of the storage quota for %{namespace_name}" msgstr "" -msgid "NamespaceStorage|You have used %{used_storage_percentage}%% of the storage quota for %{namespace_name}" +msgid "NamespaceStorage|You have used %{used_storage_percentage} of the storage quota for %{name} (%{current_size} of %{limit})." msgstr "" msgid "NamespaceUserCap|Pending users must be reviewed and approved by a group owner. Learn more about %{user_caps_link_start}user caps%{link_end} and %{users_pending_approval_link_start}users pending approval%{link_end}." diff --git a/qa/gdk/Dockerfile.gdk b/qa/gdk/Dockerfile.gdk index 97406a9df6e..34895fba406 100644 --- a/qa/gdk/Dockerfile.gdk +++ b/qa/gdk/Dockerfile.gdk @@ -1,6 +1,6 @@ ARG BASE_TAG=master -FROM registry.gitlab.com/gitlab-org/gitlab-development-kit/asdf-bootstrapped-verify:main@sha256:934d8caa0a91c2bb9c68fe7bce42ca89fd04c580deea351a21820b45fa74413f as gdk-base +FROM registry.gitlab.com/gitlab-org/gitlab-development-kit/asdf-bootstrapped-verify:main@sha256:14fa752a80df21f840fc48f4be8561bee21b78886ac718652582fdd788d34c32 as gdk-base # Allow passwordless /etc/hosts update by gdk user USER root diff --git a/scripts/trigger-build.rb b/scripts/trigger-build.rb index 8f509399fd4..98ca8112d62 100755 --- a/scripts/trigger-build.rb +++ b/scripts/trigger-build.rb @@ -307,6 +307,8 @@ module Trigger 'omnibus' when 'gitlab-org/charts/gitlab' 'charts' + when 'gitlab-org/cloud-native/gitlab-operator' + 'operator' end end diff --git a/spec/db/schema_spec.rb b/spec/db/schema_spec.rb index 04a83a1f6ab..fea3c5b77a1 100644 --- a/spec/db/schema_spec.rb +++ b/spec/db/schema_spec.rb @@ -15,7 +15,8 @@ RSpec.describe 'Database schema', feature_category: :database do search_namespace_index_assignments: [%w[search_index_id index_type]], slack_integrations_scopes: [%w[slack_api_scope_id]], notes: %w[namespace_id], # this index is added in an async manner, hence it needs to be ignored in the first phase. - vulnerabilities: [%w[finding_id]] # index will be created in https://gitlab.com/gitlab-org/gitlab/-/issues/423541 + vulnerabilities: [%w[finding_id]], # index will be created in https://gitlab.com/gitlab-org/gitlab/-/issues/423541 + projects: %w[organization_id] # this index is added in an async manner, hence it needs to be ignored in the first phase. }.with_indifferent_access.freeze TABLE_PARTITIONS = %w[ci_builds_metadata].freeze diff --git a/spec/features/merge_request/user_closes_reopens_merge_request_state_spec.rb b/spec/features/merge_request/user_closes_reopens_merge_request_state_spec.rb index 446f6a470de..fea4841c5ea 100644 --- a/spec/features/merge_request/user_closes_reopens_merge_request_state_spec.rb +++ b/spec/features/merge_request/user_closes_reopens_merge_request_state_spec.rb @@ -2,8 +2,7 @@ require 'spec_helper' -RSpec.describe 'User closes/reopens a merge request', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/297500', - feature_category: :code_review_workflow do +RSpec.describe 'User closes/reopens a merge request', :js, feature_category: :code_review_workflow do let_it_be(:project) { create(:project, :repository) } let_it_be(:user) { create(:user) } @@ -13,89 +12,67 @@ RSpec.describe 'User closes/reopens a merge request', :js, quarantine: 'https:// end describe 'when open' do - context 'when clicking the top `Close merge request` link', :aggregate_failures do - let(:open_merge_request) { create(:merge_request, source_project: project, target_project: project) } + let(:open_merge_request) { create(:merge_request, source_project: project, target_project: project) } - before do - visit merge_request_path(open_merge_request) - end + before do + visit merge_request_path(open_merge_request) + end - it 'can close a merge request' do - expect(find('.status-box')).to have_content 'Open' + context 'when clicking the top `Close merge request` button', :aggregate_failures do + it 'closes the merge request' do + expect(page).to have_css('.gl-badge', text: 'Open') within '.detail-page-header' do - click_button 'Toggle dropdown' - click_link 'Close merge request' + click_button 'Merge request actions' + click_button 'Close merge request' end - wait_for_requests - - expect(find('.status-box')).to have_content 'Closed' + expect(page).to have_css('.gl-badge', text: 'Closed') end end context 'when clicking the bottom `Close merge request` button', :aggregate_failures do - let(:open_merge_request) { create(:merge_request, source_project: project, target_project: project) } - - before do - visit merge_request_path(open_merge_request) - end - - it 'can close a merge request' do - expect(find('.status-box')).to have_content 'Open' + it 'closes the merge request' do + expect(page).to have_css('.gl-badge', text: 'Open') within '.timeline-content-form' do click_button 'Close merge request' - - # Clicking the bottom `Close merge request` button does not yet update - # the header status so for now we'll check that the button text changes - expect(page).not_to have_button 'Close merge request' - expect(page).to have_button 'Reopen merge request' end + + expect(page).to have_css('.gl-badge', text: 'Closed') end end end describe 'when closed' do - context 'when clicking the top `Reopen merge request` link', :aggregate_failures do - let(:closed_merge_request) { create(:merge_request, source_project: project, target_project: project, state: 'closed') } + let(:closed_merge_request) { create(:merge_request, source_project: project, target_project: project, state: 'closed') } - before do - visit merge_request_path(closed_merge_request) - end + before do + visit merge_request_path(closed_merge_request) + end - it 'can reopen a merge request' do - expect(find('.status-box')).to have_content 'Closed' + context 'when clicking the top `Reopen merge request` button', :aggregate_failures do + it 'reopens the merge request' do + expect(page).to have_css('.gl-badge', text: 'Closed') within '.detail-page-header' do - click_button 'Toggle dropdown' - click_link 'Reopen merge request' + click_button 'Merge request actions' + click_button 'Reopen merge request' end - wait_for_requests - - expect(find('.status-box')).to have_content 'Open' + expect(page).to have_css('.gl-badge', text: 'Open') end end context 'when clicking the bottom `Reopen merge request` button', :aggregate_failures do - let(:closed_merge_request) { create(:merge_request, source_project: project, target_project: project, state: 'closed') } - - before do - visit merge_request_path(closed_merge_request) - end - - it 'can reopen a merge request' do - expect(find('.status-box')).to have_content 'Closed' + it 'reopens the merge request' do + expect(page).to have_css('.gl-badge', text: 'Closed') within '.timeline-content-form' do click_button 'Reopen merge request' - - # Clicking the bottom `Reopen merge request` button does not yet update - # the header status so for now we'll check that the button text changes - expect(page).not_to have_button 'Reopen merge request' - expect(page).to have_button 'Close merge request' end + + expect(page).to have_css('.gl-badge', text: 'Open') end end end diff --git a/spec/frontend/vue_merge_request_widget/components/action_buttons.js b/spec/frontend/vue_merge_request_widget/components/action_buttons.js deleted file mode 100644 index 7334f061dc9..00000000000 --- a/spec/frontend/vue_merge_request_widget/components/action_buttons.js +++ /dev/null @@ -1,43 +0,0 @@ -import { GlButton, GlDropdownItem } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; -import Actions from '~/vue_merge_request_widget/components/action_buttons.vue'; - -let wrapper; - -function factory(propsData = {}) { - wrapper = shallowMount(Actions, { - propsData: { ...propsData, widget: 'test' }, - }); -} - -describe('MR widget extension actions', () => { - describe('tertiaryButtons', () => { - it('renders buttons', () => { - factory({ - tertiaryButtons: [{ text: 'hello world', href: 'https://gitlab.com', target: '_blank' }], - }); - - expect(wrapper.findAllComponents(GlButton)).toHaveLength(1); - }); - - it('calls action click handler', async () => { - const onClick = jest.fn(); - - factory({ - tertiaryButtons: [{ text: 'hello world', onClick }], - }); - - await wrapper.findComponent(GlButton).vm.$emit('click'); - - expect(onClick).toHaveBeenCalled(); - }); - - it('renders tertiary actions in dropdown', () => { - factory({ - tertiaryButtons: [{ text: 'hello world', href: 'https://gitlab.com', target: '_blank' }], - }); - - expect(wrapper.findAllComponents(GlDropdownItem)).toHaveLength(1); - }); - }); -}); diff --git a/spec/frontend/vue_merge_request_widget/components/action_buttons_spec.js b/spec/frontend/vue_merge_request_widget/components/action_buttons_spec.js new file mode 100644 index 00000000000..02e23b81413 --- /dev/null +++ b/spec/frontend/vue_merge_request_widget/components/action_buttons_spec.js @@ -0,0 +1,61 @@ +import { GlButton, GlDisclosureDropdown } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import Actions from '~/vue_merge_request_widget/components/action_buttons.vue'; + +let wrapper; + +function factory(propsData = {}) { + wrapper = shallowMount(Actions, { + propsData, + }); +} + +describe('MR widget extension actions', () => { + describe('tertiaryButtons', () => { + it('renders buttons', () => { + factory({ + tertiaryButtons: [{ text: 'hello world', href: 'https://gitlab.com', target: '_blank' }], + }); + + expect(wrapper.findAllComponents(GlButton)).toHaveLength(1); + }); + + it('calls action click handler', async () => { + const onClick = jest.fn(); + + factory({ + tertiaryButtons: [{ text: 'hello world', onClick }], + }); + + await wrapper.findComponent(GlButton).vm.$emit('click'); + + expect(onClick).toHaveBeenCalled(); + }); + + it('renders tertiary actions in dropdown', () => { + const action = { text: 'hello world', href: 'https://gitlab.com', target: '_blank' }; + factory({ + tertiaryButtons: [action, action], + }); + + const component = wrapper.findComponent(GlDisclosureDropdown); + expect(component.exists()).toBe(true); + expect(component.props('items')).toMatchObject([ + { + text: action.text, + href: action.href, + extraAttrs: { + target: action.target, + }, + }, + { + text: action.text, + href: action.href, + extraAttrs: { + target: action.target, + }, + }, + ]); + }); + }); +}); diff --git a/spec/frontend/vue_merge_request_widget/components/states/mr_widget_merged_spec.js b/spec/frontend/vue_merge_request_widget/components/states/mr_widget_merged_spec.js index e44e2834a0e..5efb1dcce42 100644 --- a/spec/frontend/vue_merge_request_widget/components/states/mr_widget_merged_spec.js +++ b/spec/frontend/vue_merge_request_widget/components/states/mr_widget_merged_spec.js @@ -1,4 +1,4 @@ -import { getByRole } from '@testing-library/dom'; +import { getAllByRole } from '@testing-library/dom'; import { nextTick } from 'vue'; import { mount } from '@vue/test-utils'; import waitForPromises from 'helpers/wait_for_promises'; @@ -132,7 +132,7 @@ describe('MRWidgetMerged', () => { createComponent(); const eventHubSpy = jest.spyOn(modalEventHub, '$emit'); - getByRole(wrapper.element, 'button', { name: /Revert/i }).click(); + getAllByRole(wrapper.element, 'button', { name: /Revert/i })[0].click(); expect(eventHubSpy).toHaveBeenCalledWith(OPEN_REVERT_MODAL); }); @@ -141,7 +141,7 @@ describe('MRWidgetMerged', () => { createComponent(); const eventHubSpy = jest.spyOn(modalEventHub, '$emit'); - getByRole(wrapper.element, 'button', { name: /Cherry-pick/i }).click(); + getAllByRole(wrapper.element, 'button', { name: /Cherry-pick/i })[0].click(); expect(eventHubSpy).toHaveBeenCalledWith(OPEN_CHERRY_PICK_MODAL); }); diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 99e871e5255..de3f28a5b90 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -823,6 +823,7 @@ project: - project_state - security_policy_bots - target_branch_rules +- organization award_emoji: - awardable - user diff --git a/spec/models/organizations/organization_spec.rb b/spec/models/organizations/organization_spec.rb index 7838fc1c5a4..2f9f04fd3e6 100644 --- a/spec/models/organizations/organization_spec.rb +++ b/spec/models/organizations/organization_spec.rb @@ -11,6 +11,7 @@ RSpec.describe Organizations::Organization, type: :model, feature_category: :cel it { is_expected.to have_many :groups } it { is_expected.to have_many(:users).through(:organization_users).inverse_of(:organizations) } it { is_expected.to have_many(:organization_users).inverse_of(:organization) } + it { is_expected.to have_many :projects } end describe 'validations' do diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 657c7d5dee8..5312ca0ef70 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -17,6 +17,7 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr it_behaves_like 'ensures runners_token is prefixed', :project describe 'associations' do + it { is_expected.to belong_to(:organization) } it { is_expected.to belong_to(:group) } it { is_expected.to belong_to(:namespace) } it { is_expected.to belong_to(:project_namespace).class_name('Namespaces::ProjectNamespace').with_foreign_key('project_namespace_id').inverse_of(:project) } @@ -9189,6 +9190,13 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr end end + context 'with loose foreign key on organization_id' do + it_behaves_like 'cleanup by a loose foreign key' do + let_it_be(:parent) { create(:organization) } + let_it_be(:model) { create(:project, organization: parent) } + end + end + private def finish_job(export_job) diff --git a/spec/requests/api/project_attributes.yml b/spec/requests/api/project_attributes.yml index 1055c1a6968..677cb243a7c 100644 --- a/spec/requests/api/project_attributes.yml +++ b/spec/requests/api/project_attributes.yml @@ -44,6 +44,7 @@ itself: # project - storage_version - topic_list - verification_checksum + - organization_id remapped_attributes: avatar: avatar_url build_allow_git_fetch: build_git_strategy diff --git a/spec/scripts/trigger-build_spec.rb b/spec/scripts/trigger-build_spec.rb index d3b520d385f..f46adb1a9f1 100644 --- a/spec/scripts/trigger-build_spec.rb +++ b/spec/scripts/trigger-build_spec.rb @@ -477,6 +477,18 @@ RSpec.describe Trigger, feature_category: :tooling do end end + describe "BRANCH_OPERATOR" do + before do + stub_env('CI_PROJECT_PATH', 'gitlab-org/cloud-native/gitlab-operator') + end + + context 'when CI_PROJECT_PATH is gitlab-org/cloud-native/gitlab-operator' do + it 'sets BRANCH_OPERATOR to CI_COMMIT_REF_NAME' do + expect(subject.variables['BRANCH_OPERATOR']).to eq(env['CI_COMMIT_REF_NAME']) + end + end + end + describe "REVIEW_SLUG" do before do stub_env('CI_PROJECT_PATH', 'gitlab-org/gitlab-foss') diff --git a/spec/support/capybara_wait_for_all_requests.rb b/spec/support/capybara_wait_for_all_requests.rb index 84273eab45d..6f272474cf6 100644 --- a/spec/support/capybara_wait_for_all_requests.rb +++ b/spec/support/capybara_wait_for_all_requests.rb @@ -26,26 +26,26 @@ module Capybara include CapybaraHelpers include WaitForRequests - module WaitForAllRequestsAfterClickButton + module WaitForRequestsAfterClickButton def click_button(locator = nil, **options) super - wait_for_all_requests + wait_for_requests end end - module WaitForAllRequestsAfterClickLink + module WaitForRequestsAfterClickLink def click_link(locator = nil, **options, &block) super yield if block - wait_for_all_requests + wait_for_requests end end - prepend WaitForAllRequestsAfterClickButton - prepend WaitForAllRequestsAfterClickLink + prepend WaitForRequestsAfterClickButton + prepend WaitForRequestsAfterClickLink end end end diff --git a/spec/support_specs/capybara_wait_for_all_requests_spec.rb b/spec/support_specs/capybara_wait_for_all_requests_spec.rb index ddd4be6c644..64b89ba0b56 100644 --- a/spec/support_specs/capybara_wait_for_all_requests_spec.rb +++ b/spec/support_specs/capybara_wait_for_all_requests_spec.rb @@ -23,37 +23,37 @@ RSpec.describe 'capybara_wait_for_all_requests', feature_category: :tooling do # end end - context 'for Capybara::Node::Actions::WaitForAllRequestsAfterClickButton' do + context 'for Capybara::Node::Actions::WaitForRequestsAfterClickButton' do let(:node) do Class.new do def click_button(locator = nil, **_options) locator end - prepend Capybara::Node::Actions::WaitForAllRequestsAfterClickButton + prepend Capybara::Node::Actions::WaitForRequestsAfterClickButton end.new end - it 'waits for all requests after a click button' do - expect(node).to receive(:wait_for_all_requests) + it 'waits for requests after a click button' do + expect(node).to receive(:wait_for_requests) node.click_button end end - context 'for Capybara::Node::Actions::WaitForAllRequestsAfterClickLink' do + context 'for Capybara::Node::Actions::WaitForRequestsAfterClickLink' do let(:node) do Class.new do def click_link(locator = nil, **_options) locator end - prepend Capybara::Node::Actions::WaitForAllRequestsAfterClickLink + prepend Capybara::Node::Actions::WaitForRequestsAfterClickLink end.new end - it 'waits for all requests after a click link' do - expect(node).to receive(:wait_for_all_requests) + it 'waits for requests after a click link' do + expect(node).to receive(:wait_for_requests) node.click_link end -- cgit v1.2.3