diff options
110 files changed, 1092 insertions, 583 deletions
diff --git a/app/assets/stylesheets/page_bundles/search.scss b/app/assets/stylesheets/page_bundles/search.scss index b145d046fa4..87d0d5b91d3 100644 --- a/app/assets/stylesheets/page_bundles/search.scss +++ b/app/assets/stylesheets/page_bundles/search.scss @@ -281,14 +281,6 @@ $language-filter-max-height: 20rem; margin-right: 5px; } } - - .dropdown-menu-toggle, - .gl-dropdown { - @include media-breakpoint-up(sm) { - width: 180px; - margin-top: 0; - } - } } .search-page-form { diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index b997b2e0b6b..fa1d693205d 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -87,8 +87,14 @@ class ProjectsController < Projects::ApplicationController @parent_group = Group.find_by(id: params[:namespace_id]) + manageable_groups_count = current_user.manageable_groups(include_groups_with_developer_maintainer_access: true).count + + if manageable_groups_count == 0 && !can?(current_user, :create_projects, current_user.namespace) + return access_denied! + end + @current_user_group = - if current_user.manageable_groups(include_groups_with_developer_maintainer_access: true).count == 1 + if manageable_groups_count == 1 current_user.manageable_groups(include_groups_with_developer_maintainer_access: true).first end diff --git a/app/graphql/resolvers/container_repository_tags_resolver.rb b/app/graphql/resolvers/container_repository_tags_resolver.rb index 50adf98fa07..d3929451bd0 100644 --- a/app/graphql/resolvers/container_repository_tags_resolver.rb +++ b/app/graphql/resolvers/container_repository_tags_resolver.rb @@ -14,6 +14,11 @@ module Resolvers required: false, default_value: nil + argument :referrers, GraphQL::Types::Boolean, + description: 'Include tag referrers.', + required: false, + default_value: nil + alias_method :container_repository, :object def resolve(sort:, **filters) @@ -25,7 +30,8 @@ module Resolvers last: filters[:after], sort: map_sort_field(sort), name: filters[:name], - page_size: page_size + page_size: page_size, + referrers: filters[:referrers] ) Gitlab::Graphql::ExternallyPaginatedArray.new( diff --git a/app/graphql/types/container_repository_referrer_type.rb b/app/graphql/types/container_repository_referrer_type.rb new file mode 100644 index 00000000000..d9d4d150b95 --- /dev/null +++ b/app/graphql/types/container_repository_referrer_type.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Types + class ContainerRepositoryReferrerType < BaseObject + graphql_name 'ContainerRepositoryReferrer' + + description 'A referrer for a container repository tag' + + authorize :read_container_image + + expose_permissions Types::PermissionTypes::ContainerRepositoryTag + + field :artifact_type, GraphQL::Types::String, description: 'Artifact type of the referrer.' + field :digest, GraphQL::Types::String, description: 'Digest of the referrer.' + end +end diff --git a/app/graphql/types/container_repository_tag_type.rb b/app/graphql/types/container_repository_tag_type.rb index cf8796410d3..ce58694d237 100644 --- a/app/graphql/types/container_repository_tag_type.rb +++ b/app/graphql/types/container_repository_tag_type.rb @@ -22,6 +22,7 @@ module Types field :location, GraphQL::Types::String, null: false, description: 'URL of the tag.' field :name, GraphQL::Types::String, null: false, description: 'Name of the tag.' field :path, GraphQL::Types::String, null: false, description: 'Path of the tag.' + field :referrers, [Types::ContainerRepositoryReferrerType], null: true, description: 'Referrers for this tag.' field :revision, GraphQL::Types::String, null: true, description: 'Revision of the tag.' field :short_revision, GraphQL::Types::String, null: true, description: 'Short revision of the tag.' field :total_size, GraphQL::Types::BigInt, null: true, description: 'Size of the tag.' diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index e01496ca254..919fc485d64 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -511,7 +511,8 @@ module ApplicationSettingsHelper :namespace_aggregation_schedule_lease_duration_in_seconds, :ci_max_total_yaml_size_bytes, :project_jobs_api_rate_limit, - :security_txt_content + :security_txt_content, + :allow_project_creation_for_guest_and_below ].tap do |settings| next if Gitlab.com? diff --git a/app/helpers/listbox_helper.rb b/app/helpers/listbox_helper.rb index 6a7e09f75e4..ba292f560c4 100644 --- a/app/helpers/listbox_helper.rb +++ b/app/helpers/listbox_helper.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module ListboxHelper - DROPDOWN_CONTAINER_CLASSES = %w[dropdown b-dropdown gl-dropdown btn-group js-redirect-listbox].freeze + DROPDOWN_CONTAINER_CLASSES = %w[dropdown b-dropdown gl-dropdown js-redirect-listbox].freeze DROPDOWN_BUTTON_CLASSES = %w[btn dropdown-toggle btn-default btn-md gl-button gl-dropdown-toggle].freeze DROPDOWN_INNER_CLASS = 'gl-dropdown-button-text' DROPDOWN_ICON_CLASS = 'gl-button-icon dropdown-chevron gl-icon' diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb index 851b65055d0..eddc508a6ee 100644 --- a/app/models/application_setting_implementation.rb +++ b/app/models/application_setting_implementation.rb @@ -275,7 +275,8 @@ module ApplicationSettingImplementation allow_account_deletion: true, gitlab_shell_operation_limit: 600, project_jobs_api_rate_limit: 600, - security_txt_content: nil + security_txt_content: nil, + allow_project_creation_for_guest_and_below: true }.tap do |hsh| hsh.merge!(non_production_defaults) unless Rails.env.production? end diff --git a/app/models/container_repository.rb b/app/models/container_repository.rb index 4df92235f50..0257848af37 100644 --- a/app/models/container_repository.rb +++ b/app/models/container_repository.rb @@ -482,7 +482,7 @@ class ContainerRepository < ApplicationRecord raise 'too many pages requested' if page_count >= MAX_TAGS_PAGES end - def tags_page(before: nil, last: nil, sort: nil, name: nil, page_size: 100) + def tags_page(before: nil, last: nil, sort: nil, name: nil, page_size: 100, referrers: nil) raise ArgumentError, 'not a migrated repository' unless migrated? page = gitlab_api_client.tags( @@ -491,7 +491,8 @@ class ContainerRepository < ApplicationRecord before: before, last: last, sort: sort, - name: name + name: name, + referrers: referrers ) { @@ -656,6 +657,7 @@ class ContainerRepository < ApplicationRecord tag.total_size = raw_tag['size_bytes'] tag.manifest_digest = raw_tag['digest'] tag.revision = raw_tag['config_digest'].to_s.split(':')[1] || '' + tag.referrers = raw_tag['referrers'] tag end end diff --git a/app/models/tree.rb b/app/models/tree.rb index 030e7d9e85f..d62e5c1b368 100644 --- a/app/models/tree.rb +++ b/app/models/tree.rb @@ -18,8 +18,15 @@ class Tree ref = ExtractsRef::RefExtractor.qualify_ref(@sha, ref_type) - @entries, @cursor = Gitlab::Git::Tree.where(git_repo, ref, @path, recursive, skip_flat_paths, rescue_not_found, - pagination_params) + @entries, @cursor = Gitlab::Git::Tree.tree_entries( + repository: git_repo, + sha: ref, + path: @path, + recursive: recursive, + skip_flat_paths: skip_flat_paths, + rescue_not_found: rescue_not_found, + pagination_params: pagination_params + ) @entries.each do |entry| entry.ref_type = self.ref_type diff --git a/app/models/user.rb b/app/models/user.rb index e10cd224931..3654faedb3a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1322,7 +1322,13 @@ class User < MainClusterwide::ApplicationRecord end def can_create_project? - projects_limit_left > 0 + projects_limit_left > 0 && allow_user_to_create_group_and_project? + end + + def allow_user_to_create_group_and_project? + return true if Gitlab::CurrentSettings.allow_project_creation_for_guest_and_below + + highest_role > Gitlab::Access::GUEST end def can_create_group? diff --git a/app/policies/container_registry/referrer_policy.rb b/app/policies/container_registry/referrer_policy.rb new file mode 100644 index 00000000000..96eb4c60c84 --- /dev/null +++ b/app/policies/container_registry/referrer_policy.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module ContainerRegistry + class ReferrerPolicy < BasePolicy + delegate { @subject.tag } + end +end diff --git a/app/policies/global_policy.rb b/app/policies/global_policy.rb index 175f86c9673..85ddf61fbd4 100644 --- a/app/policies/global_policy.rb +++ b/app/policies/global_policy.rb @@ -15,6 +15,8 @@ class GlobalPolicy < BasePolicy @user&.required_terms_not_accepted? end + condition(:can_create_group_and_projects, scope: :user) { @user&.allow_user_to_create_group_and_project? } + condition(:password_expired, scope: :user) do @user&.password_expired_if_applicable? end @@ -90,6 +92,8 @@ class GlobalPolicy < BasePolicy enable :create_group end + rule { ~can_create_group_and_projects }.prevent :create_group + rule { can_create_organization }.policy do enable :create_organization end diff --git a/app/views/admin/application_settings/_user_restrictions.html.haml b/app/views/admin/application_settings/_user_restrictions.html.haml index 4fb65c20daf..4bdc21a3695 100644 --- a/app/views/admin/application_settings/_user_restrictions.html.haml +++ b/app/views/admin/application_settings/_user_restrictions.html.haml @@ -8,3 +8,4 @@ = form.gitlab_ui_checkbox_component :can_create_group, _("Allow new users to create top-level groups") = form.gitlab_ui_checkbox_component :user_defaults_to_private_profile, _("Make new users' profiles private by default") = render_if_exists 'admin/application_settings/allow_account_deletion', form: form + = form.gitlab_ui_checkbox_component :allow_project_creation_for_guest_and_below, _("Allow users with up to Guest role to create groups and personal projects") diff --git a/app/views/projects/forks/index.html.haml b/app/views/projects/forks/index.html.haml index 98055534a27..10ca730ac11 100644 --- a/app/views/projects/forks/index.html.haml +++ b/app/views/projects/forks/index.html.haml @@ -16,7 +16,7 @@ .dropdown.gl-display-inline.gl-md-ml-3.issue-sort-dropdown.gl-mt-3.gl-md-mt-0 .btn-group{ role: 'group' } - = gl_redirect_listbox_tag [created_at, activity], @sort + = gl_redirect_listbox_tag [created_at, activity], @sort, class: 'btn-group' = forks_sort_direction_button(sort_value) - if current_user && can?(current_user, :fork_project, @project) diff --git a/app/views/shared/issuable/_sort_dropdown.html.haml b/app/views/shared/issuable/_sort_dropdown.html.haml index 0a3fd4f8b9e..261a7517eda 100644 --- a/app/views/shared/issuable/_sort_dropdown.html.haml +++ b/app/views/shared/issuable/_sort_dropdown.html.haml @@ -5,5 +5,5 @@ .gl-ml-3 .btn-group{ role: 'group' } - = gl_redirect_listbox_tag(items, selected, data: { placement: 'right' }) + = gl_redirect_listbox_tag(items, selected, class: 'btn-group', data: { placement: 'right' }) = issuable_sort_direction_button(@sort) diff --git a/bin/feature-flag b/bin/feature-flag index a82abdf43cd..1924ad91824 100755 --- a/bin/feature-flag +++ b/bin/feature-flag @@ -155,13 +155,58 @@ class FeatureFlagOptionParser groups.find { |_, group| group['label'] == label }[1] end + def types_list + list = [] + TYPES.each_with_index do |(type, data), index| + next if data[:deprecated] + + list << "#{index + 1}. #{type.to_s.rjust(17)} #{data[:description]}" + end + + list + end + def group_list list = [] group_labels.each_with_index do |group_label, index| list << "#{index + 1}. #{group_label}" end - list.join("\n") + list + end + + def fzf_available? + find_compatible_command(%w[fzf]) + end + + def prompt_readline(prompt:) + Readline.readline('?> ', false)&.strip + end + + def prompt_fzf(list:, prompt:) + arr = list.join("\n") + selection = IO.popen("echo \"#{arr}\" | fzf --tac --prompt=\"#{prompt}\"") { |pipe| pipe.readlines }.join.strip + selection.match(/(\d+)\./)[1] + end + + def print_list(list) + return if list.empty? + + $stdout.puts list.join("\n") + end + + def print_prompt(prompt) + $stdout.puts + $stdout.puts ">> #{prompt}:" + $stdout.puts + end + + def prompt_list(prompt:, list: nil) + if fzf_available? + prompt_fzf(list: list, prompt: prompt) + else + prompt_readline(prompt: prompt) + end end def fetch_json(json_url) @@ -177,17 +222,14 @@ class FeatureFlagOptionParser end def read_type - $stdout.puts - $stdout.puts ">> Specify the feature flag type:" - $stdout.puts - TYPES.each_with_index do |(type, data), index| - next if data[:deprecated] - - $stdout.puts "#{index + 1}. #{type.to_s.rjust(17)} #{data[:description]}" + prompt = 'Specify the feature flag type' + unless fzf_available? + print_prompt(prompt) + print_list(types_list) end loop do - type = Readline.readline('?> ', false)&.strip + type = prompt_list(prompt: prompt, list: types_list) type = TYPES.keys[type.to_i - 1] unless type.to_i.zero? type = type&.to_sym type_def = TYPES[type] @@ -202,11 +244,15 @@ class FeatureFlagOptionParser end def read_group - $stdout.puts - $stdout.puts ">> Specify the group label to which the feature flag belongs, from the following list:\n#{group_list}" + prompt = "Specify the group label to which the feature flag belongs, from the following list" + + unless fzf_available? + print_prompt(prompt) + print_list(group_list) + end loop do - group = Readline.readline('?> ', false)&.strip + group = prompt_list(prompt: prompt, list: group_list) group = group_labels[group.to_i - 1] unless group.to_i.zero? if group_labels.include?(group) diff --git a/doc/administration/audit_event_streaming/audit_event_types.md b/doc/administration/audit_event_streaming/audit_event_types.md index 28cab04553a..d4f9586a9b3 100644 --- a/doc/administration/audit_event_streaming/audit_event_types.md +++ b/doc/administration/audit_event_streaming/audit_event_types.md @@ -233,6 +233,12 @@ Audit event types belong to the following product categories. | [`feature_flag_deleted`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/113453) | Triggered when a feature flag is deleted.| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [15.10](https://gitlab.com/gitlab-org/gitlab/-/issues/374109) | | [`feature_flag_updated`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/113453) | Triggered when a feature flag is updated.| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [15.10](https://gitlab.com/gitlab-org/gitlab/-/issues/374109) | +### Fleet visibility + +| Name | Description | Saved to database | Streamed | Introduced in | +|:-----|:------------|:------------------|:---------|:--------------| +| [`ci_runner_usage_export`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/139578) | Triggered when a runner usage report is generated.| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.8](https://gitlab.com/gitlab-org/gitlab/-/issues/426560) | + ### Fuzz testing | Name | Description | Saved to database | Streamed | Introduced in | diff --git a/doc/administration/raketasks/maintenance.md b/doc/administration/raketasks/maintenance.md index 3a136e773d9..c9082ea826c 100644 --- a/doc/administration/raketasks/maintenance.md +++ b/doc/administration/raketasks/maintenance.md @@ -245,7 +245,7 @@ clear Redis' cache. To do this, run: Sometimes during version upgrades you might end up with some wrong CSS or missing some icons. In that case, try to precompile the assets again. -This Rake task only applies to self-compiled installations. [Read more](../../update/package/index.md#missing-asset-files) +This Rake task only applies to self-compiled installations. [Read more](../../update/package/package_troubleshooting.md#missing-asset-files) about troubleshooting this problem when running the Linux package. The guidance for Linux package might be applicable for Kubernetes and Docker deployments of GitLab, though in general, container-based installations diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index bc2629fde20..d8507c9d49e 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -16671,6 +16671,7 @@ four standard [pagination arguments](#connection-pagination-arguments): | Name | Type | Description | | ---- | ---- | ----------- | | <a id="containerrepositorydetailstagsname"></a>`name` | [`String`](#string) | Search by tag name. | +| <a id="containerrepositorydetailstagsreferrers"></a>`referrers` | [`Boolean`](#boolean) | Include tag referrers. | | <a id="containerrepositorydetailstagssort"></a>`sort` | [`ContainerRepositoryTagSort`](#containerrepositorytagsort) | Sort tags by these criteria. | ### `ContainerRepositoryPermissions` @@ -16681,6 +16682,18 @@ four standard [pagination arguments](#connection-pagination-arguments): | ---- | ---- | ----------- | | <a id="containerrepositorypermissionsdestroycontainerrepository"></a>`destroyContainerRepository` | [`Boolean!`](#boolean) | If `true`, the user can perform `destroy_container_image` on this resource. | +### `ContainerRepositoryReferrer` + +A referrer for a container repository tag. + +#### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="containerrepositoryreferrerartifacttype"></a>`artifactType` | [`String`](#string) | Artifact type of the referrer. | +| <a id="containerrepositoryreferrerdigest"></a>`digest` | [`String`](#string) | Digest of the referrer. | +| <a id="containerrepositoryreferreruserpermissions"></a>`userPermissions` | [`ContainerRepositoryTagPermissions!`](#containerrepositorytagpermissions) | Permissions for the current user on the resource. | + ### `ContainerRepositoryRegistry` Represents the Geo replication and verification state of an Container Repository. @@ -16719,6 +16732,7 @@ A tag from a container repository. | <a id="containerrepositorytaglocation"></a>`location` | [`String!`](#string) | URL of the tag. | | <a id="containerrepositorytagname"></a>`name` | [`String!`](#string) | Name of the tag. | | <a id="containerrepositorytagpath"></a>`path` | [`String!`](#string) | Path of the tag. | +| <a id="containerrepositorytagreferrers"></a>`referrers` | [`[ContainerRepositoryReferrer!]`](#containerrepositoryreferrer) | Referrers for this tag. | | <a id="containerrepositorytagrevision"></a>`revision` | [`String`](#string) | Revision of the tag. | | <a id="containerrepositorytagshortrevision"></a>`shortRevision` | [`String`](#string) | Short revision of the tag. | | <a id="containerrepositorytagtotalsize"></a>`totalSize` | [`BigInt`](#bigint) | Size of the tag. | diff --git a/doc/update/package/convert_to_ee.md b/doc/update/package/convert_to_ee.md index 5a76c85e915..ae89891d4f4 100644 --- a/doc/update/package/convert_to_ee.md +++ b/doc/update/package/convert_to_ee.md @@ -17,7 +17,7 @@ you are upgrading the same version (for example, CE 12.1 to EE 12.1), which is * WARNING: When updating to EE from CE, avoid reverting back to CE if you plan to go to EE again in the future. Reverting back to CE can cause -[database issues](index.md#500-error-when-accessing-project--settings--repository) +[database issues](package_troubleshooting.md#500-error-when-accessing-project--settings--repository) that may require Support intervention. The steps can be summed up to: diff --git a/doc/update/package/index.md b/doc/update/package/index.md index 93967a30660..e780958d485 100644 --- a/doc/update/package/index.md +++ b/doc/update/package/index.md @@ -205,288 +205,4 @@ see how to [upgrade to a later version](../../administration/docs_self_host.md#u ## Troubleshooting -### Get the status of a GitLab installation - -```shell -sudo gitlab-ctl status -sudo gitlab-rake gitlab:check SANITIZE=true -``` - -- Information on using `gitlab-ctl` to perform [maintenance tasks](https://docs.gitlab.com/omnibus/maintenance/index.html). -- Information on using `gitlab-rake` to [check the configuration](../../administration/raketasks/maintenance.md#check-gitlab-configuration). - -### RPM 'package is already installed' error - -If you are using RPM and you are upgrading from GitLab Community Edition to GitLab Enterprise Edition you may get an error like this: - -```shell -package gitlab-7.5.2_omnibus.5.2.1.ci-1.el7.x86_64 (which is newer than gitlab-7.5.2_ee.omnibus.5.2.1.ci-1.el7.x86_64) is already installed -``` - -You can override this version check with the `--oldpackage` option: - -```shell -sudo rpm -Uvh --oldpackage gitlab-7.5.2_ee.omnibus.5.2.1.ci-1.el7.x86_64.rpm -``` - -### Package obsoleted by installed package - -CE and EE packages are marked as obsoleting and replacing each other so that both aren't installed and running at the same time. - -If you are using local RPM files to switch from CE to EE or vice versa, use `rpm` for installing the package rather than `yum`. If you try to use yum, then you may get an error like this: - -```plaintext -Cannot install package gitlab-ee-11.8.3-ee.0.el6.x86_64. It is obsoleted by installed package gitlab-ce-11.8.3-ce.0.el6.x86_64 -``` - -To avoid this issue, either: - -- Use the same instructions provided in the - [Upgrade using a manually-downloaded package](#upgrade-using-a-manually-downloaded-package) section. -- Temporarily disable this checking in yum by adding `--setopt=obsoletes=0` to the options given to the command. - -### 500 error when accessing Project > Settings > Repository - -This error occurs when GitLab is converted from CE > EE > CE, and then back to EE. -When viewing a project's repository settings, you can view this error in the logs: - -```shell -Processing by Projects::Settings::RepositoryController#show as HTML - Parameters: {"namespace_id"=>"<namespace_id>", "project_id"=>"<project_id>"} -Completed 500 Internal Server Error in 62ms (ActiveRecord: 4.7ms | Elasticsearch: 0.0ms | Allocations: 14583) - -NoMethodError (undefined method `commit_message_negative_regex' for #<PushRule:0x00007fbddf4229b8> -Did you mean? commit_message_regex_change): -``` - -This error is caused by an EE feature being added to a CE instance on the initial move to EE. -After the instance is moved back to CE and then is upgraded to EE again, the -`push_rules` table already exists in the database. Therefore, a migration is -unable to add the `commit_message_regex_change` column. - -This results in the [backport migration of EE tables](https://gitlab.com/gitlab-org/gitlab/-/blob/cf00e431024018ddd82158f8a9210f113d0f4dbc/db/migrate/20190402150158_backport_enterprise_schema.rb#L1619) not working correctly. -The backport migration assumes that certain tables in the database do not exist when running CE. - -To fix this issue: - -1. Start a database console: - - In GitLab 14.2 and later: - - ```shell - sudo gitlab-rails dbconsole --database main - ``` - - In GitLab 14.1 and earlier: - - ```shell - sudo gitlab-rails dbconsole - ``` - -1. Manually add the missing `commit_message_negative_regex` column: - - ```sql - ALTER TABLE push_rules ADD COLUMN commit_message_negative_regex VARCHAR; - - # Exit psql - \q - ``` - -1. Restart GitLab: - - ```shell - sudo gitlab-ctl restart - ``` - -### Error `Failed to connect to the internal GitLab API` on a separate GitLab Pages server - -See [GitLab Pages administration troubleshooting](../../administration/pages/troubleshooting.md#failed-to-connect-to-the-internal-gitlab-api). - -### Error `An error occurred during the signature verification` when running `apt-get update` - -To update the GPG key of the GitLab packages server run: - -```shell -curl --silent "https://packages.gitlab.com/gpg.key" | apt-key add - -apt-get update -``` - -### `Mixlib::ShellOut::CommandTimeout: rails_migration[gitlab-rails] [..] Command timed out after 3600s` - -If database schema and data changes (database migrations) must take more than one hour to run, -upgrades fail with a `timed out` error: - -```plaintext -FATAL: Mixlib::ShellOut::CommandTimeout: rails_migration[gitlab-rails] (gitlab::database_migrations line 51) -had an error: Mixlib::ShellOut::CommandTimeout: bash[migrate gitlab-rails database] -(/opt/gitlab/embedded/cookbooks/cache/cookbooks/gitlab/resources/rails_migration.rb line 16) -had an error: Mixlib::ShellOut::CommandTimeout: Command timed out after 3600s: -``` - -To fix this error: - -1. Run the remaining database migrations: - - ```shell - sudo gitlab-rake db:migrate - ``` - - This command may take a very long time to complete. Use `screen` or some other mechanism to ensure - the program is not interrupted if your SSH session drops. - -1. Complete the upgrade: - - ```shell - sudo gitlab-ctl reconfigure - ``` - -1. Hot reload `puma` and `sidekiq` services: - - ```shell - sudo gitlab-ctl hup puma - sudo gitlab-ctl restart sidekiq - ``` - -### Missing asset files - -Following an upgrade, GitLab might not be correctly serving up assets such as images, JavaScript, and style sheets. -It might be generating 500 errors, or the web UI may be failing to render properly. - -In a scaled out GitLab environment, if one web server behind the load balancer is demonstrating -this issue, the problem occurs intermittently. - -The [Rake task to recompile](../../administration/raketasks/maintenance.md#precompile-the-assets) the -assets doesn't apply to an Omnibus installation which serves -pre-compiled assets from `/opt/gitlab/embedded/service/gitlab-rails/public/assets`. - -Potential causes and fixes: - -- [Ensure no old processes are running](#old-processes). -- [Remove duplicate sprockets files](#duplicate-sprockets-files) -- [The installation is incomplete](#incomplete-installation) -- [NGINX Gzip support is disabled](#nginx-gzip-support) - -#### Old processes - -The most likely cause is that an old Puma process is running, instructing clients -to request asset files from a previous release of GitLab. As the files no longer exist, -HTTP 404 errors are returned. - -A reboot is the best way to ensure these old Puma processes are no longer running. - -Alternatively: - -1. Stop Puma: - - ```shell - gitlab-ctl stop puma - ``` - -1. Check for any remaining Puma processes, and kill them: - - ```shell - ps -ef | egrep 'puma[: ]' - kill <processid> - ``` - -1. Verify with `ps` that the Puma processes have stopped running. - -1. Start Puma - - ```shell - gitlab-ctl start puma - ``` - -#### Duplicate sprockets files - -The compiled asset files have unique file names in each release. The sprockets files -provide a mapping from the filenames in the application code to the unique filenames. - -```plaintext -/opt/gitlab/embedded/service/gitlab-rails/public/assets/.sprockets-manifest*.json -``` - -Make sure there's only one sprockets file. [Rails uses the first one](https://github.com/rails/sprockets-rails/blob/118ce60b1ffeb7a85640661b014cd2ee3c4e3e56/lib/sprockets/railtie.rb#L201). - -A check for duplicate sprockets files runs during Omnibus GitLab upgrades: - -```plaintext -GitLab discovered stale file(s) from the previous install that need to be cleaned up. -The following files need to be removed: - -/opt/gitlab/embedded/service/gitlab-rails/public/assets/.sprockets-manifest-e16fdb7dd73cfdd64ed9c2cc0e35718a.json -``` - -Options for resolving this include: - -- If you have the output from the package upgrade, remove the specified files. Then restart Puma: - - ```shell - gitlab-ctl restart puma - ``` - -- If you don't have the message, perform a reinstall - (see [incomplete installation](#incomplete-installation) below for more details) - to generate it again. - -- Remove all the sprockets files and then follow the instructions for an [incomplete installation](#incomplete-installation). - -#### Incomplete installation - -An incomplete installation could be the cause of this issue. - -Verify the package to determine if this is the problem: - -- For Debian distributions: - - ```shell - apt-get install debsums - debsums -c gitlab-ee - ``` - -- For Red Hat/SUSE (RPM) distributions: - - ```shell - rpm -V gitlab-ee - ``` - -To reinstall the package to fix an incomplete installation: - -1. Check the installed version - - - For Debian distributions: - - ```shell - apt --installed list gitlab-ee - ``` - - - For Red Hat/SUSE (RPM) distributions: - - ```shell - rpm -qa gitlab-ee - ``` - -1. Reinstall the package, specifying the installed version. For example 14.4.0 Enterprise Edition: - - - For Debian distributions: - - ```shell - apt-get install --reinstall gitlab-ee=14.4.0-ee.0 - ``` - - - For Red Hat/SUSE (RPM) distributions: - - ```shell - yum reinstall gitlab-ee-14.4.0 - ``` - -#### NGINX Gzip support - -Check whether `nginx['gzip_enabled']` has been disabled: - -```shell -grep gzip /etc/gitlab/gitlab.rb -``` - -This might prevent some assets from being served. -[Read more](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/6087#note_558194395) in one of the related issues. +See [troubleshooting](package_troubleshooting.md) for more information. diff --git a/doc/update/package/package_troubleshooting.md b/doc/update/package/package_troubleshooting.md new file mode 100644 index 00000000000..6d83db1fac1 --- /dev/null +++ b/doc/update/package/package_troubleshooting.md @@ -0,0 +1,293 @@ +--- +stage: Systems +group: Distribution +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments +--- + +# Troubleshooting **(FREE SELF)** + +## Get the status of a GitLab installation + +```shell +sudo gitlab-ctl status +sudo gitlab-rake gitlab:check SANITIZE=true +``` + +- Information on using `gitlab-ctl` to perform [maintenance tasks](https://docs.gitlab.com/omnibus/maintenance/index.html). +- Information on using `gitlab-rake` to [check the configuration](../../administration/raketasks/maintenance.md#check-gitlab-configuration). + +## RPM 'package is already installed' error + +If you are using RPM and you are upgrading from GitLab Community Edition to GitLab Enterprise Edition you may get an error like this: + +```shell +package gitlab-7.5.2_omnibus.5.2.1.ci-1.el7.x86_64 (which is newer than gitlab-7.5.2_ee.omnibus.5.2.1.ci-1.el7.x86_64) is already installed +``` + +You can override this version check with the `--oldpackage` option: + +```shell +sudo rpm -Uvh --oldpackage gitlab-7.5.2_ee.omnibus.5.2.1.ci-1.el7.x86_64.rpm +``` + +## Package obsoleted by installed package + +CE and EE packages are marked as obsoleting and replacing each other so that both aren't installed and running at the same time. + +If you are using local RPM files to switch from CE to EE or vice versa, use `rpm` for installing the package rather than `yum`. If you try to use yum, then you may get an error like this: + +```plaintext +Cannot install package gitlab-ee-11.8.3-ee.0.el6.x86_64. It is obsoleted by installed package gitlab-ce-11.8.3-ce.0.el6.x86_64 +``` + +To avoid this issue, either: + +- Use the same instructions provided in the + [Upgrade using a manually-downloaded package](index.md#upgrade-using-a-manually-downloaded-package) section. +- Temporarily disable this checking in yum by adding `--setopt=obsoletes=0` to the options given to the command. + +## 500 error when accessing Project > Settings > Repository + +This error occurs when GitLab is converted from CE > EE > CE, and then back to EE. +When viewing a project's repository settings, you can view this error in the logs: + +```shell +Processing by Projects::Settings::RepositoryController#show as HTML + Parameters: {"namespace_id"=>"<namespace_id>", "project_id"=>"<project_id>"} +Completed 500 Internal Server Error in 62ms (ActiveRecord: 4.7ms | Elasticsearch: 0.0ms | Allocations: 14583) + +NoMethodError (undefined method `commit_message_negative_regex' for #<PushRule:0x00007fbddf4229b8> +Did you mean? commit_message_regex_change): +``` + +This error is caused by an EE feature being added to a CE instance on the initial move to EE. +After the instance is moved back to CE and then is upgraded to EE again, the +`push_rules` table already exists in the database. Therefore, a migration is +unable to add the `commit_message_regex_change` column. + +This results in the [backport migration of EE tables](https://gitlab.com/gitlab-org/gitlab/-/blob/cf00e431024018ddd82158f8a9210f113d0f4dbc/db/migrate/20190402150158_backport_enterprise_schema.rb#L1619) not working correctly. +The backport migration assumes that certain tables in the database do not exist when running CE. + +To fix this issue: + +1. Start a database console: + + In GitLab 14.2 and later: + + ```shell + sudo gitlab-rails dbconsole --database main + ``` + + In GitLab 14.1 and earlier: + + ```shell + sudo gitlab-rails dbconsole + ``` + +1. Manually add the missing `commit_message_negative_regex` column: + + ```sql + ALTER TABLE push_rules ADD COLUMN commit_message_negative_regex VARCHAR; + + # Exit psql + \q + ``` + +1. Restart GitLab: + + ```shell + sudo gitlab-ctl restart + ``` + +## Error `Failed to connect to the internal GitLab API` on a separate GitLab Pages server + +See [GitLab Pages administration troubleshooting](../../administration/pages/troubleshooting.md#failed-to-connect-to-the-internal-gitlab-api). + +## Error `An error occurred during the signature verification` when running `apt-get update` + +To update the GPG key of the GitLab packages server run: + +```shell +curl --silent "https://packages.gitlab.com/gpg.key" | apt-key add - +apt-get update +``` + +## `Mixlib::ShellOut::CommandTimeout: rails_migration[gitlab-rails] [..] Command timed out after 3600s` + +If database schema and data changes (database migrations) must take more than one hour to run, +upgrades fail with a `timed out` error: + +```plaintext +FATAL: Mixlib::ShellOut::CommandTimeout: rails_migration[gitlab-rails] (gitlab::database_migrations line 51) +had an error: Mixlib::ShellOut::CommandTimeout: bash[migrate gitlab-rails database] +(/opt/gitlab/embedded/cookbooks/cache/cookbooks/gitlab/resources/rails_migration.rb line 16) +had an error: Mixlib::ShellOut::CommandTimeout: Command timed out after 3600s: +``` + +To fix this error: + +1. Run the remaining database migrations: + + ```shell + sudo gitlab-rake db:migrate + ``` + + This command may take a very long time to complete. Use `screen` or some other mechanism to ensure + the program is not interrupted if your SSH session drops. + +1. Complete the upgrade: + + ```shell + sudo gitlab-ctl reconfigure + ``` + +1. Hot reload `puma` and `sidekiq` services: + + ```shell + sudo gitlab-ctl hup puma + sudo gitlab-ctl restart sidekiq + ``` + +## Missing asset files + +Following an upgrade, GitLab might not be correctly serving up assets such as images, JavaScript, and style sheets. +It might be generating 500 errors, or the web UI may be failing to render properly. + +In a scaled out GitLab environment, if one web server behind the load balancer is demonstrating +this issue, the problem occurs intermittently. + +The [Rake task to recompile](../../administration/raketasks/maintenance.md#precompile-the-assets) the +assets doesn't apply to an Omnibus installation which serves +pre-compiled assets from `/opt/gitlab/embedded/service/gitlab-rails/public/assets`. + +Potential causes and fixes: + +- [Ensure no old processes are running](#old-processes). +- [Remove duplicate sprockets files](#duplicate-sprockets-files) +- [The installation is incomplete](#incomplete-installation) +- [NGINX Gzip support is disabled](#nginx-gzip-support) + +### Old processes + +The most likely cause is that an old Puma process is running, instructing clients +to request asset files from a previous release of GitLab. As the files no longer exist, +HTTP 404 errors are returned. + +A reboot is the best way to ensure these old Puma processes are no longer running. + +Alternatively: + +1. Stop Puma: + + ```shell + gitlab-ctl stop puma + ``` + +1. Check for any remaining Puma processes, and kill them: + + ```shell + ps -ef | egrep 'puma[: ]' + kill <processid> + ``` + +1. Verify with `ps` that the Puma processes have stopped running. + +1. Start Puma + + ```shell + gitlab-ctl start puma + ``` + +### Duplicate sprockets files + +The compiled asset files have unique file names in each release. The sprockets files +provide a mapping from the filenames in the application code to the unique filenames. + +```plaintext +/opt/gitlab/embedded/service/gitlab-rails/public/assets/.sprockets-manifest*.json +``` + +Make sure there's only one sprockets file. [Rails uses the first one](https://github.com/rails/sprockets-rails/blob/118ce60b1ffeb7a85640661b014cd2ee3c4e3e56/lib/sprockets/railtie.rb#L201). + +A check for duplicate sprockets files runs during Omnibus GitLab upgrades: + +```plaintext +GitLab discovered stale file(s) from the previous install that need to be cleaned up. +The following files need to be removed: + +/opt/gitlab/embedded/service/gitlab-rails/public/assets/.sprockets-manifest-e16fdb7dd73cfdd64ed9c2cc0e35718a.json +``` + +Options for resolving this include: + +- If you have the output from the package upgrade, remove the specified files. Then restart Puma: + + ```shell + gitlab-ctl restart puma + ``` + +- If you don't have the message, perform a reinstall + (see [incomplete installation](#incomplete-installation) below for more details) + to generate it again. + +- Remove all the sprockets files and then follow the instructions for an [incomplete installation](#incomplete-installation). + +### Incomplete installation + +An incomplete installation could be the cause of this issue. + +Verify the package to determine if this is the problem: + +- For Debian distributions: + + ```shell + apt-get install debsums + debsums -c gitlab-ee + ``` + +- For Red Hat/SUSE (RPM) distributions: + + ```shell + rpm -V gitlab-ee + ``` + +To reinstall the package to fix an incomplete installation: + +1. Check the installed version + + - For Debian distributions: + + ```shell + apt --installed list gitlab-ee + ``` + + - For Red Hat/SUSE (RPM) distributions: + + ```shell + rpm -qa gitlab-ee + ``` + +1. Reinstall the package, specifying the installed version. For example 14.4.0 Enterprise Edition: + + - For Debian distributions: + + ```shell + apt-get install --reinstall gitlab-ee=14.4.0-ee.0 + ``` + + - For Red Hat/SUSE (RPM) distributions: + + ```shell + yum reinstall gitlab-ee-14.4.0 + ``` + +### NGINX Gzip support + +Check whether `nginx['gzip_enabled']` has been disabled: + +```shell +grep gzip /etc/gitlab/gitlab.rb +``` + +This might prevent some assets from being served. +[Read more](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/6087#note_558194395) in one of the related issues. diff --git a/doc/update/versions/gitlab_14_changes.md b/doc/update/versions/gitlab_14_changes.md index 3244e63df2d..fd58d24790a 100644 --- a/doc/update/versions/gitlab_14_changes.md +++ b/doc/update/versions/gitlab_14_changes.md @@ -44,7 +44,7 @@ For more information about upgrading GitLab Helm Chart, see [the release notes f Mixlib::ShellOut::CommandTimeout: Command timed out after 3600s: ``` - A workaround exists to [complete the data change and the upgrade manually](../package/index.md#mixlibshelloutcommandtimeout-rails_migrationgitlab-rails--command-timed-out-after-3600s). + A workaround exists to [complete the data change and the upgrade manually](../package/package_troubleshooting.md#mixlibshelloutcommandtimeout-rails_migrationgitlab-rails--command-timed-out-after-3600s). ### Linux package installations @@ -287,7 +287,7 @@ that may remain stuck permanently in a **pending** state. Mixlib::ShellOut::CommandTimeout: Command timed out after 3600s: ``` - [There is a workaround to complete the data change and the upgrade manually](../package/index.md#mixlibshelloutcommandtimeout-rails_migrationgitlab-rails--command-timed-out-after-3600s) + [There is a workaround to complete the data change and the upgrade manually](../package/package_troubleshooting.md#mixlibshelloutcommandtimeout-rails_migrationgitlab-rails--command-timed-out-after-3600s) - As part of [enabling real-time issue assignees](https://gitlab.com/gitlab-org/gitlab/-/issues/330117), Action Cable is now enabled by default. For **self-compiled (source) installations**, `config/cable.yml` is required to be present. diff --git a/doc/update/versions/gitlab_15_changes.md b/doc/update/versions/gitlab_15_changes.md index df00ca1b46c..7440c701509 100644 --- a/doc/update/versions/gitlab_15_changes.md +++ b/doc/update/versions/gitlab_15_changes.md @@ -303,7 +303,7 @@ if you can't upgrade to 15.11.12 and later. Mixlib::ShellOut::CommandTimeout: Command timed out after 3600s: ``` - A workaround exists to [complete the data change and the upgrade manually](../package/index.md#mixlibshelloutcommandtimeout-rails_migrationgitlab-rails--command-timed-out-after-3600s). + A workaround exists to [complete the data change and the upgrade manually](../package/package_troubleshooting.md#mixlibshelloutcommandtimeout-rails_migrationgitlab-rails--command-timed-out-after-3600s). - The default Sidekiq `max_concurrency` has been changed to 20. This is now consistent in our documentation and product defaults. diff --git a/doc/update/versions/gitlab_16_changes.md b/doc/update/versions/gitlab_16_changes.md index 7f34946c35d..7108f0eaa3f 100644 --- a/doc/update/versions/gitlab_16_changes.md +++ b/doc/update/versions/gitlab_16_changes.md @@ -979,7 +979,7 @@ FATAL: Mixlib::ShellOut::CommandTimeout: rails_migration[gitlab-rails] Mixlib::ShellOut::CommandTimeout: Command timed out after 3600s: ``` -[There is a fix-forward workaround for this issue](../package/index.md#mixlibshelloutcommandtimeout-rails_migrationgitlab-rails--command-timed-out-after-3600s). +[There is a fix-forward workaround for this issue](../package/package_troubleshooting.md#mixlibshelloutcommandtimeout-rails_migrationgitlab-rails--command-timed-out-after-3600s). While the workaround is completing the database changes, GitLab is likely to be in an unusable state, generating `500` errors. The errors are caused by Sidekiq and Puma running diff --git a/lib/banzai/pipeline/gfm_pipeline.rb b/lib/banzai/pipeline/gfm_pipeline.rb index 1b3905f0dde..474efe71b70 100644 --- a/lib/banzai/pipeline/gfm_pipeline.rb +++ b/lib/banzai/pipeline/gfm_pipeline.rb @@ -53,11 +53,11 @@ module Banzai Filter::References::MergeRequestReferenceFilter, Filter::References::SnippetReferenceFilter, Filter::References::CommitRangeReferenceFilter, - Filter::References::CommitReferenceFilter, Filter::References::LabelReferenceFilter, Filter::References::MilestoneReferenceFilter, Filter::References::AlertReferenceFilter, - Filter::References::FeatureFlagReferenceFilter + Filter::References::FeatureFlagReferenceFilter, + Filter::References::CommitReferenceFilter ] end diff --git a/lib/container_registry/gitlab_api_client.rb b/lib/container_registry/gitlab_api_client.rb index 9b6c37da847..276f9b492cb 100644 --- a/lib/container_registry/gitlab_api_client.rb +++ b/lib/container_registry/gitlab_api_client.rb @@ -170,7 +170,7 @@ module ContainerRegistry end # https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/gitlab/api.md#list-repository-tags - def tags(path, page_size: 100, last: nil, before: nil, name: nil, sort: nil) + def tags(path, page_size: 100, last: nil, before: nil, name: nil, sort: nil, referrers: nil) limited_page_size = [page_size, MAX_TAGS_PAGE_SIZE].min with_token_faraday do |faraday_client| url = "#{GITLAB_REPOSITORIES_PATH}/#{path}/tags/list/" @@ -180,6 +180,7 @@ module ContainerRegistry req.params['before'] = before if before req.params['name'] = name if name.present? req.params['sort'] = sort if sort + req.params['referrers'] = 'true' if referrers end unless response.success? diff --git a/lib/container_registry/referrer.rb b/lib/container_registry/referrer.rb new file mode 100644 index 00000000000..e61899b3a1b --- /dev/null +++ b/lib/container_registry/referrer.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module ContainerRegistry + class Referrer + attr_reader :artifact_type, :digest, :tag + + def initialize(artifact_type, digest, tag) + @artifact_type = artifact_type + @digest = digest + @tag = tag + end + end +end diff --git a/lib/container_registry/tag.rb b/lib/container_registry/tag.rb index 70742e8bd38..0000a0641be 100644 --- a/lib/container_registry/tag.rb +++ b/lib/container_registry/tag.rb @@ -4,7 +4,7 @@ module ContainerRegistry class Tag include Gitlab::Utils::StrongMemoize - attr_reader :repository, :name, :updated_at + attr_reader :repository, :name, :updated_at, :referrers attr_writer :created_at, :manifest_digest, :revision, :total_size delegate :registry, :client, to: :repository @@ -14,6 +14,10 @@ module ContainerRegistry @name = name end + def referrers=(refs) + @referrers = Array.wrap(refs).map { |ref| Referrer.new(ref['artifactType'], ref['digest'], self) } + end + def revision @revision || config_blob&.revision end diff --git a/lib/gitlab/git/tree.rb b/lib/gitlab/git/tree.rb index 4747ab55c63..6365ac941de 100644 --- a/lib/gitlab/git/tree.rb +++ b/lib/gitlab/git/tree.rb @@ -12,15 +12,17 @@ module Gitlab class << self # Get list of tree objects # for repository based on commit sha and path - def where( - repository, sha, path = nil, recursive = false, skip_flat_paths = true, rescue_not_found = true, - pagination_params = nil) + def tree_entries( + repository:, + sha:, + path: nil, + recursive: false, + skip_flat_paths: true, + rescue_not_found: true, + pagination_params: nil + ) path = nil if path == '' || path == '/' - tree_entries(repository, sha, path, recursive, skip_flat_paths, rescue_not_found, pagination_params) - end - - def tree_entries(repository, sha, path, recursive, skip_flat_paths, rescue_not_found, pagination_params = nil) wrapped_gitaly_errors do repository.gitaly_commit_client.tree_entries( repository, sha, path, recursive, skip_flat_paths, pagination_params) diff --git a/lib/gitlab/redis/wrapper.rb b/lib/gitlab/redis/wrapper.rb index bb231eec226..b2494c7d43c 100644 --- a/lib/gitlab/redis/wrapper.rb +++ b/lib/gitlab/redis/wrapper.rb @@ -30,7 +30,12 @@ module Gitlab end def pool - @pool ||= ConnectionPool.new(size: pool_size, name: store_name.underscore) { redis } + @pool ||= if config_fallback && + config_fallback.params.except(:instrumentation_class) == params.except(:instrumentation_class) + config_fallback.pool + else + ConnectionPool.new(size: pool_size, name: store_name.underscore) { redis } + end end def pool_size diff --git a/locale/gitlab.pot b/locale/gitlab.pot index a633c3bfabf..369e49c0529 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -4964,6 +4964,9 @@ msgstr "" msgid "Allow users to register any application to use GitLab as an OAuth provider. This setting does not affect group-level OAuth applications." msgstr "" +msgid "Allow users with up to Guest role to create groups and personal projects" +msgstr "" + msgid "Allowed" msgstr "" @@ -23523,6 +23526,9 @@ msgstr "" msgid "GroupSettings|Enforce SSH Certificates" msgstr "" +msgid "GroupSettings|Experiment" +msgstr "" + msgid "GroupSettings|Experiment and Beta features" msgstr "" @@ -23574,7 +23580,7 @@ msgstr "" msgid "GroupSettings|Reporting" msgstr "" -msgid "GroupSettings|Security policy custom CI Experiment" +msgid "GroupSettings|Security policy Pipeline Execution Action Experiment" msgstr "" msgid "GroupSettings|Security policy scope Experiment" diff --git a/scripts/lint/unused_helper_methods.rb b/scripts/lint/unused_helper_methods.rb new file mode 100755 index 00000000000..b7b651614ef --- /dev/null +++ b/scripts/lint/unused_helper_methods.rb @@ -0,0 +1,55 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# Inspired in part by https://gist.github.com/kylefox/617b0bead5f53dc53a224a8651328c92 +# + +require 'parallel' + +start = Process.clock_gettime(Process::CLOCK_MONOTONIC) + +# Build an array of filename globs to process. +# Only search file types that might use or define a helper. +# +extensions = %w[rb haml erb].map { |ext| "{ee/,}app/**/*.#{ext}" } + +# Build a hash of all the source files to search. +# Key is filename, value is an array of the lines. +# +source_files = {} + +Dir.glob(extensions).each do |filename| + source_files[filename] = File.readlines(filename) +end + +# Build an array of {method, file} hashes defined in app/helper/* files. +# +helpers = source_files.keys.grep(%r{app/helpers}).flat_map do |filename| + source_files[filename].flat_map do |line| + line =~ /def ([^(\s]+)/ ? [{ method: Regexp.last_match(1).chomp, file: filename }] : [] + end +end + +puts "Scanning #{source_files.size} files for #{helpers.size} helpers..." + +# Combine all the source code into one big string, because regex are fast. +# +source_code = source_files.values.flatten.join + +# Iterate over all the helpers and reject any that appear anywhere in the complete source. +# +unused = Parallel.flat_map(helpers, progress: 'Checking helpers') do |helper| + /(?<!def )#{Regexp.quote(helper[:method].sub(/^self\./, ''))}\W/.match?(source_code) ? [] : helper +end + +finish = Process.clock_gettime(Process::CLOCK_MONOTONIC) + +if unused + puts "\nFound #{unused.size} unused helpers:\n\n" + unused.each { |helper| puts " - [ ] `#{helper[:file]}`: `#{helper[:method]}`" } + puts "\n" +else + puts 'No unused helpers were found.' +end + +puts "Finished in #{finish - start} seconds." diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index 88d9d1228e3..c76775c820f 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -43,6 +43,49 @@ RSpec.describe ProjectsController, feature_category: :groups_and_projects do end end end + + context 'with managable group' do + context 'when managable_group_count is 1' do + before do + group.add_owner(user) + end + + it 'renders the template' do + get :new + + expect(response).to have_gitlab_http_status(:ok) + expect(response).to render_template('new') + end + end + + context 'when managable_group_count is 0' do + context 'when create_projects on personal namespace is allowed' do + before do + allow(user).to receive(:can_create_project?).and_return(true) + end + + it 'renders the template' do + get :new + + expect(response).to have_gitlab_http_status(:ok) + expect(response).to render_template('new') + end + end + + context 'when create_projects on personal namespace is not allowed' do + before do + stub_application_setting(allow_project_creation_for_guest_and_below: false) + end + + it 'responds with status 404' do + get :new + + expect(response).to have_gitlab_http_status(:not_found) + expect(response).not_to render_template('new') + end + end + end + end end end diff --git a/spec/features/admin/admin_abuse_reports_spec.rb b/spec/features/admin/admin_abuse_reports_spec.rb index 5e98d2ffcf3..9c425f83508 100644 --- a/spec/features/admin/admin_abuse_reports_spec.rb +++ b/spec/features/admin/admin_abuse_reports_spec.rb @@ -17,7 +17,7 @@ RSpec.describe "Admin::AbuseReports", :js, feature_category: :insider_threat do before do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) visit admin_abuse_reports_path end diff --git a/spec/features/admin/admin_appearance_spec.rb b/spec/features/admin/admin_appearance_spec.rb index 2a9bff55dce..ec63e43d183 100644 --- a/spec/features/admin/admin_appearance_spec.rb +++ b/spec/features/admin/admin_appearance_spec.rb @@ -12,7 +12,7 @@ RSpec.describe 'Admin Appearance', feature_category: :shared do it 'create new appearance' do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) visit admin_application_settings_appearances_path fill_in 'appearance_title', with: 'MyCompany' @@ -39,7 +39,7 @@ RSpec.describe 'Admin Appearance', feature_category: :shared do it 'preview sign-in page appearance' do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) visit admin_application_settings_appearances_path click_link "Sign-in page" @@ -53,7 +53,7 @@ RSpec.describe 'Admin Appearance', feature_category: :shared do it 'preview new project page appearance', :js do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) visit admin_application_settings_appearances_path click_link "New project page" @@ -64,7 +64,7 @@ RSpec.describe 'Admin Appearance', feature_category: :shared do context 'Custom system header and footer' do before do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) end context 'when system header and footer messages are empty' do @@ -102,7 +102,7 @@ RSpec.describe 'Admin Appearance', feature_category: :shared do it 'custom new project page', :js do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) visit new_project_path click_link 'Create blank project' @@ -112,7 +112,7 @@ RSpec.describe 'Admin Appearance', feature_category: :shared do context 'Profile page with custom profile image guidelines' do before do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) visit admin_application_settings_appearances_path fill_in 'appearance_profile_image_guidelines', with: 'Custom profile image guidelines, please :smile:!' click_button 'Update appearance settings' @@ -128,7 +128,7 @@ RSpec.describe 'Admin Appearance', feature_category: :shared do it 'appearance logo' do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) visit admin_application_settings_appearances_path attach_file(:appearance_logo, logo_fixture) @@ -141,7 +141,7 @@ RSpec.describe 'Admin Appearance', feature_category: :shared do it 'appearance pwa icon' do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) visit admin_application_settings_appearances_path attach_file(:appearance_pwa_icon, logo_fixture) @@ -154,7 +154,7 @@ RSpec.describe 'Admin Appearance', feature_category: :shared do it 'header logos' do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) visit admin_application_settings_appearances_path attach_file(:appearance_header_logo, logo_fixture) @@ -167,7 +167,7 @@ RSpec.describe 'Admin Appearance', feature_category: :shared do it 'Favicon' do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) visit admin_application_settings_appearances_path attach_file(:appearance_favicon, logo_fixture) diff --git a/spec/features/admin/admin_browse_spam_logs_spec.rb b/spec/features/admin/admin_browse_spam_logs_spec.rb index f781e2adf07..1f89232759c 100644 --- a/spec/features/admin/admin_browse_spam_logs_spec.rb +++ b/spec/features/admin/admin_browse_spam_logs_spec.rb @@ -8,7 +8,7 @@ RSpec.describe 'Admin browse spam logs', feature_category: :shared do before do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) end it 'browse spam logs' do diff --git a/spec/features/admin/admin_deploy_keys_spec.rb b/spec/features/admin/admin_deploy_keys_spec.rb index f9510ef296a..d6d021aeafc 100644 --- a/spec/features/admin/admin_deploy_keys_spec.rb +++ b/spec/features/admin/admin_deploy_keys_spec.rb @@ -12,7 +12,7 @@ RSpec.describe 'admin deploy keys', :js, feature_category: :system_access do before do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) end it 'show all public deploy keys' do diff --git a/spec/features/admin/admin_dev_ops_reports_spec.rb b/spec/features/admin/admin_dev_ops_reports_spec.rb index 99d43e6b0da..e820ae866a1 100644 --- a/spec/features/admin/admin_dev_ops_reports_spec.rb +++ b/spec/features/admin/admin_dev_ops_reports_spec.rb @@ -6,7 +6,7 @@ RSpec.describe 'DevOps Report page', :js, feature_category: :devops_reports do before do admin = create(:admin) sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) end context 'without licensed feature devops adoption' do diff --git a/spec/features/admin/admin_disables_git_access_protocol_spec.rb b/spec/features/admin/admin_disables_git_access_protocol_spec.rb index 76620b93557..039968025a9 100644 --- a/spec/features/admin/admin_disables_git_access_protocol_spec.rb +++ b/spec/features/admin/admin_disables_git_access_protocol_spec.rb @@ -12,7 +12,7 @@ RSpec.describe 'Admin disables Git access protocol', :js, feature_category: :sou before do stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) end context 'with HTTP disabled' do diff --git a/spec/features/admin/admin_disables_two_factor_spec.rb b/spec/features/admin/admin_disables_two_factor_spec.rb index eed20d449cd..cb3c8973872 100644 --- a/spec/features/admin/admin_disables_two_factor_spec.rb +++ b/spec/features/admin/admin_disables_two_factor_spec.rb @@ -8,7 +8,7 @@ RSpec.describe 'Admin disables 2FA for a user', feature_category: :system_access it 'successfully', :js do admin = create(:admin) sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) user = create(:user, :two_factor) edit_user(user) @@ -27,7 +27,7 @@ RSpec.describe 'Admin disables 2FA for a user', feature_category: :system_access it 'for a user without 2FA enabled' do admin = create(:admin) sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) user = create(:user) edit_user(user) diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb index f071da1835a..283caddab6a 100644 --- a/spec/features/admin/admin_groups_spec.rb +++ b/spec/features/admin/admin_groups_spec.rb @@ -15,7 +15,7 @@ RSpec.describe 'Admin Groups', feature_category: :groups_and_projects do before do sign_in(current_user) - gitlab_enable_admin_mode_sign_in(current_user) + enable_admin_mode!(current_user) stub_application_setting(default_group_visibility: internal) end diff --git a/spec/features/admin/admin_health_check_spec.rb b/spec/features/admin/admin_health_check_spec.rb index 66014e676d5..fa91159c5f5 100644 --- a/spec/features/admin/admin_health_check_spec.rb +++ b/spec/features/admin/admin_health_check_spec.rb @@ -10,7 +10,7 @@ RSpec.describe "Admin Health Check", :js, feature_category: :error_budgets do before do stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) end describe '#show' do diff --git a/spec/features/admin/admin_hook_logs_spec.rb b/spec/features/admin/admin_hook_logs_spec.rb index 0a537e65b99..146c83dbeee 100644 --- a/spec/features/admin/admin_hook_logs_spec.rb +++ b/spec/features/admin/admin_hook_logs_spec.rb @@ -9,7 +9,7 @@ RSpec.describe 'Admin::HookLogs', feature_category: :webhooks do before do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) end it 'show list of hook logs' do diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb index 2aec5baf351..9bdb7ce000f 100644 --- a/spec/features/admin/admin_hooks_spec.rb +++ b/spec/features/admin/admin_hooks_spec.rb @@ -9,7 +9,7 @@ RSpec.describe 'Admin::Hooks', feature_category: :webhooks do before do sign_in(user) - gitlab_enable_admin_mode_sign_in(user) + enable_admin_mode!(user) end describe 'GET /admin/hooks' do diff --git a/spec/features/admin/admin_jobs_spec.rb b/spec/features/admin/admin_jobs_spec.rb index b3e21d02354..fc775c180ff 100644 --- a/spec/features/admin/admin_jobs_spec.rb +++ b/spec/features/admin/admin_jobs_spec.rb @@ -8,7 +8,7 @@ RSpec.describe 'Admin Jobs', :js, feature_category: :continuous_integration do before do admin = create(:admin) sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) end describe 'GET /admin/jobs' do diff --git a/spec/features/admin/admin_labels_spec.rb b/spec/features/admin/admin_labels_spec.rb index 47dc8577037..2fe68363062 100644 --- a/spec/features/admin/admin_labels_spec.rb +++ b/spec/features/admin/admin_labels_spec.rb @@ -11,7 +11,7 @@ RSpec.describe 'admin issues labels', feature_category: :team_planning do before do admin = create(:admin) sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) end describe 'list' do diff --git a/spec/features/admin/admin_manage_applications_spec.rb b/spec/features/admin/admin_manage_applications_spec.rb index b4c77e802a8..3e351af6121 100644 --- a/spec/features/admin/admin_manage_applications_spec.rb +++ b/spec/features/admin/admin_manage_applications_spec.rb @@ -10,7 +10,7 @@ RSpec.describe 'admin manage applications', feature_category: :system_access do before do admin = create(:admin) sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) end include_examples 'manage applications' diff --git a/spec/features/admin/admin_mode/login_spec.rb b/spec/features/admin/admin_mode/login_spec.rb index 5e4935ee4b1..5298407deb3 100644 --- a/spec/features/admin/admin_mode/login_spec.rb +++ b/spec/features/admin/admin_mode/login_spec.rb @@ -24,7 +24,7 @@ RSpec.describe 'Admin Mode Login', feature_category: :system_access do repeated_otp = user.current_otp enter_code(repeated_otp) - gitlab_enable_admin_mode_sign_in(user, use_mock_admin_mode: false) + enable_admin_mode!(user, use_ui: true) expect(page).to have_content(_('Enter verification code')) @@ -41,7 +41,7 @@ RSpec.describe 'Admin Mode Login', feature_category: :system_access do expect(page).to have_content('Enter verification code') enter_code(user.current_otp) - gitlab_enable_admin_mode_sign_in(user, use_mock_admin_mode: false) + enable_admin_mode!(user, use_ui: true) expect(page).to have_content(_('Enter verification code')) end diff --git a/spec/features/admin/admin_mode/logout_spec.rb b/spec/features/admin/admin_mode/logout_spec.rb index 584151726a6..beac36e28c5 100644 --- a/spec/features/admin/admin_mode/logout_spec.rb +++ b/spec/features/admin/admin_mode/logout_spec.rb @@ -12,7 +12,7 @@ RSpec.describe 'Admin Mode Logout', :js, feature_category: :system_access do # TODO: This used to use gitlab_sign_in, instead of sign_in, but that is buggy. See # this issue to look into why: https://gitlab.com/gitlab-org/gitlab/-/issues/331851 sign_in(user) - gitlab_enable_admin_mode_sign_in(user, use_mock_admin_mode: false) + enable_admin_mode!(user, use_ui: true) visit admin_root_path end diff --git a/spec/features/admin/admin_mode/workers_spec.rb b/spec/features/admin/admin_mode/workers_spec.rb index 124c43eef9d..f0cea425bb7 100644 --- a/spec/features/admin/admin_mode/workers_spec.rb +++ b/spec/features/admin/admin_mode/workers_spec.rb @@ -34,7 +34,7 @@ RSpec.describe 'Admin mode for workers', :request_store, feature_category: :syst context 'when admin mode enabled', :delete do before do - gitlab_enable_admin_mode_sign_in(user) + enable_admin_mode!(user) end it 'can delete user', :js do @@ -67,6 +67,6 @@ RSpec.describe 'Admin mode for workers', :request_store, feature_category: :syst Sidekiq::Worker.drain_all sign_in(user) - gitlab_enable_admin_mode_sign_in(user) + enable_admin_mode!(user) end end diff --git a/spec/features/admin/admin_mode_spec.rb b/spec/features/admin/admin_mode_spec.rb index 2a655cdb1f4..29eb24fa9b8 100644 --- a/spec/features/admin/admin_mode_spec.rb +++ b/spec/features/admin/admin_mode_spec.rb @@ -69,7 +69,7 @@ RSpec.describe 'Admin mode', :js, feature_category: :shared do context 'when in admin_mode' do before do - gitlab_enable_admin_mode_sign_in(admin, use_mock_admin_mode: false) + enable_admin_mode!(admin, use_ui: true) end it 'contains link to leave admin mode' do diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb index b793299e253..978b2176431 100644 --- a/spec/features/admin/admin_projects_spec.rb +++ b/spec/features/admin/admin_projects_spec.rb @@ -14,7 +14,7 @@ RSpec.describe "Admin::Projects", feature_category: :groups_and_projects do before do sign_in(current_user) - gitlab_enable_admin_mode_sign_in(current_user) + enable_admin_mode!(current_user) end describe 'when membership is set to expire', :js do diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb index 653458710e3..2b4ceb05f00 100644 --- a/spec/features/admin/admin_runners_spec.rb +++ b/spec/features/admin/admin_runners_spec.rb @@ -11,7 +11,7 @@ RSpec.describe "Admin Runners", feature_category: :fleet_visibility do before do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) end describe "Admin Runners page", :js do diff --git a/spec/features/admin/admin_search_settings_spec.rb b/spec/features/admin/admin_search_settings_spec.rb index 3254bf75738..c20a50cf218 100644 --- a/spec/features/admin/admin_search_settings_spec.rb +++ b/spec/features/admin/admin_search_settings_spec.rb @@ -8,7 +8,7 @@ RSpec.describe 'Admin searches application settings', :js, feature_category: :gl before do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) end context 'in appearances page' do diff --git a/spec/features/admin/admin_sees_background_migrations_spec.rb b/spec/features/admin/admin_sees_background_migrations_spec.rb index ae307b8038c..43b920c657c 100644 --- a/spec/features/admin/admin_sees_background_migrations_spec.rb +++ b/spec/features/admin/admin_sees_background_migrations_spec.rb @@ -18,7 +18,7 @@ RSpec.describe "Admin > Admin sees background migrations", feature_category: :da before do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) end it 'can navigate to background migrations', :js do diff --git a/spec/features/admin/admin_sees_project_statistics_spec.rb b/spec/features/admin/admin_sees_project_statistics_spec.rb index d977735daf8..07f90d247cd 100644 --- a/spec/features/admin/admin_sees_project_statistics_spec.rb +++ b/spec/features/admin/admin_sees_project_statistics_spec.rb @@ -7,7 +7,7 @@ RSpec.describe "Admin > Admin sees project statistics", feature_category: :group before do sign_in(current_user) - gitlab_enable_admin_mode_sign_in(current_user) + enable_admin_mode!(current_user) visit admin_project_path(project) end diff --git a/spec/features/admin/admin_sees_projects_statistics_spec.rb b/spec/features/admin/admin_sees_projects_statistics_spec.rb index 3363a67ea90..cc6ccbab0a0 100644 --- a/spec/features/admin/admin_sees_projects_statistics_spec.rb +++ b/spec/features/admin/admin_sees_projects_statistics_spec.rb @@ -10,7 +10,7 @@ RSpec.describe "Admin > Admin sees projects statistics", feature_category: :grou create(:project, :repository) { |project| project.statistics.destroy! } sign_in(current_user) - gitlab_enable_admin_mode_sign_in(current_user) + enable_admin_mode!(current_user) visit admin_projects_path end diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb index 77707a67d58..d1fdbfc5329 100644 --- a/spec/features/admin/admin_settings_spec.rb +++ b/spec/features/admin/admin_settings_spec.rb @@ -13,7 +13,7 @@ RSpec.describe 'Admin updates settings', feature_category: :shared do before do stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin, use_mock_admin_mode: false) + enable_admin_mode!(admin, use_ui: true) end context 'General page' do diff --git a/spec/features/admin/admin_system_info_spec.rb b/spec/features/admin/admin_system_info_spec.rb index 71a0b829932..f285fefe6db 100644 --- a/spec/features/admin/admin_system_info_spec.rb +++ b/spec/features/admin/admin_system_info_spec.rb @@ -6,7 +6,7 @@ RSpec.describe 'Admin System Info', feature_category: :shared do before do admin = create(:admin) sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) end describe 'GET /admin/system_info' do diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb index 543dc2cc2a6..7cfe0cdbc81 100644 --- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb +++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb @@ -11,7 +11,7 @@ RSpec.describe 'Admin > Users > Impersonation Tokens', :js, feature_category: :s before do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) end describe "token creation" do diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb index 9ab5b1fd3bb..f09c1a59b0d 100644 --- a/spec/features/admin/admin_users_spec.rb +++ b/spec/features/admin/admin_users_spec.rb @@ -7,7 +7,7 @@ RSpec.describe "Admin::Users", feature_category: :user_management do before do sign_in(current_user) - gitlab_enable_admin_mode_sign_in(current_user) + enable_admin_mode!(current_user) end describe 'Tabs' do diff --git a/spec/features/admin/admin_uses_repository_checks_spec.rb b/spec/features/admin/admin_uses_repository_checks_spec.rb index 05232de35e5..a628344bfeb 100644 --- a/spec/features/admin/admin_uses_repository_checks_spec.rb +++ b/spec/features/admin/admin_uses_repository_checks_spec.rb @@ -25,7 +25,7 @@ RSpec.describe 'Admin uses repository checks', :request_store, feature_category: context 'when admin mode is enabled' do before do - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) end it 'to trigger a single check', :js do diff --git a/spec/features/admin/broadcast_messages_spec.rb b/spec/features/admin/broadcast_messages_spec.rb index e4a2e31ee1c..16651ffa07e 100644 --- a/spec/features/admin/broadcast_messages_spec.rb +++ b/spec/features/admin/broadcast_messages_spec.rb @@ -7,7 +7,7 @@ RSpec.describe 'Admin Broadcast Messages', :js, feature_category: :onboarding do it 'previews, creates and edits a broadcast message' do admin = create(:admin) sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) # create visit admin_broadcast_messages_path diff --git a/spec/features/admin/dashboard_spec.rb b/spec/features/admin/dashboard_spec.rb index 06f9c531e74..9e8f5138815 100644 --- a/spec/features/admin/dashboard_spec.rb +++ b/spec/features/admin/dashboard_spec.rb @@ -8,7 +8,7 @@ RSpec.describe 'admin visits dashboard' do before do admin = create(:admin) sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) end context 'counting forks', :js, feature_category: :source_code_management do diff --git a/spec/features/admin/users/user_identities_spec.rb b/spec/features/admin/users/user_identities_spec.rb index 903ddbed399..6db94750761 100644 --- a/spec/features/admin/users/user_identities_spec.rb +++ b/spec/features/admin/users/user_identities_spec.rb @@ -8,7 +8,7 @@ RSpec.describe 'Admin::Users::UserIdentities', feature_category: :user_managemen before do sign_in(current_user) - gitlab_enable_admin_mode_sign_in(current_user, use_mock_admin_mode: false) + enable_admin_mode!(current_user, use_ui: true) end describe 'GET /admin/users/:id' do diff --git a/spec/features/admin/users/user_impersonation_spec.rb b/spec/features/admin/users/user_impersonation_spec.rb index 81c1d0de115..215afc40d80 100644 --- a/spec/features/admin/users/user_impersonation_spec.rb +++ b/spec/features/admin/users/user_impersonation_spec.rb @@ -8,7 +8,7 @@ RSpec.describe 'Admin::Users::UserImpersonation', feature_category: :user_manage before do sign_in(current_user) - gitlab_enable_admin_mode_sign_in(current_user, use_mock_admin_mode: false) + enable_admin_mode!(current_user, use_ui: true) end describe 'GET /admin/users/:id' do diff --git a/spec/features/admin/users/user_spec.rb b/spec/features/admin/users/user_spec.rb index d6f53fc6ca4..b7e7a037ffc 100644 --- a/spec/features/admin/users/user_spec.rb +++ b/spec/features/admin/users/user_spec.rb @@ -11,7 +11,7 @@ RSpec.describe 'Admin::Users::User', feature_category: :user_management do before do sign_in(current_user) - gitlab_enable_admin_mode_sign_in(current_user, use_mock_admin_mode: false) + enable_admin_mode!(current_user, use_ui: true) end describe 'GET /admin/users/:id' do diff --git a/spec/features/admin/users/users_spec.rb b/spec/features/admin/users/users_spec.rb index d2f3b0e8e40..20cedda626b 100644 --- a/spec/features/admin/users/users_spec.rb +++ b/spec/features/admin/users/users_spec.rb @@ -12,7 +12,7 @@ RSpec.describe 'Admin::Users', feature_category: :user_management do before do sign_in(current_user) - gitlab_enable_admin_mode_sign_in(current_user) + enable_admin_mode!(current_user) end describe 'GET /admin/users', :js do diff --git a/spec/features/admin_variables_spec.rb b/spec/features/admin_variables_spec.rb index caa94209e50..0fc0ae9e199 100644 --- a/spec/features/admin_variables_spec.rb +++ b/spec/features/admin_variables_spec.rb @@ -11,7 +11,7 @@ RSpec.describe 'Instance variables', :js, feature_category: :secrets_management before do stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) visit page_path wait_for_requests diff --git a/spec/features/boards/keyboard_shortcut_spec.rb b/spec/features/boards/keyboard_shortcut_spec.rb index 6f03f6db3ab..d4777fa671c 100644 --- a/spec/features/boards/keyboard_shortcut_spec.rb +++ b/spec/features/boards/keyboard_shortcut_spec.rb @@ -11,7 +11,7 @@ RSpec.describe 'Issue Boards shortcut', :js, feature_category: :team_planning do admin = create(:admin) sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) visit project_path(project) end @@ -30,7 +30,7 @@ RSpec.describe 'Issue Boards shortcut', :js, feature_category: :team_planning do before do admin = create(:admin) sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) visit project_path(project) end diff --git a/spec/features/broadcast_messages_spec.rb b/spec/features/broadcast_messages_spec.rb index f887242384c..867ed3c3acb 100644 --- a/spec/features/broadcast_messages_spec.rb +++ b/spec/features/broadcast_messages_spec.rb @@ -121,7 +121,7 @@ RSpec.describe 'Broadcast Messages', feature_category: :onboarding do stub_const('Gitlab::Cache::JsonCaches::JsonKeyed::STRATEGY_KEY_COMPONENTS', original_strategy_value) admin = create(:admin) sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) visit admin_broadcast_messages_path diff --git a/spec/features/clusters/cluster_detail_page_spec.rb b/spec/features/clusters/cluster_detail_page_spec.rb index 31dec5e38da..78ac752a375 100644 --- a/spec/features/clusters/cluster_detail_page_spec.rb +++ b/spec/features/clusters/cluster_detail_page_spec.rb @@ -145,7 +145,7 @@ RSpec.describe 'Clusterable > Show page', feature_category: :deployment_manageme let(:cluster) { create(:cluster, :provided_by_gcp, :instance) } before do - gitlab_enable_admin_mode_sign_in(current_user) + enable_admin_mode!(current_user) end it_behaves_like 'show page' do diff --git a/spec/features/expand_collapse_diffs_spec.rb b/spec/features/expand_collapse_diffs_spec.rb index 7fbd6c4e235..523ef8990bb 100644 --- a/spec/features/expand_collapse_diffs_spec.rb +++ b/spec/features/expand_collapse_diffs_spec.rb @@ -12,7 +12,7 @@ RSpec.describe 'Expand and collapse diffs', :js, feature_category: :source_code_ allow(Gitlab::CurrentSettings).to receive(:diff_max_patch_bytes).and_return(100.kilobytes) sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) wait_for_requests diff --git a/spec/features/gitlab_experiments_spec.rb b/spec/features/gitlab_experiments_spec.rb index facf4994c44..0d0afa801c8 100644 --- a/spec/features/gitlab_experiments_spec.rb +++ b/spec/features/gitlab_experiments_spec.rb @@ -12,7 +12,7 @@ RSpec.describe "Gitlab::Experiment", :js, feature_category: :activation do before do admin = create(:admin) sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) stub_experiments(null_hypothesis: :candidate) end diff --git a/spec/features/groups/clusters/user_spec.rb b/spec/features/groups/clusters/user_spec.rb index 9089fba1886..24552daa11b 100644 --- a/spec/features/groups/clusters/user_spec.rb +++ b/spec/features/groups/clusters/user_spec.rb @@ -130,7 +130,7 @@ RSpec.describe 'User Cluster', :js, feature_category: :environment_management do gitlab_sign_out gitlab_sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) visit group_clusters_path(group) end diff --git a/spec/features/groups/members/list_members_spec.rb b/spec/features/groups/members/list_members_spec.rb index b16d61a5fe4..b6e0deb2e73 100644 --- a/spec/features/groups/members/list_members_spec.rb +++ b/spec/features/groups/members/list_members_spec.rb @@ -66,7 +66,7 @@ RSpec.describe 'Groups > Members > List members', :js, feature_category: :groups it 'shows 2FA badge to admins' do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) visit group_group_members_path(group) diff --git a/spec/features/help_dropdown_spec.rb b/spec/features/help_dropdown_spec.rb index 3e4c0bc55fe..89040ec9ab6 100644 --- a/spec/features/help_dropdown_spec.rb +++ b/spec/features/help_dropdown_spec.rb @@ -27,7 +27,7 @@ RSpec.describe "Help Dropdown", :js, feature_category: :shared do context "when severity is #{severity}" do before do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) allow_next_instance_of(VersionCheck) do |instance| allow(instance).to receive(:response).and_return({ "severity" => severity }) diff --git a/spec/features/merge_requests/admin_views_hidden_merge_requests_spec.rb b/spec/features/merge_requests/admin_views_hidden_merge_requests_spec.rb index 7e33946f713..f52520313b2 100644 --- a/spec/features/merge_requests/admin_views_hidden_merge_requests_spec.rb +++ b/spec/features/merge_requests/admin_views_hidden_merge_requests_spec.rb @@ -11,7 +11,7 @@ RSpec.describe 'Admin views hidden merge requests', feature_category: :insider_t before do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) visit(project_merge_requests_path(project)) end diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb index c223053606b..e7e419a4c60 100644 --- a/spec/features/projects/clusters/gcp_spec.rb +++ b/spec/features/projects/clusters/gcp_spec.rb @@ -110,7 +110,7 @@ RSpec.describe 'Gcp Cluster', :js, feature_category: :deployment_management do before do stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') - gitlab_enable_admin_mode_sign_in(user) + enable_admin_mode!(user) visit general_admin_application_settings_path end diff --git a/spec/features/projects/clusters/user_spec.rb b/spec/features/projects/clusters/user_spec.rb index 067963e06e0..bc4d64dad21 100644 --- a/spec/features/projects/clusters/user_spec.rb +++ b/spec/features/projects/clusters/user_spec.rb @@ -120,7 +120,7 @@ RSpec.describe 'User Cluster', :js, feature_category: :deployment_management do gitlab_sign_out gitlab_sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) visit project_clusters_path(project) end diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb index c6a770cee9e..5f1bc4f86c1 100644 --- a/spec/features/projects/features_visibility_spec.rb +++ b/spec/features/projects/features_visibility_spec.rb @@ -153,7 +153,7 @@ RSpec.describe 'Edit Project Settings', feature_category: :groups_and_projects d before do non_member.update_attribute(:admin, true) sign_in(non_member) - gitlab_enable_admin_mode_sign_in(non_member) + enable_admin_mode!(non_member) end it 'renders 404 if feature is disabled' do diff --git a/spec/features/projects/members/manage_members_spec.rb b/spec/features/projects/members/manage_members_spec.rb index 3423c636c2b..2ab0e63d840 100644 --- a/spec/features/projects/members/manage_members_spec.rb +++ b/spec/features/projects/members/manage_members_spec.rb @@ -265,7 +265,7 @@ RSpec.describe 'Projects > Members > Manage members', :js, feature_category: :on it 'shows 2FA badge to admins' do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) visit_members_page diff --git a/spec/features/projects/user_views_empty_project_spec.rb b/spec/features/projects/user_views_empty_project_spec.rb index ed34b109d29..7dc3dd1da1e 100644 --- a/spec/features/projects/user_views_empty_project_spec.rb +++ b/spec/features/projects/user_views_empty_project_spec.rb @@ -43,7 +43,7 @@ RSpec.describe 'User views an empty project', feature_category: :groups_and_proj context 'when admin mode is enabled' do before do sign_in(user) - gitlab_enable_admin_mode_sign_in(user) + enable_admin_mode!(user) end it_behaves_like 'allowing push to default branch' diff --git a/spec/features/protected_branches_spec.rb b/spec/features/protected_branches_spec.rb index 41105630204..c29323cba27 100644 --- a/spec/features/protected_branches_spec.rb +++ b/spec/features/protected_branches_spec.rb @@ -82,7 +82,7 @@ RSpec.describe 'Protected Branches', :js, feature_category: :source_code_managem context 'logged in as admin' do before do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) end describe "explicit protected branches" do diff --git a/spec/features/usage_stats_consent_spec.rb b/spec/features/usage_stats_consent_spec.rb index ebf1cd9e143..5436018250d 100644 --- a/spec/features/usage_stats_consent_spec.rb +++ b/spec/features/usage_stats_consent_spec.rb @@ -19,7 +19,7 @@ RSpec.describe 'Usage stats consent', feature_category: :service_ping do end gitlab_sign_in(user) - gitlab_enable_admin_mode_sign_in(user) + enable_admin_mode!(user) end shared_examples 'dismissible banner' do |button_text| diff --git a/spec/features/user_settings/active_sessions_spec.rb b/spec/features/user_settings/active_sessions_spec.rb index 5d1d4bc6490..bc0693d79e1 100644 --- a/spec/features/user_settings/active_sessions_spec.rb +++ b/spec/features/user_settings/active_sessions_spec.rb @@ -47,7 +47,7 @@ RSpec.describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state, fe ) gitlab_sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) visit admin_user_path(user) diff --git a/spec/frontend/alerts_settings/components/alerts_settings_form_spec.js b/spec/frontend/alerts_settings/components/alerts_settings_form_spec.js index e6b38a1e824..41690e1b5be 100644 --- a/spec/frontend/alerts_settings/components/alerts_settings_form_spec.js +++ b/spec/frontend/alerts_settings/components/alerts_settings_form_spec.js @@ -6,30 +6,48 @@ import { GlFormTextarea, GlTab, GlLink, + GlModal, } from '@gitlab/ui'; import { mount } from '@vue/test-utils'; -import { nextTick } from 'vue'; +import Vue, { nextTick } from 'vue'; +import VueApollo from 'vue-apollo'; import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import waitForPromises from 'helpers/wait_for_promises'; import MappingBuilder from '~/alerts_settings/components/alert_mapping_builder.vue'; import AlertsSettingsForm from '~/alerts_settings/components/alerts_settings_form.vue'; import { typeSet } from '~/alerts_settings/constants'; -import alertFields from '../mocks/alert_fields.json'; +import createMockApollo from 'helpers/mock_apollo_helper'; import parsedMapping from '../mocks/parsed_mapping.json'; +import alertFields from '../mocks/alert_fields.json'; const scrollIntoViewMock = jest.fn(); HTMLElement.prototype.scrollIntoView = scrollIntoViewMock; +Vue.use(VueApollo); + describe('AlertsSettingsForm', () => { let wrapper; const mockToastShow = jest.fn(); + let apolloProvider; + + const createComponent = async ({ + props = {}, + multiIntegrations = true, + currentIntegration = null, + } = {}) => { + const mockResolvers = { + Query: { + currentIntegration() { + return currentIntegration; + }, + }, + }; + + apolloProvider = createMockApollo([], mockResolvers); - const createComponent = ({ data = {}, props = {}, multiIntegrations = true } = {}) => { wrapper = extendedWrapper( mount(AlertsSettingsForm, { - data() { - return { ...data }; - }, + apolloProvider, propsData: { loading: false, canAddIntegration: true, @@ -39,15 +57,14 @@ describe('AlertsSettingsForm', () => { multiIntegrations, }, mocks: { - $apollo: { - query: jest.fn(), - }, $toast: { show: mockToastShow, }, }, }), ); + + await waitForPromises(); }; const findForm = () => wrapper.findComponent(GlForm); @@ -55,6 +72,7 @@ describe('AlertsSettingsForm', () => { const findFormFields = () => wrapper.findAllComponents(GlFormInput); const findFormToggle = () => wrapper.findComponent(GlToggle); const findSamplePayloadSection = () => wrapper.findByTestId('sample-payload-section'); + const findResetPayloadModal = () => wrapper.findComponent(GlModal); const findMappingBuilder = () => wrapper.findComponent(MappingBuilder); const findSubmitButton = () => wrapper.findByTestId('integration-form-submit'); const findMultiSupportText = () => wrapper.findByTestId('multi-integrations-not-supported'); @@ -76,9 +94,13 @@ describe('AlertsSettingsForm', () => { findFormToggle().vm.$emit('change', true); }; + afterEach(() => { + apolloProvider = null; + }); + describe('with default values', () => { - beforeEach(() => { - createComponent(); + beforeEach(async () => { + await createComponent(); }); it('render the initial form with only an integration type dropdown', () => { @@ -94,21 +116,23 @@ describe('AlertsSettingsForm', () => { expect(findFormFields().at(0).isVisible()).toBe(true); }); - it('disables the dropdown and shows help text when multi integrations are not supported', () => { - createComponent({ props: { canAddIntegration: false } }); + it('disables the dropdown and shows help text when multi integrations are not supported', async () => { + await createComponent({ props: { canAddIntegration: false } }); + expect(findSelect().attributes('disabled')).toBeDefined(); expect(findMultiSupportText().exists()).toBe(true); }); it('hides the name input when the selected value is prometheus', async () => { - createComponent(); + await createComponent(); await selectOptionAtIndex(2); expect(findFormFields()).toHaveLength(0); }); - it('verify pricing link url', () => { - createComponent({ props: { canAddIntegration: false } }); + it('verify pricing link url', async () => { + await createComponent({ props: { canAddIntegration: false } }); + const link = findMultiSupportText().findComponent(GlLink); expect(link.attributes('href')).toMatch(/https:\/\/about.gitlab.(com|cn)\/pricing/); }); @@ -118,24 +142,19 @@ describe('AlertsSettingsForm', () => { expect(findTabs()).toHaveLength(3); }); - it('only first tab is enabled on integration create', () => { - createComponent({ - data: { - currentIntegration: null, - }, - }); + it('only first tab is enabled on integration create', async () => { + await createComponent(); + const tabs = findTabs(); expect(tabs.at(0).find('[role="tabpanel"]').classes('disabled')).toBe(false); expect(tabs.at(1).find('[role="tabpanel"]').classes('disabled')).toBe(true); expect(tabs.at(2).find('[role="tabpanel"]').classes('disabled')).toBe(true); }); - it('all tabs are enabled on integration edit', () => { - createComponent({ - data: { - currentIntegration: { id: 1 }, - }, - }); + it('all tabs are enabled on integration edit', async () => { + const currentIntegration = { id: 1 }; + await createComponent({ currentIntegration }); + const tabs = findTabs(); expect(tabs.at(0).find('[role="tabpanel"]').classes('disabled')).toBe(false); expect(tabs.at(1).find('[role="tabpanel"]').classes('disabled')).toBe(false); @@ -147,10 +166,7 @@ describe('AlertsSettingsForm', () => { describe('submitting integration form', () => { describe('HTTP', () => { it('create with custom mapping', async () => { - createComponent({ - multiIntegrations: true, - props: { alertFields }, - }); + await createComponent({ props: { alertFields } }); const integrationName = 'Test integration'; await selectOptionAtIndex(1); @@ -172,25 +188,23 @@ describe('AlertsSettingsForm', () => { }); }); - it('update', () => { - createComponent({ - data: { - integrationForm: { id: '1', name: 'Test integration pre', type: typeSet.http }, - currentIntegration: { id: '1' }, - }, - props: { - loading: false, - }, - }); + it('update', async () => { + const currentIntegration = { + id: '1', + name: 'Test integration pre', + type: typeSet.http, + }; + await createComponent({ currentIntegration }); const updatedIntegrationName = 'Test integration post'; enableIntegration(0, updatedIntegrationName); - const submitBtn = findSubmitButton(); - expect(submitBtn.exists()).toBe(true); - expect(submitBtn.text()).toBe('Save integration'); + expect(findSubmitButton().exists()).toBe(true); + expect(findSubmitButton().text()).toBe('Save integration'); + + await nextTick(); + await findSubmitButton().trigger('click'); - submitBtn.trigger('click'); expect(wrapper.emitted('update-integration')[0][0]).toMatchObject({ type: typeSet.http, variables: { @@ -205,13 +219,12 @@ describe('AlertsSettingsForm', () => { describe('PROMETHEUS', () => { it('create', async () => { - createComponent(); + await createComponent(); await selectOptionAtIndex(2); enableIntegration(0); - const submitBtn = findSubmitButton(); - expect(submitBtn.exists()).toBe(true); - expect(submitBtn.text()).toBe('Save integration'); + expect(findSubmitButton().exists()).toBe(true); + expect(findSubmitButton().text()).toBe('Save integration'); findForm().trigger('submit'); @@ -221,22 +234,17 @@ describe('AlertsSettingsForm', () => { }); }); - it('update', () => { - createComponent({ - data: { - integrationForm: { id: '1', type: typeSet.prometheus }, - currentIntegration: { id: '1' }, - }, - props: { - loading: false, - }, - }); + it('update', async () => { + const currentIntegration = { + id: '1', + type: typeSet.prometheus, + }; + await createComponent({ currentIntegration }); enableIntegration(0); - const submitBtn = findSubmitButton(); - expect(submitBtn.exists()).toBe(true); - expect(submitBtn.text()).toBe('Save integration'); + expect(findSubmitButton().exists()).toBe(true); + expect(findSubmitButton().text()).toBe('Save integration'); findForm().trigger('submit'); @@ -249,16 +257,9 @@ describe('AlertsSettingsForm', () => { }); describe('submitting the integration with a JSON test payload', () => { - beforeEach(() => { - createComponent({ - data: { - currentIntegration: { id: '1', name: 'Test' }, - active: true, - }, - props: { - loading: false, - }, - }); + beforeEach(async () => { + const currentIntegration = { id: '1', name: 'Test' }; + await createComponent({ currentIntegration }); }); it('should not allow a user to test invalid JSON', async () => { @@ -285,17 +286,18 @@ describe('AlertsSettingsForm', () => { describe('Test payload section for HTTP integration', () => { const validSamplePayload = JSON.stringify(alertFields); const emptySamplePayload = '{}'; - beforeEach(() => { - createComponent({ - multiIntegrations: true, - data: { - integrationForm: { type: typeSet.http }, - currentIntegration: { - payloadExample: emptySamplePayload, - }, - active: false, - resetPayloadAndMappingConfirmed: false, - }, + + beforeEach(async () => { + const currentIntegration = { + id: '1', + name: 'Test', + type: typeSet.http, + payloadExample: emptySamplePayload, + payloadAttributeMappings: [], + }; + + await createComponent({ + currentIntegration, props: { alertFields }, }); }); @@ -314,14 +316,25 @@ describe('AlertsSettingsForm', () => { const validPayloadMsg = payload === emptySamplePayload ? 'not valid' : 'valid'; it(`textarea should be ${enabledState} when payload reset ${payloadResetMsg} and payload is ${validPayloadMsg}`, async () => { - // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details - // eslint-disable-next-line no-restricted-syntax - wrapper.setData({ - currentIntegration: { payloadExample: payload }, - resetPayloadAndMappingConfirmed, + const currentIntegration = { + id: '1', + name: 'Test', + type: typeSet.http, + payloadExample: payload, + payloadAttributeMappings: [], + }; + + await createComponent({ + currentIntegration, + props: { alertFields }, }); + if (resetPayloadAndMappingConfirmed) { + findResetPayloadModal().vm.$emit('ok'); + } + await nextTick(); + expect( findSamplePayloadSection().findComponent(GlFormTextarea).attributes('disabled'), ).toBe(disabled); @@ -342,14 +355,21 @@ describe('AlertsSettingsForm', () => { : 'was not confirmed'; it(`shows ${caption} button when sample payload ${samplePayloadMsg} and payload reset ${payloadResetMsg}`, async () => { - // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details - // eslint-disable-next-line no-restricted-syntax - wrapper.setData({ - currentIntegration: { - payloadExample, - }, - resetPayloadAndMappingConfirmed, + const currentIntegration = { + type: typeSet.http, + payloadExample, + payloadAttributeMappings: [], + }; + + await createComponent({ + currentIntegration, + props: { alertFields }, }); + + if (resetPayloadAndMappingConfirmed) { + findResetPayloadModal().vm.$emit('ok'); + } + await nextTick(); expect(findActionBtn().text()).toBe(caption); }); @@ -357,14 +377,6 @@ describe('AlertsSettingsForm', () => { }); describe('Parsing payload', () => { - beforeEach(() => { - // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details - // eslint-disable-next-line no-restricted-syntax - wrapper.setData({ - resetPayloadAndMappingConfirmed: true, - }); - }); - it('displays a toast message on successful parse', async () => { jest.spyOn(wrapper.vm.$apollo, 'query').mockResolvedValue({ data: { @@ -408,7 +420,7 @@ describe('AlertsSettingsForm', () => { const multiIntegrationsEnabled = multiIntegrations ? 'enabled' : 'not enabled'; it(`is ${visibleMsg} when multiIntegrations are ${multiIntegrationsEnabled}, integration type is ${integrationType} and alert fields are ${alertFieldsMsg}`, async () => { - createComponent({ + await createComponent({ multiIntegrations, props: { alertFields: alertFieldsProvided ? alertFields : [], @@ -423,8 +435,8 @@ describe('AlertsSettingsForm', () => { }); describe('Form validation', () => { - beforeEach(() => { - createComponent(); + beforeEach(async () => { + await createComponent(); }); it('should not be able to submit when no integration type is selected', async () => { @@ -452,39 +464,29 @@ describe('AlertsSettingsForm', () => { }); it('should be able to submit when form is dirty', async () => { - // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details - // eslint-disable-next-line no-restricted-syntax - wrapper.setData({ - currentIntegration: { type: typeSet.http, name: 'Existing integration' }, - }); - await nextTick(); - await findFormFields().at(0).vm.$emit('input', 'Updated name'); + const currentIntegration = { type: typeSet.http, name: 'Existing integration' }; + await createComponent({ currentIntegration }); + await findFormFields().at(0).vm.$emit('input', 'Updated name'); expect(findSubmitButton().attributes('disabled')).toBe(undefined); }); it('should not be able to submit when form is pristine', async () => { - // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details - // eslint-disable-next-line no-restricted-syntax - wrapper.setData({ - currentIntegration: { type: typeSet.http, name: 'Existing integration' }, - }); - await nextTick(); - + const currentIntegration = { type: typeSet.http, name: 'Existing integration' }; + await createComponent({ currentIntegration }); expect(findSubmitButton().attributes('disabled')).toBeDefined(); }); it('should disable submit button after click on validation failure', async () => { await selectOptionAtIndex(1); - findSubmitButton().trigger('click'); - await nextTick(); + await findSubmitButton().trigger('click'); expect(findSubmitButton().attributes('disabled')).toBeDefined(); }); it('should scroll to invalid field on validation failure', async () => { await selectOptionAtIndex(1); - findSubmitButton().trigger('click'); + await findSubmitButton().trigger('click'); expect(scrollIntoViewMock).toHaveBeenCalledWith({ behavior: 'smooth', block: 'center' }); }); diff --git a/spec/graphql/resolvers/container_repository_tags_resolver_spec.rb b/spec/graphql/resolvers/container_repository_tags_resolver_spec.rb index 5f12e8649b7..4d0f1676c7f 100644 --- a/spec/graphql/resolvers/container_repository_tags_resolver_spec.rb +++ b/spec/graphql/resolvers/container_repository_tags_resolver_spec.rb @@ -83,15 +83,16 @@ RSpec.describe Resolvers::ContainerRepositoryTagsResolver, feature_category: :co context 'with parameters' do using RSpec::Parameterized::TableSyntax - where(:before, :after, :sort, :name, :first, :last, :sort_value) do - nil | nil | 'NAME_DESC' | '' | 10 | nil | '-name' - 'bb' | nil | 'NAME_ASC' | 'a' | nil | 5 | 'name' - nil | 'aa' | 'NAME_DESC' | 'a' | 10 | nil | '-name' + where(:before, :after, :sort, :name, :first, :last, :sort_value, :referrers) do + nil | nil | 'NAME_DESC' | '' | 10 | nil | '-name' | nil + 'bb' | nil | 'NAME_ASC' | 'a' | nil | 5 | 'name' | false + nil | 'aa' | 'NAME_DESC' | 'a' | 10 | nil | '-name' | true end with_them do let(:args) do - { before: before, after: after, sort: sort, name: name, first: first, last: last }.compact + { before: before, after: after, sort: sort, name: name, + first: first, last: last, referrers: referrers }.compact end it 'calls ContainerRepository#tags_page with correct parameters' do @@ -100,7 +101,8 @@ RSpec.describe Resolvers::ContainerRepositoryTagsResolver, feature_category: :co last: after, sort: sort_value, name: name, - page_size: [first, last].map(&:to_i).max + page_size: [first, last].map(&:to_i).max, + referrers: referrers ) resolver(args) diff --git a/spec/graphql/types/container_repository_referrer_type_spec.rb b/spec/graphql/types/container_repository_referrer_type_spec.rb new file mode 100644 index 00000000000..1baab8a7f89 --- /dev/null +++ b/spec/graphql/types/container_repository_referrer_type_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GitlabSchema.types['ContainerRepositoryReferrer'], feature_category: :container_registry do + fields = %i[artifact_type digest user_permissions] + + it { expect(described_class.graphql_name).to eq('ContainerRepositoryReferrer') } + + it { expect(described_class.description).to eq('A referrer for a container repository tag') } + + it { expect(described_class).to require_graphql_authorizations(:read_container_image) } + + it { expect(described_class).to have_graphql_fields(fields) } + + it { expect(described_class).to expose_permissions_using(Types::PermissionTypes::ContainerRepositoryTag) } +end diff --git a/spec/graphql/types/container_repository_tag_type_spec.rb b/spec/graphql/types/container_repository_tag_type_spec.rb index 596a221b5c0..28bfb2b46de 100644 --- a/spec/graphql/types/container_repository_tag_type_spec.rb +++ b/spec/graphql/types/container_repository_tag_type_spec.rb @@ -3,7 +3,8 @@ require 'spec_helper' RSpec.describe GitlabSchema.types['ContainerRepositoryTag'], feature_category: :container_registry do - fields = %i[name path location digest revision short_revision total_size created_at can_delete user_permissions] + fields = %i[name path location digest revision short_revision + total_size created_at can_delete user_permissions referrers] it { expect(described_class.graphql_name).to eq('ContainerRepositoryTag') } diff --git a/spec/helpers/listbox_helper_spec.rb b/spec/helpers/listbox_helper_spec.rb index bae9c40aa02..ff386ec1f3d 100644 --- a/spec/helpers/listbox_helper_spec.rb +++ b/spec/helpers/listbox_helper_spec.rb @@ -31,7 +31,6 @@ RSpec.describe ListboxHelper do dropdown b-dropdown gl-dropdown - btn-group js-redirect-listbox ]) end diff --git a/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb b/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb index a845e4fa7f4..bb6d4eeefbc 100644 --- a/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb +++ b/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb @@ -167,6 +167,21 @@ RSpec.describe Banzai::Pipeline::GfmPipeline, feature_category: :team_planning d end end + context 'when label reference is similar to a commit SHA' do + let(:numeric_commit_sha) { '8634272' } + let(:project) { create(:project, :repository) } + let(:label) { create(:label, project: project, id: numeric_commit_sha) } + + it 'renders a label reference' do + expect(project.commit_by(oid: numeric_commit_sha)).to be_present + + output = described_class.to_html(label.to_reference(format: :id), project: project) + + expect(output).to include(label.name) + expect(output).to include(Gitlab::Routing.url_helpers.project_issues_path(project, label_name: label.name)) + end + end + describe 'asset proxy' do let(:project) { create(:project, :public) } let(:image) { '![proxy](http://example.com/test.png)' } diff --git a/spec/lib/container_registry/gitlab_api_client_spec.rb b/spec/lib/container_registry/gitlab_api_client_spec.rb index 3c87af3a1c8..e13f639f048 100644 --- a/spec/lib/container_registry/gitlab_api_client_spec.rb +++ b/spec/lib/container_registry/gitlab_api_client_spec.rb @@ -256,6 +256,23 @@ RSpec.describe ContainerRegistry::GitlabApiClient, feature_category: :container_ it { is_expected.to eq(expected) } end + context 'with referrers included' do + subject { client.tags(path, page_size: page_size, referrers: true) } + + let(:expected) do + { + pagination: {}, + response_body: ::Gitlab::Json.parse(response.to_json) + } + end + + before do + stub_tags(path, page_size: page_size, input: { referrers: 'true' }, respond_with: response) + end + + it { is_expected.to eq(expected) } + end + context 'with a response with a link header containing next page' do let(:expected) do { @@ -961,7 +978,8 @@ RSpec.describe ContainerRegistry::GitlabApiClient, feature_category: :container_ last: input[:last], name: input[:name], sort: input[:sort], - before: input[:before] + before: input[:before], + referrers: input[:referrers] }.compact url = "#{registry_api_url}/gitlab/v1/repositories/#{path}/tags/list/" diff --git a/spec/lib/gitlab/git/tree_spec.rb b/spec/lib/gitlab/git/tree_spec.rb index 090f9af2620..468df96b356 100644 --- a/spec/lib/gitlab/git/tree_spec.rb +++ b/spec/lib/gitlab/git/tree_spec.rb @@ -9,7 +9,17 @@ RSpec.describe Gitlab::Git::Tree, feature_category: :source_code_management do let_it_be(:repository) { project.repository.raw } shared_examples 'repo' do - subject(:tree) { Gitlab::Git::Tree.where(repository, sha, path, recursive, skip_flat_paths, rescue_not_found, pagination_params) } + subject(:tree) do + Gitlab::Git::Tree.tree_entries( + repository: repository, + sha: sha, + path: path, + recursive: recursive, + skip_flat_paths: skip_flat_paths, + rescue_not_found: rescue_not_found, + pagination_params: pagination_params + ) + end let(:sha) { SeedRepo::Commit::ID } let(:path) { nil } diff --git a/spec/lib/gitlab/redis/sessions_spec.rb b/spec/lib/gitlab/redis/sessions_spec.rb index b02864cb73d..874822e3e6a 100644 --- a/spec/lib/gitlab/redis/sessions_spec.rb +++ b/spec/lib/gitlab/redis/sessions_spec.rb @@ -5,27 +5,6 @@ require 'spec_helper' RSpec.describe Gitlab::Redis::Sessions do it_behaves_like "redis_new_instance_shared_examples", 'sessions', Gitlab::Redis::SharedState - describe 'redis instance used in connection pool' do - around do |example| - clear_pool - example.run - ensure - clear_pool - end - - it 'uses ::Redis instance' do - described_class.pool.with do |redis_instance| - expect(redis_instance).to be_instance_of(::Redis) - end - end - - def clear_pool - described_class.remove_instance_variable(:@pool) - rescue NameError - # raised if @pool was not set; ignore - end - end - describe '#store' do subject(:store) { described_class.store(namespace: described_class::SESSION_NAMESPACE) } diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb index d16a78be533..1e70653c628 100644 --- a/spec/models/application_setting_spec.rb +++ b/spec/models/application_setting_spec.rb @@ -27,6 +27,7 @@ RSpec.describe ApplicationSetting, feature_category: :shared, type: :model do it { expect(setting.max_decompressed_archive_size).to eq(25600) } it { expect(setting.decompress_archive_file_timeout).to eq(210) } it { expect(setting.bulk_import_concurrent_pipeline_batch_limit).to eq(25) } + it { expect(setting.allow_project_creation_for_guest_and_below).to eq(true) } end describe 'validations' do diff --git a/spec/models/container_repository_spec.rb b/spec/models/container_repository_spec.rb index dc53c420704..25c28399abc 100644 --- a/spec/models/container_repository_spec.rb +++ b/spec/models/container_repository_spec.rb @@ -693,7 +693,7 @@ RSpec.describe ContainerRepository, :aggregate_failures, feature_category: :cont it 'calls GitlabApiClient#tags and passes parameters' do allow(repository.gitlab_api_client).to receive(:tags).and_return({}) expect(repository.gitlab_api_client).to receive(:tags).with( - repository.path, page_size: page_size, before: before, last: last, sort: sort, name: name) + repository.path, page_size: page_size, before: before, last: last, sort: sort, name: name, referrers: nil) subject end @@ -708,7 +708,13 @@ RSpec.describe ContainerRepository, :aggregate_failures, feature_category: :cont media_type: 'application/vnd.oci.image.manifest.v1+json', size_bytes: 1234567890, created_at: 5.minutes.ago, - updated_at: 5.minutes.ago + updated_at: 5.minutes.ago, + referrers: [ + { + artifactType: 'application/vnd.example+type', + digest: 'sha256:57d3be92c2f857566ecc7f9306a80021c0a7fa631e0ef5146957235aea859961' + } + ] }, { name: 'latest', @@ -755,6 +761,14 @@ RSpec.describe ContainerRepository, :aggregate_failures, feature_category: :cont created_at: DateTime.rfc3339(tags_response[index][:created_at].rfc3339), updated_at: DateTime.rfc3339(tags_response[index][:updated_at].rfc3339) ) + + Array(tag.referrers).each_with_index do |ref, ref_index| + expect(ref.is_a?(ContainerRegistry::Referrer)).to eq(true) + expect(ref).to have_attributes( + artifact_type: tags_response[index][:referrers][ref_index][:artifactType], + digest: tags_response[index][:referrers][ref_index][:digest] + ) + end end end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 77ceee3b1b0..68fdbeba84d 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -3669,6 +3669,66 @@ RSpec.describe User, feature_category: :user_profile do end end + describe '#can_create_project?' do + let(:user) { create(:user) } + + context "when projects_limit_left is 0" do + before do + allow(user).to receive(:projects_limit_left).and_return(0) + end + + it "returns false" do + expect(user.can_create_project?).to be_falsey + end + end + + context "when projects_limit_left is > 0" do + before do + allow(user).to receive(:projects_limit_left).and_return(1) + end + + context "with allow_project_creation_for_guest_and_below default value of true" do + it "returns true" do + expect(user.can_create_project?).to be_truthy + end + end + + context "when Gitlab::CurrentSettings.allow_project_creation_for_guest_and_below is false" do + before do + stub_application_setting(allow_project_creation_for_guest_and_below: false) + end + + [ + Gitlab::Access::NO_ACCESS, + Gitlab::Access::MINIMAL_ACCESS, + Gitlab::Access::GUEST + ].each do |role| + context "when users highest role is #{role}" do + it "returns false" do + allow(user).to receive(:highest_role).and_return(role) + expect(user.can_create_project?).to be_falsey + end + end + end + + [ + Gitlab::Access::REPORTER, + Gitlab::Access::DEVELOPER, + Gitlab::Access::MAINTAINER, + Gitlab::Access::OWNER, + Gitlab::Access::ADMIN + ].each do |role| + context "when users highest role is #{role}" do + it "returns true" do + allow(user).to receive(:highest_role).and_return(role) + expect(user.can_create_project?).to be_truthy + end + end + end + end + end + end + describe '#all_emails' do let(:user) { create(:user) } let!(:unconfirmed_secondary_email) { create(:email, user: user) } diff --git a/spec/policies/global_policy_spec.rb b/spec/policies/global_policy_spec.rb index 1d58b941d41..db8249252fa 100644 --- a/spec/policies/global_policy_spec.rb +++ b/spec/policies/global_policy_spec.rb @@ -90,6 +90,22 @@ RSpec.describe GlobalPolicy, feature_category: :shared do let(:current_user) { create(:user, can_create_group: true) } it { is_expected.to be_allowed(:create_group) } + + context 'when can_create_group_and_projects returns true' do + before do + allow(current_user).to receive(:allow_user_to_create_group_and_project?).and_return(true) + end + + it { is_expected.to be_allowed(:create_group) } + end + + context 'when can_create_group_and_projects returns false' do + before do + allow(current_user).to receive(:allow_user_to_create_group_and_project?).and_return(false) + end + + it { is_expected.to be_disallowed(:create_group) } + end end context 'when user does not have the ability to create group' do diff --git a/spec/requests/api/graphql/container_repository/container_repository_details_spec.rb b/spec/requests/api/graphql/container_repository/container_repository_details_spec.rb index 2acdd509355..46563aba992 100644 --- a/spec/requests/api/graphql/container_repository/container_repository_details_spec.rb +++ b/spec/requests/api/graphql/container_repository/container_repository_details_spec.rb @@ -430,6 +430,85 @@ RSpec.describe 'container repository details', feature_category: :container_regi it_behaves_like 'returning an invalid value error' end + + context 'with referrers' do + let(:tags_response) { container_repository_details_response.dig('tags', 'edges') } + let(:raw_tags_response) do + [ + { + name: 'latest', + digest: 'sha256:1234567892', + config_digest: 'sha256:3332132331', + media_type: 'application/vnd.oci.image.manifest.v1+json', + size_bytes: 1234509876, + created_at: 10.minutes.ago, + updated_at: 10.minutes.ago, + referrers: [ + { + artifactType: 'application/vnd.example+type', + digest: 'sha256:57d3be92c2f857566ecc7f9306a80021c0a7fa631e0ef5146957235aea859961' + }, + { + artifactType: 'application/vnd.example+type+2', + digest: 'sha256:01db72e42d61b8d2183d53475814cce2bfb9c8a254e97539a852441979cd5c90' + } + ] + }, + { + name: 'latest', + digest: 'sha256:1234567893', + config_digest: 'sha256:3332132331', + media_type: 'application/vnd.oci.image.manifest.v1+json', + size_bytes: 1234509877, + created_at: 9.minutes.ago, + updated_at: 9.minutes.ago + } + ] + end + + let(:query) do + <<~GQL + query($id: ContainerRepositoryID!, $n: String) { + containerRepository(id: $id) { + tags(name: $n, referrers: true) { + edges { + node { + #{all_graphql_fields_for('ContainerRepositoryTag')} + } + } + } + } + } + GQL + end + + let(:url) { URI('/gitlab/v1/repositories/group1/proj1/tags/list/?before=tag1&referrers=true') } + + let(:response_body) do + { + pagination: { previous: { uri: url }, next: { uri: url } }, + response_body: ::Gitlab::Json.parse(raw_tags_response.to_json) + } + end + + it 'includes referrers in response' do + subject + + refs = tags_response.map { |tag| tag.dig('node', 'referrers') } + + expect(refs.first.size).to eq(2) + expect(refs.first.first).to include({ + 'artifactType' => 'application/vnd.example+type', + 'digest' => 'sha256:57d3be92c2f857566ecc7f9306a80021c0a7fa631e0ef5146957235aea859961' + }) + expect(refs.first.second).to include({ + 'artifactType' => 'application/vnd.example+type+2', + 'digest' => 'sha256:01db72e42d61b8d2183d53475814cce2bfb9c8a254e97539a852441979cd5c90' + }) + + expect(refs.second).to be_empty + end + end end it_behaves_like 'handling graphql network errors with the container registry' diff --git a/spec/support/helpers/admin_mode_helpers.rb b/spec/support/helpers/admin_mode_helpers.rb index a6e31791127..8b71552f928 100644 --- a/spec/support/helpers/admin_mode_helpers.rb +++ b/spec/support/helpers/admin_mode_helpers.rb @@ -5,17 +5,30 @@ module AdminModeHelper # Administrators are logged in by default in user mode and have to switch to admin # mode for accessing any administrative functionality. This helper lets a user - # be in admin mode without requiring a second authentication step (provided - # the user is an admin) + # access the admin area in two different ways: + # + # * Fast (use_ui: false) and suitable form the most use cases: fakes calls and grants + # access to the admin area without requiring a second authentication step (provided the + # user is an admin) + # * Slow (use_ui: true): visits the admin UI and enters the users password. A second + # authentication step may be needed. # # See also tag :enable_admin_mode in spec/spec_helper.rb for a spec-wide # alternative - def enable_admin_mode!(user) - fake_user_mode = instance_double(Gitlab::Auth::CurrentUserMode) + def enable_admin_mode!(user, use_ui: false) + if use_ui + visit new_admin_session_path + fill_in 'user_password', with: user.password + click_button 'Enter admin mode' + + wait_for_requests + else + fake_user_mode = instance_double(Gitlab::Auth::CurrentUserMode) - allow(Gitlab::Auth::CurrentUserMode).to receive(:new).and_call_original + allow(Gitlab::Auth::CurrentUserMode).to receive(:new).and_call_original - allow(Gitlab::Auth::CurrentUserMode).to receive(:new).with(user).and_return(fake_user_mode) - allow(fake_user_mode).to receive(:admin_mode?).and_return(user&.admin?) + allow(Gitlab::Auth::CurrentUserMode).to receive(:new).with(user).and_return(fake_user_mode) + allow(fake_user_mode).to receive(:admin_mode?).and_return(user&.admin?) + end end end diff --git a/spec/support/helpers/login_helpers.rb b/spec/support/helpers/login_helpers.rb index 0cdddeaa84a..ff1c528d94a 100644 --- a/spec/support/helpers/login_helpers.rb +++ b/spec/support/helpers/login_helpers.rb @@ -49,18 +49,6 @@ module LoginHelpers @current_user = user end - def gitlab_enable_admin_mode_sign_in(user, use_mock_admin_mode: true) - if use_mock_admin_mode - enable_admin_mode!(user) - else - visit new_admin_session_path - fill_in 'user_password', with: user.password - click_button 'Enter admin mode' - - wait_for_requests - end - end - def gitlab_sign_in_via(provider, user, uid, saml_response = nil) mock_auth_hash_with_saml_xml(provider, uid, user.email, saml_response) visit new_user_session_path diff --git a/spec/support/shared_contexts/features/integrations/instance_integrations_shared_context.rb b/spec/support/shared_contexts/features/integrations/instance_integrations_shared_context.rb index c740917cec4..678199a35ea 100644 --- a/spec/support/shared_contexts/features/integrations/instance_integrations_shared_context.rb +++ b/spec/support/shared_contexts/features/integrations/instance_integrations_shared_context.rb @@ -7,7 +7,7 @@ RSpec.shared_context 'instance integration activation' do before do sign_in(user) - gitlab_enable_admin_mode_sign_in(user) + enable_admin_mode!(user) end def visit_instance_integrations diff --git a/spec/support/shared_examples/features/inviting_groups_shared_examples.rb b/spec/support/shared_examples/features/inviting_groups_shared_examples.rb index 4921676a065..d21e69b72e1 100644 --- a/spec/support/shared_examples/features/inviting_groups_shared_examples.rb +++ b/spec/support/shared_examples/features/inviting_groups_shared_examples.rb @@ -9,7 +9,7 @@ RSpec.shared_examples 'inviting groups search results' do before do sign_in(admin) - gitlab_enable_admin_mode_sign_in(admin) + enable_admin_mode!(admin) end it 'shows groups where the admin has no direct membership' do diff --git a/spec/support/shared_examples/redis/redis_new_instance_shared_examples.rb b/spec/support/shared_examples/redis/redis_new_instance_shared_examples.rb index 4a3732efe13..9b774449379 100644 --- a/spec/support/shared_examples/redis/redis_new_instance_shared_examples.rb +++ b/spec/support/shared_examples/redis/redis_new_instance_shared_examples.rb @@ -15,6 +15,37 @@ RSpec.shared_examples "redis_new_instance_shared_examples" do |name, fallback_cl it_behaves_like "redis_shared_examples" + describe '.pool' do + before do + allow(described_class).to receive(:config_file_name).and_call_original + allow(fallback_class).to receive(:params).and_return({}) + + clear_class_pool(described_class) + clear_class_pool(fallback_class) + end + + after do + clear_class_pool(described_class) + clear_class_pool(fallback_class) + end + + context 'when not using fallback config' do + it 'creates its own connection pool' do + expect(fallback_class.pool == described_class.pool).to eq(false) + end + end + + context 'when using fallback config' do + before do + allow(described_class).to receive(:params).and_return({}) + end + + it 'uses the fallback class connection pool' do + expect(fallback_class.pool == described_class.pool).to eq(true) + end + end + end + describe '#fetch_config' do subject { described_class.new('test').send(:fetch_config) } @@ -81,4 +112,10 @@ RSpec.shared_examples "redis_new_instance_shared_examples" do |name, fallback_cl end end end + + def clear_class_pool(klass) + klass.remove_instance_variable(:@pool) + rescue NameError + # raised if @pool was not set; ignore + end end diff --git a/spec/support/shared_examples/redis/redis_shared_examples.rb b/spec/support/shared_examples/redis/redis_shared_examples.rb index 1e30df2af09..4929a753829 100644 --- a/spec/support/shared_examples/redis/redis_shared_examples.rb +++ b/spec/support/shared_examples/redis/redis_shared_examples.rb @@ -217,6 +217,10 @@ RSpec.shared_examples "redis_shared_examples" do clear_pool end + it 'yields a ::Redis' do + described_class.with { |conn| expect(conn).to be_instance_of(::Redis) } + end + context 'when running on single-threaded runtime' do before do allow(Gitlab::Runtime).to receive(:multi_threaded?).and_return(false) diff --git a/workhorse/go.mod b/workhorse/go.mod index 02eacb15535..14456a5c687 100644 --- a/workhorse/go.mod +++ b/workhorse/go.mod @@ -17,7 +17,7 @@ require ( github.com/jpillora/backoff v1.0.0 github.com/mitchellh/copystructure v1.2.0 github.com/prometheus/client_golang v1.17.0 - github.com/redis/go-redis/v9 v9.3.0 + github.com/redis/go-redis/v9 v9.3.1 github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a github.com/sirupsen/logrus v1.9.3 github.com/smartystreets/goconvey v1.8.1 diff --git a/workhorse/go.sum b/workhorse/go.sum index 0bdecb91f43..32d2d9edb45 100644 --- a/workhorse/go.sum +++ b/workhorse/go.sum @@ -379,8 +379,8 @@ github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwa github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= github.com/prometheus/prometheus v0.48.0 h1:yrBloImGQ7je4h8M10ujGh4R6oxYQJQKlMuETwNskGk= github.com/prometheus/prometheus v0.48.0/go.mod h1:SRw624aMAxTfryAcP8rOjg4S/sHHaetx2lyJJ2nM83g= -github.com/redis/go-redis/v9 v9.3.0 h1:RiVDjmig62jIWp7Kk4XVLs0hzV6pI3PyTnnL0cnn0u0= -github.com/redis/go-redis/v9 v9.3.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= +github.com/redis/go-redis/v9 v9.3.1 h1:KqdY8U+3X6z+iACvumCNxnoluToB+9Me+TvyFa21Mds= +github.com/redis/go-redis/v9 v9.3.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= |