diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-11-08 21:11:09 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-11-08 21:11:09 +0300 |
commit | da576e4a0b8e1adc3df559a163b01c962a565ef5 (patch) | |
tree | f563a8746fd54a2d638f6b421955220af24c8489 | |
parent | b5bdf6e5219b3b57107aee49ba7c103affb65dd9 (diff) |
Add latest changes from gitlab-org/gitlab@master
65 files changed, 500 insertions, 157 deletions
diff --git a/.rubocop.yml b/.rubocop.yml index 51877a85a99..2c4f6da99ed 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -728,6 +728,12 @@ Migration/PreventIndexCreation: - !ruby/regexp /\Adb\/(post_)?migrate\/2020.*\.rb\z/ - !ruby/regexp /\Adb\/(post_)?migrate\/20210[1-6].*\.rb\z/ +Migration/SchemaAdditionMethodsNoPost: + Enabled: true + Include: + - db/post_migrate/*.rb + EnforcedSince: 20221024034228 + Gitlab/RailsLogger: Exclude: - 'spec/**/*.rb' @@ -217,10 +217,10 @@ gem 'state_machines-activerecord', '~> 0.8.0' gem 'acts-as-taggable-on', '~> 9.0' # Background jobs -gem 'sidekiq', '~> 6.4.0' +gem 'sidekiq', '~> 6.5.7' gem 'sidekiq-cron', '~> 1.8.0' gem 'redis-namespace', '~> 1.9.0' -gem 'gitlab-sidekiq-fetcher', '0.8.0', require: 'sidekiq-reliable-fetch' +gem 'gitlab-sidekiq-fetcher', '0.9.0', require: 'sidekiq-reliable-fetch' # Cron Parser gem 'fugit', '~> 1.2.1' diff --git a/Gemfile.checksum b/Gemfile.checksum index 053304f111b..6497d75cdea 100644 --- a/Gemfile.checksum +++ b/Gemfile.checksum @@ -210,7 +210,7 @@ {"name":"gitlab-markup","version":"1.8.1","platform":"ruby","checksum":"ab1f9fd016977497c2af25b76341dea670533014f406861834a0bd99f646707b"}, {"name":"gitlab-net-dns","version":"0.9.1","platform":"ruby","checksum":"bcd1a08dcb31b731e8ff602d828de619d2d9f53f5812f6abacf11c720873d4cb"}, {"name":"gitlab-omniauth-openid-connect","version":"0.10.0","platform":"ruby","checksum":"ea44a23ea93457057bba6a9912e883f5aefab36a941c6c58512c8a7095fb1153"}, -{"name":"gitlab-sidekiq-fetcher","version":"0.8.0","platform":"ruby","checksum":"9c564caa2a958d44a8d78672dc23b2a206102d0223b41b77b58626a945e37362"}, +{"name":"gitlab-sidekiq-fetcher","version":"0.9.0","platform":"ruby","checksum":"54041aec059f20c8e6dfce394e1b60e0c0a9c7cef32da912a58abbd333e13897"}, {"name":"gitlab-styles","version":"9.0.0","platform":"ruby","checksum":"ef0edfab8f807a5be2309ba24dfc44fec5ba52ed68b87167c051e9ffdadb3bad"}, {"name":"gitlab_chronic_duration","version":"0.10.6.2","platform":"ruby","checksum":"6dda4cfe7dca9b958f163ac8835c3d9cc70cf8df8cbb89bb2fbf9ba4375105fb"}, {"name":"gitlab_omniauth-ldap","version":"2.2.0","platform":"ruby","checksum":"bb4d20acb3b123ed654a8f6a47d3fac673ece7ed0b6992edb92dca14bad2838c"}, @@ -533,7 +533,7 @@ {"name":"sexp_processor","version":"4.15.1","platform":"ruby","checksum":"9291a0f2247f50d15068ee6965b67cd7b678b0d273e18adf3c0b2ea4a890125c"}, {"name":"shellany","version":"0.0.1","platform":"ruby","checksum":"0e127a9132698766d7e752e82cdac8250b6adbd09e6c0a7fbbb6f61964fedee7"}, {"name":"shoulda-matchers","version":"5.1.0","platform":"ruby","checksum":"a01d20589989e9653ab4a28c67d9db2b82bcf0a2496cf01d5e1a95a4aaaf5b07"}, -{"name":"sidekiq","version":"6.4.2","platform":"ruby","checksum":"0d3c05fecb5fbace5ff5efc63da707e02a9c4673fb8e33ceca10b5ec0e9f062c"}, +{"name":"sidekiq","version":"6.5.7","platform":"ruby","checksum":"7d966fd84d42a942615d6874be31e40f8bece841fdd9b96fc53cad22a590555c"}, {"name":"sidekiq-cron","version":"1.8.0","platform":"ruby","checksum":"47da72ca73ce5b71896aaf7e7c4391386ec517dd003f184c50c0b727d82eb0ca"}, {"name":"sigdump","version":"0.2.4","platform":"ruby","checksum":"0bf2176e55c1a262788623fe5ea57caddd6ba2abebe5e349d9d5e7c3a3010ed7"}, {"name":"signet","version":"0.17.0","platform":"ruby","checksum":"1d2831930dc28da32e34bec68cf7ded97ee2867b208f97c500ee293829cb0004"}, diff --git a/Gemfile.lock b/Gemfile.lock index e2dcac3a6db..557c366cbb3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -584,7 +584,8 @@ GEM addressable (~> 2.7) omniauth (>= 1.9, < 3) openid_connect (~> 1.2) - gitlab-sidekiq-fetcher (0.8.0) + gitlab-sidekiq-fetcher (0.9.0) + json (>= 2.5) sidekiq (~> 6.1) gitlab-styles (9.0.0) rubocop (~> 1.36.0) @@ -1314,10 +1315,10 @@ GEM shellany (0.0.1) shoulda-matchers (5.1.0) activesupport (>= 5.2.0) - sidekiq (6.4.2) - connection_pool (>= 2.2.2) + sidekiq (6.5.7) + connection_pool (>= 2.2.5) rack (~> 2.0) - redis (>= 4.2.0) + redis (>= 4.5.0, < 5) sidekiq-cron (1.8.0) fugit (~> 1) sidekiq (>= 4.2.1) @@ -1635,7 +1636,7 @@ DEPENDENCIES gitlab-markup (~> 1.8.0) gitlab-net-dns (~> 0.9.1) gitlab-omniauth-openid-connect (~> 0.10.0) - gitlab-sidekiq-fetcher (= 0.8.0) + gitlab-sidekiq-fetcher (= 0.9.0) gitlab-styles (~> 9.0.0) gitlab_chronic_duration (~> 0.10.6.2) gitlab_omniauth-ldap (~> 2.2.0) @@ -1787,7 +1788,7 @@ DEPENDENCIES sentry-sidekiq (~> 5.1.1) settingslogic (~> 2.0.9) shoulda-matchers (~> 5.1.0) - sidekiq (~> 6.4.0) + sidekiq (~> 6.5.7) sidekiq-cron (~> 1.8.0) sigdump (~> 0.2.4) simple_po_parser (~> 1.1.6) diff --git a/app/assets/javascripts/search/sidebar/components/app.vue b/app/assets/javascripts/search/sidebar/components/app.vue index 927ae6f6b81..6f29864c0a2 100644 --- a/app/assets/javascripts/search/sidebar/components/app.vue +++ b/app/assets/javascripts/search/sidebar/components/app.vue @@ -1,6 +1,7 @@ <script> import { mapState } from 'vuex'; import ScopeNavigation from '~/search/sidebar/components/scope_navigation.vue'; +import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { SCOPE_ISSUES, SCOPE_MERGE_REQUESTS } from '../constants'; import ResultsFilters from './results_filters.vue'; @@ -10,6 +11,7 @@ export default { ResultsFilters, ScopeNavigation, }, + mixins: [glFeatureFlagsMixin()], computed: { ...mapState(['urlQuery']), showFilters() { @@ -21,7 +23,7 @@ export default { <template> <section class="search-sidebar gl-display-flex gl-flex-direction-column gl-mr-4 gl-mb-6 gl-mt-5"> - <scope-navigation /> + <scope-navigation v-if="glFeatures.searchPageVerticalNav" /> <results-filters v-if="showFilters" /> </section> </template> diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb index cfe59edd439..07ca17bca79 100644 --- a/app/graphql/types/project_type.rb +++ b/app/graphql/types/project_type.rb @@ -226,7 +226,6 @@ module Types Types::IssueType.connection_type, null: true, description: 'Issues of the project.', - extras: [:lookahead], resolver: Resolvers::ProjectIssuesResolver field :work_items, diff --git a/app/models/deployment.rb b/app/models/deployment.rb index 20841bc14cd..7116827f153 100644 --- a/app/models/deployment.rb +++ b/app/models/deployment.rb @@ -439,8 +439,9 @@ class Deployment < ApplicationRecord end # default tag limit is 100, 0 means no limit + # when refs_by_oid is passed an SHA, returns refs for that commit def tags(limit: 100) - project.repository.tag_names_contains(sha, limit: limit) + project.repository.refs_by_oid(oid: sha, limit: limit, ref_patterns: [Gitlab::Git::TAG_REF_PREFIX]) || [] end strong_memoize_attr :tags diff --git a/app/models/pages_domain.rb b/app/models/pages_domain.rb index 8b15db7badc..328c67a0711 100644 --- a/app/models/pages_domain.rb +++ b/app/models/pages_domain.rb @@ -10,8 +10,8 @@ class PagesDomain < ApplicationRecord SSL_RENEWAL_THRESHOLD = 30.days.freeze enum certificate_source: { user_provided: 0, gitlab_provided: 1 }, _prefix: :certificate - enum scope: { instance: 0, group: 1, project: 2 }, _prefix: :scope - enum usage: { pages: 0, serverless: 1 }, _prefix: :usage + enum scope: { instance: 0, group: 1, project: 2 }, _prefix: :scope, _default: :project + enum usage: { pages: 0, serverless: 1 }, _prefix: :usage, _default: :pages belongs_to :project has_many :acme_orders, class_name: "PagesDomainAcmeOrder" @@ -35,10 +35,8 @@ class PagesDomain < ApplicationRecord validate :validate_intermediates, if: ->(domain) { domain.certificate.present? && domain.certificate_changed? } validate :validate_custom_domain_count_per_project, on: :create - default_value_for(:auto_ssl_enabled, allows_nil: false) { ::Gitlab::LetsEncrypt.enabled? } - default_value_for :scope, allows_nil: false, value: :project - default_value_for :wildcard, allows_nil: false, value: false - default_value_for :usage, allows_nil: false, value: :pages + attribute :auto_ssl_enabled, default: -> { ::Gitlab::LetsEncrypt.enabled? } + attribute :wildcard, default: false attr_encrypted :key, mode: :per_attribute_iv_and_salt, diff --git a/app/models/project_setting.rb b/app/models/project_setting.rb index 4c3be49fddd..69b76b7efa9 100644 --- a/app/models/project_setting.rb +++ b/app/models/project_setting.rb @@ -26,7 +26,7 @@ class ProjectSetting < ApplicationRecord validate :validates_mr_default_target_self - default_value_for(:legacy_open_source_license_available) do + attribute :legacy_open_source_license_available, default: -> do Feature.enabled?(:legacy_open_source_license_available, type: :ops) end diff --git a/app/models/serverless/domain_cluster.rb b/app/models/serverless/domain_cluster.rb index 1effabf1c22..561bfc65b2b 100644 --- a/app/models/serverless/domain_cluster.rb +++ b/app/models/serverless/domain_cluster.rb @@ -19,7 +19,7 @@ module Serverless validates :uuid, presence: true, uniqueness: true, length: { is: ::Serverless::Domain::UUID_LENGTH }, format: { with: HEX_REGEXP, message: 'only allows hex characters' } - default_value_for(:uuid, allows_nil: false) { ::Serverless::Domain.generate_uuid } + after_initialize :set_uuid, if: :new_record? delegate :domain, to: :pages_domain delegate :cluster, to: :knative @@ -29,5 +29,11 @@ module Serverless .includes(:pages_domain, :knative) .find_by(uuid: uuid) end + + private + + def set_uuid + self.uuid = ::Serverless::Domain.generate_uuid + end end end diff --git a/app/presenters/deployments/deployment_presenter.rb b/app/presenters/deployments/deployment_presenter.rb index 5ef6fcff974..478c7a85f90 100644 --- a/app/presenters/deployments/deployment_presenter.rb +++ b/app/presenters/deployments/deployment_presenter.rb @@ -5,11 +5,14 @@ module Deployments presents ::Deployment, as: :deployment delegator_override :tags + + # Note: this returns the path key as 'tags/tag_name' but it is used as a URL in the UI + def tags super.map do |tag| { - name: tag, - path: "tags/#{tag}" + name: tag.delete_prefix(Gitlab::Git::TAG_REF_PREFIX), + path: tag.delete_prefix('refs/') } end end diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index d1b734fb4bc..8c991c71313 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -35,19 +35,19 @@ enable_json_logs = Gitlab.config.sidekiq.log_format == 'json' enable_sidekiq_memory_killer = ENV['SIDEKIQ_MEMORY_KILLER_MAX_RSS'].to_i.nonzero? Sidekiq.configure_server do |config| - config.options[:strict] = false - config.options[:queues] = Gitlab::SidekiqConfig.expand_queues(config.options[:queues]) + config[:strict] = false + config[:queues] = Gitlab::SidekiqConfig.expand_queues(config[:queues]) if enable_json_logs config.log_formatter = Gitlab::SidekiqLogging::JSONFormatter.new - config.options[:job_logger] = Gitlab::SidekiqLogging::StructuredLogger + config[:job_logger] = Gitlab::SidekiqLogging::StructuredLogger # Remove the default-provided handler. The exception is logged inside # Gitlab::SidekiqLogging::StructuredLogger - config.error_handlers.reject! { |handler| handler.is_a?(Sidekiq::ExceptionHandler::Logger) } + config.error_handlers.delete(Sidekiq::DEFAULT_ERROR_HANDLER) end - Sidekiq.logger.info "Listening on queues #{config.options[:queues].uniq.sort}" + Sidekiq.logger.info "Listening on queues #{config[:queues].uniq.sort}" config.redis = queues_config_hash @@ -84,13 +84,13 @@ Sidekiq.configure_server do |config| end if enable_reliable_fetch? - config.options[:semi_reliable_fetch] = enable_semi_reliable_fetch_mode? + config[:semi_reliable_fetch] = enable_semi_reliable_fetch_mode? Sidekiq::ReliableFetch.setup_reliable_fetch!(config) end Gitlab::SidekiqVersioning.install! - config.options[:cron_poll_interval] = Gitlab.config.cron_jobs.poll_interval + config[:cron_poll_interval] = Gitlab.config.cron_jobs.poll_interval load_cron_jobs! # Avoid autoload issue such as 'Mail::Parsers::AddressStruct' diff --git a/config/initializers/sidekiq_cluster.rb b/config/initializers/sidekiq_cluster.rb index 6fd598b3e25..5851e3bd838 100644 --- a/config/initializers/sidekiq_cluster.rb +++ b/config/initializers/sidekiq_cluster.rb @@ -19,7 +19,7 @@ if ENV['ENABLE_SIDEKIQ_CLUSTER'] # Allow sidekiq to cleanly terminate and push any running jobs back # into the queue. We use the configured timeout and add a small # grace period - sleep(Sidekiq.options[:timeout] + 5) + sleep(Sidekiq[:timeout] + 5) # Signaling the Sidekiq Pgroup as KILL is not forwarded to # a possible child process. In Sidekiq Cluster, all child Sidekiq diff --git a/danger/architecture/Dangerfile b/danger/architecture/Dangerfile new file mode 100644 index 00000000000..148180247fe --- /dev/null +++ b/danger/architecture/Dangerfile @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +BLUEPRINT_LABEL = 'Architecture Evolution Blueprint' + +return unless helper.ci? + +blueprint_changes = helper.changed_files(%r{^doc/architecture/blueprints/.*}) + +BLUEPRINT_SHORT_MESSAGE = <<~MSG +This merge request requires a review from an [Architecture Evolution Coach](https://about.gitlab.com/handbook/engineering/architecture/workflow/). +MSG + +BLUEPRINT_LONG_MESSAGE = <<~MSG +## Architecture Evolution Review + +#{BLUEPRINT_SHORT_MESSAGE} + +Following files, that may require the additional review, have been changed: +#{helper.markdown_list(blueprint_changes.to_set)} +MSG + +if blueprint_changes.any? + message(BLUEPRINT_SHORT_MESSAGE) + markdown(BLUEPRINT_LONG_MESSAGE) + + helper.labels_to_add.push(BLUEPRINT_LABEL) unless helper.mr_has_labels?(BLUEPRINT_LABEL) +end diff --git a/doc/administration/geo/disaster_recovery/index.md b/doc/administration/geo/disaster_recovery/index.md index 156a87614e6..dfa8d09e6ef 100644 --- a/doc/administration/geo/disaster_recovery/index.md +++ b/doc/administration/geo/disaster_recovery/index.md @@ -758,7 +758,7 @@ If you are running GitLab 14.4 and earlier: To promote the **secondary** cluster to a **primary** cluster, update `role: secondary` to `role: primary`. - If the cluster remains as a primary site, you can remove the entire `psql` section; it refers to the tracking database and is ignored whilst the cluster is acting as a primary site. + If the cluster remains as a primary site, you can remove the entire `psql` section; it refers to the tracking database and is ignored while the cluster is acting as a primary site. Update the cluster with the new configuration: diff --git a/doc/administration/instance_limits.md b/doc/administration/instance_limits.md index 3f44b53a6d5..b2514cbb8ba 100644 --- a/doc/administration/instance_limits.md +++ b/doc/administration/instance_limits.md @@ -212,12 +212,20 @@ It's possible that this limit changes to a lower number in the future. ## Size of commit titles and descriptions -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/292039) in GitLab 13.9 +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/292039) in GitLab 13.9. -Commits with arbitrarily large messages may be pushed to GitLab, but when -displaying commits, titles (the first line of the commit message) -limits to 1KiB, and descriptions (the rest of the message) limits to -1MiB. +Commits with arbitrarily large messages may be pushed to GitLab, but the following +display limits apply: + +- **Title** - The first line of the commit message. Limited to 1 KiB. +- **Description** - The rest of the commit message. Limited to 1 MiB. + +When a commit is pushed, GitLab processes the title and description to replace +references to issues (`#123`) and merge requests (`!123`) with links to the +issues and merge requests. + +When a branch with a large number of commits is pushed, only the last 100 commits +are processed. ## Number of issues in the milestone overview diff --git a/doc/administration/sidekiq/sidekiq_memory_killer.md b/doc/administration/sidekiq/sidekiq_memory_killer.md index bbf95bc45ce..0876f98621d 100644 --- a/doc/administration/sidekiq/sidekiq_memory_killer.md +++ b/doc/administration/sidekiq/sidekiq_memory_killer.md @@ -64,5 +64,5 @@ The MemoryKiller is controlled using environment variables. If the process hard shutdown/restart is not performed by Sidekiq, the Sidekiq process is forcefully terminated after - `Sidekiq.options[:timeout] + 2` seconds. An external supervision mechanism + `Sidekiq[:timeout] + 2` seconds. An external supervision mechanism (for example, runit) must restart Sidekiq afterwards. diff --git a/doc/administration/troubleshooting/postgresql.md b/doc/administration/troubleshooting/postgresql.md index e392bdffe30..829fed38060 100644 --- a/doc/administration/troubleshooting/postgresql.md +++ b/doc/administration/troubleshooting/postgresql.md @@ -58,59 +58,6 @@ This section is for links to information elsewhere in the GitLab documentation. some of which is absolutely not for production use. Including: - Understanding EXPLAIN plans. -### Troubleshooting/Fixes - -- [GitLab database requirements](../../install/requirements.md#database), - including - - Support for MySQL was removed in GitLab 12.1; [migrate to PostgreSQL](../../update/mysql_to_postgresql.md). - - Required extension: `pg_trgm` - - Required extension: `btree_gist` - -- Errors like this in the `production/sidekiq` log; see: - [Set `default_transaction_isolation` into read committed](https://docs.gitlab.com/omnibus/settings/database.html#set-default_transaction_isolation-into-read-committed): - - ```plaintext - ActiveRecord::StatementInvalid PG::TRSerializationFailure: ERROR: could not serialize access due to concurrent update - ``` - -- PostgreSQL HA [replication slot errors](https://docs.gitlab.com/omnibus/settings/database.html#troubleshooting-upgrades-in-an-ha-cluster): - - ```plaintext - pg_basebackup: could not create temporary replication slot "pg_basebackup_12345": ERROR: all replication slots are in use - HINT: Free one or increase max_replication_slots. - ``` - -- Geo [replication errors](../geo/replication/troubleshooting.md#fixing-postgresql-database-replication-errors) including: - - ```plaintext - ERROR: replication slots can only be used if max_replication_slots > 0 - - FATAL: could not start WAL streaming: ERROR: replication slot "geo_secondary_my_domain_com" does not exist - - Command exceeded allowed execution time - - PANIC: could not write to file 'pg_xlog/xlogtemp.123': No space left on device - ``` - -- [Checking Geo configuration](../geo/replication/troubleshooting.md), including: - - Reconfiguring hosts/ports. - - Checking and fixing user/password mappings. - -- [Common Geo errors](../geo/replication/troubleshooting.md#fixing-common-errors). - -- Mismatch in `pg_dump` and `psql` versions: - - ```plaintext - Dumping PostgreSQL database gitlabhq_production ... pg_dump: error: server version: 13.3; pg_dump version: 14.2 - pg_dump: error: aborting because of server version mismatch - ``` - - To fix this, see [Backup and restore a non-packaged PostgreSQL database](https://docs.gitlab.com/omnibus/settings/database.html#backup-and-restore-a-non-packaged-postgresql-database). - -- Deploying PostgreSQL on Azure Database for PostgreSQL - Flexible Server may result in an error stating `extension "btree_gist" is not allow-listed for "azure_pg_admin" users in Azure Database for PostgreSQL` - - To resolve the above error, [allow-list the extension](https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/concepts-extensions#how-to-use-postgresql-extensions) prior to install. - ## Support topics ### Database deadlocks @@ -259,3 +206,73 @@ To resolve the error, run `VACUUM` manually: 1. In the `backend>` prompt, run `VACUUM;`. This command can take several minutes to complete. 1. Wait for the command to complete, then press <kbd>Control</kbd> + <kbd>D</kbd> to exit. 1. Start GitLab with the command `gitlab-ctl start`. + +### GitLab database requirements + +The [database requirements](../../install/requirements.md#database) for GitLab include: + +- Support for MySQL was removed in GitLab 12.1; [migrate to PostgreSQL](../../update/mysql_to_postgresql.md). +- Review and install the [required extension list](../../install/postgresql_extensions.md). + +### Serialization errors in the `production/sidekiq` log + +If you receive errors like this example in your `production/sidekiq` log, read +about [setting `default_transaction_isolation` into read committed](https://docs.gitlab.com/omnibus/settings/database.html#set-default_transaction_isolation-into-read-committed) to fix the problem: + +```plaintext +ActiveRecord::StatementInvalid PG::TRSerializationFailure: ERROR: could not serialize access due to concurrent update +``` + +### PostgreSQL replication slot errors + +If you receive errors like this example, read about how to resolve PostgreSQL HA +[replication slot errors](https://docs.gitlab.com/omnibus/settings/database.html#troubleshooting-upgrades-in-an-ha-cluster): + +```plaintext +pg_basebackup: could not create temporary replication slot "pg_basebackup_12345": ERROR: all replication slots are in use +HINT: Free one or increase max_replication_slots. +``` + +### Geo replication errors + +If you receive errors like this example, read about how to resolve +[Geo replication errors](../geo/replication/troubleshooting.md#fixing-postgresql-database-replication-errors): + +```plaintext +ERROR: replication slots can only be used if max_replication_slots > 0 + +FATAL: could not start WAL streaming: ERROR: replication slot "geo_secondary_my_domain_com" does not exist + +Command exceeded allowed execution time + +PANIC: could not write to file 'pg_xlog/xlogtemp.123': No space left on device +``` + +### Review Geo configuration and common errors + +When troubleshooting problems with Geo, you should: + +- Review [common Geo errors](../geo/replication/troubleshooting.md#fixing-common-errors). +- [Review your Geo configuration](../geo/replication/troubleshooting.md), including: + - Reconfiguring hosts and ports. + - Reviewing and fixing the user and password mappings. + +### Mismatch in `pg_dump` and `psql` versions + +If you receive errors like this example, read about how to +[back up and restore a non-packaged PostgreSQL database](https://docs.gitlab.com/omnibus/settings/database.html#backup-and-restore-a-non-packaged-postgresql-database): + +```plaintext +Dumping PostgreSQL database gitlabhq_production ... pg_dump: error: server version: 13.3; pg_dump version: 14.2 +pg_dump: error: aborting because of server version mismatch +``` + +### Extension `btree_gist` is not allow-listed + +Deploying PostgreSQL on an Azure Database for PostgreSQL - Flexible Server may result in this error: + +```plaintext +extension "btree_gist" is not allow-listed for "azure_pg_admin" users in Azure Database for PostgreSQL +``` + +To resolve this error, [allow-list the extension](https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/concepts-extensions#how-to-use-postgresql-extensions) prior to install. diff --git a/doc/api/group_level_variables.md b/doc/api/group_level_variables.md index cdda15d9610..6ca4cc1d080 100644 --- a/doc/api/group_level_variables.md +++ b/doc/api/group_level_variables.md @@ -32,6 +32,7 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a "value": "TEST_1", "protected": false, "masked": false, + "raw": false, "environment_scope": "*" }, { @@ -40,6 +41,7 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a "value": "TEST_2", "protected": false, "masked": false, + "raw": false, "environment_scope": "*" } ] @@ -69,6 +71,7 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a "value": "TEST_1", "protected": false, "masked": false, + "raw": false, "environment_scope": "*" } ``` @@ -89,6 +92,7 @@ POST /groups/:id/variables | `variable_type` | string | no | The type of a variable. Available types are: `env_var` (default) and `file` | | `protected` | boolean | no | Whether the variable is protected | | `masked` | boolean | no | Whether the variable is masked | +| `raw` | boolean | no | Whether the variable is expandable | | `environment_scope` **(PREMIUM)** | string | no | The [environment scope](../ci/variables/index.md#limit-the-environment-scope-of-a-cicd-variable) of a variable | ```shell @@ -103,6 +107,7 @@ curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \ "variable_type": "env_var", "protected": false, "masked": false, + "raw": false, "environment_scope": "*" } ``` @@ -123,6 +128,7 @@ PUT /groups/:id/variables/:key | `variable_type` | string | no | The type of a variable. Available types are: `env_var` (default) and `file` | | `protected` | boolean | no | Whether the variable is protected | | `masked` | boolean | no | Whether the variable is masked | +| `raw` | boolean | no | Whether the variable is expandable | | `environment_scope` **(PREMIUM)** | string | no | The [environment scope](../ci/variables/index.md#limit-the-environment-scope-of-a-cicd-variable) of a variable | ```shell @@ -137,6 +143,7 @@ curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" \ "variable_type": "env_var", "protected": true, "masked": true, + "raw": true, "environment_scope": "*" } ``` diff --git a/doc/api/instance_level_ci_variables.md b/doc/api/instance_level_ci_variables.md index 776b1000651..e71cf777b2c 100644 --- a/doc/api/instance_level_ci_variables.md +++ b/doc/api/instance_level_ci_variables.md @@ -28,14 +28,16 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a "variable_type": "env_var", "value": "TEST_1", "protected": false, - "masked": false + "masked": false, + "raw": false }, { "key": "TEST_VARIABLE_2", "variable_type": "env_var", "value": "TEST_2", "protected": false, - "masked": false + "masked": false, + "raw": false } ] ``` @@ -62,7 +64,8 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a "variable_type": "env_var", "value": "TEST_1", "protected": false, - "masked": false + "masked": false, + "raw": false } ``` @@ -83,6 +86,7 @@ POST /admin/ci/variables | `variable_type` | string | no | The type of a variable. Available types are: `env_var` (default) and `file`. | | `protected` | boolean | no | Whether the variable is protected. | | `masked` | boolean | no | Whether the variable is masked. | +| `raw` | boolean | no | Whether the variable is expandable. | ```shell curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \ @@ -95,7 +99,8 @@ curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \ "value": "new value", "variable_type": "env_var", "protected": false, - "masked": false + "masked": false, + "raw": false } ``` @@ -114,6 +119,7 @@ PUT /admin/ci/variables/:key | `variable_type` | string | no | The type of a variable. Available types are: `env_var` (default) and `file`. | | `protected` | boolean | no | Whether the variable is protected. | | `masked` | boolean | no | Whether the variable is masked. | +| `raw` | boolean | no | Whether the variable is expandable. | ```shell curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" \ @@ -126,7 +132,8 @@ curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" \ "value": "updated value", "variable_type": "env_var", "protected": true, - "masked": true + "masked": true, + "raw": true } ``` diff --git a/doc/api/project_level_variables.md b/doc/api/project_level_variables.md index d900e1da78c..c6b56c53413 100644 --- a/doc/api/project_level_variables.md +++ b/doc/api/project_level_variables.md @@ -31,6 +31,7 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a "value": "TEST_1", "protected": false, "masked": true, + "raw": false, "environment_scope": "*" }, { @@ -39,6 +40,7 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a "value": "TEST_2", "protected": false, "masked": false, + "raw": false, "environment_scope": "*" } ] @@ -70,6 +72,7 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a "value": "TEST_1", "protected": false, "masked": true, + "raw": false, "environment_scope": "*" } ``` @@ -92,6 +95,7 @@ POST /projects/:id/variables | `variable_type` | string | no | The type of a variable. Available types are: `env_var` (default) and `file` | | `protected` | boolean | no | Whether the variable is protected. Default: `false` | | `masked` | boolean | no | Whether the variable is masked. Default: `false` | +| `raw` | boolean | no | Whether the variable is expandable. Default: `false` | | `environment_scope` | string | no | The `environment_scope` of the variable. Default: `*` | ```shell @@ -106,6 +110,7 @@ curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \ "value": "new value", "protected": false, "masked": false, + "raw": false, "environment_scope": "*" } ``` @@ -127,6 +132,7 @@ PUT /projects/:id/variables/:key | `variable_type` | string | no | The type of a variable. Available types are: `env_var` (default) and `file` | | `protected` | boolean | no | Whether the variable is protected | | `masked` | boolean | no | Whether the variable is masked | +| `raw` | boolean | no | Whether the variable is expandable. Default: `false` | | `environment_scope` | string | no | The `environment_scope` of the variable | | `filter` | hash | no | Available filters: `[environment_scope]`. See the [`filter` parameter details](#the-filter-parameter). | @@ -142,6 +148,7 @@ curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" \ "value": "updated value", "protected": true, "masked": false, + "raw": false, "environment_scope": "*" } ``` diff --git a/doc/architecture/blueprints/ci_data_decay/index.md b/doc/architecture/blueprints/ci_data_decay/index.md index e38fe26dc79..f432b74d2e2 100644 --- a/doc/architecture/blueprints/ci_data_decay/index.md +++ b/doc/architecture/blueprints/ci_data_decay/index.md @@ -249,3 +249,4 @@ In progress. - 2022-04-30: Additional [benchmarking started](https://gitlab.com/gitlab-org/gitlab/-/issues/361019) to evaluate impact. - 2022-06-31: [Pipeline partitioning design](pipeline_partitioning.md) document [merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87683) merged. - 2022-09-01: Engineering effort started to implement partitioning. +- 2022-11-01: The fastest growing CI table partitioned: `ci_builds_metadata`. diff --git a/doc/development/api_graphql_styleguide.md b/doc/development/api_graphql_styleguide.md index a6df26ff0d2..c6138c9c646 100644 --- a/doc/development/api_graphql_styleguide.md +++ b/doc/development/api_graphql_styleguide.md @@ -1294,15 +1294,25 @@ class MyThingResolver < BaseResolver end ``` -The final thing that is needed is that every field that uses this resolver needs -to advertise the need for lookahead: +The `LooksAhead` concern also provides basic support for preloading associations based on nested GraphQL field +definitions. The [WorkItemsResolver](https://gitlab.com/gitlab-org/gitlab/-/blob/e824a7e39e08a83fb162db6851de147cf0bfe14a/app/graphql/resolvers/work_items_resolver.rb#L46) +is a good example for this. `nested_preloads` is another method you can define to return a hash, but unlike the +`preloads` method, the value for each hash key is another hash and not the list of associations to preload. So in +the previous example, you could override `nested_preloads` like this: ```ruby - # in ParentType - field :my_things, MyThingType.connection_type, null: true, - extras: [:lookahead], # Necessary - resolver: MyThingResolver, - description: 'My things.' +class MyThingResolver < BaseResolver + # ... + + def nested_preloads + { + root_field: { + nested_field1: :association_to_preload, + nested_field2: [:association1, :association2] + } + } + end +end ``` For an example of real world use, please diff --git a/doc/development/documentation/styleguide/word_list.md b/doc/development/documentation/styleguide/word_list.md index faac229d8d3..669ba701b5b 100644 --- a/doc/development/documentation/styleguide/word_list.md +++ b/doc/development/documentation/styleguide/word_list.md @@ -1230,6 +1230,25 @@ Instead of: ([Vale](../testing.md#vale) rule: [`SubstitutionSuggestions.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/SubstitutionSuggestions.yml)) +## while + +Use **while** to refer only to something occurring in time. For example, +**Leave the window open while the process runs.** + +Do not use **while** for comparison. For example, use: + +- Job 1 can run quickly. However, job 2 is more precise. + +Instead of: + +- While job 1 can run quickly, job 2 is more precise. + +For details, see the [Microsoft style guide](https://learn.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/w/while). + +## whilst + +Do not use **whilst**. Use [while](#while) instead. **While** is more succinct and easier for non-native English speakers to understand. + ## whitelist Do not use **whitelist**. Another option is **allowlist**. ([Vale](../testing.md#vale) rule: [`InclusionCultural.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionCultural.yml)) diff --git a/doc/development/documentation/topic_types/tutorial.md b/doc/development/documentation/topic_types/tutorial.md index 4c8e9e4c5ad..f79229b6704 100644 --- a/doc/development/documentation/topic_types/tutorial.md +++ b/doc/development/documentation/topic_types/tutorial.md @@ -4,7 +4,7 @@ group: Style Guide info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments --- -# Tutorial topic type +# Tutorial page type A tutorial is page that contains an end-to-end walkthrough of a complex workflow or scenario. In general, you might consider using a tutorial when: @@ -77,3 +77,14 @@ you can: - Use future tense from time to time, especially when you're introducing steps. For example, `Next, you will associate your issues with your epics`. - Be more conversational. For example, `This task might take a while to complete`. + +## Metadata + +On pages that are tutorials, add the most appropriate `stage:` and `group:` metadata at the top of the file. +If the majority of the content does not align with a single group, specify `none` for the stage +and `Tutorials` for the group: + +```plaintext +stage: none +group: Tutorials +``` diff --git a/doc/user/project/labels.md b/doc/user/project/labels.md index 826e0b21ea7..b2135cd3e42 100644 --- a/doc/user/project/labels.md +++ b/doc/user/project/labels.md @@ -410,7 +410,7 @@ To subscribe to a label: 1. To the right of any label, select **Subscribe**. 1. Optional. If you are subscribing to a group label from a project, select either: - **Subscribe at project level** to be notified about events in this project. - - **Subscribe at group level**: to be notified about events in the whole group. + - **Subscribe at group level** to be notified about events in the whole group. ## Set label priority diff --git a/lib/api/admin/ci/variables.rb b/lib/api/admin/ci/variables.rb index 0d959d31a65..bc351e27f99 100644 --- a/lib/api/admin/ci/variables.rb +++ b/lib/api/admin/ci/variables.rb @@ -59,13 +59,17 @@ module API desc: 'The value of a variable' optional :protected, - type: String, + type: Boolean, desc: 'Whether the variable is protected' optional :masked, - type: String, + type: Boolean, desc: 'Whether the variable is masked' + optional :raw, + type: Boolean, + desc: 'Whether the variable will be expanded' + optional :variable_type, type: String, values: ::Ci::InstanceVariable.variable_types.keys, @@ -99,13 +103,17 @@ module API desc: 'The value of a variable' optional :protected, - type: String, + type: Boolean, desc: 'Whether the variable is protected' optional :masked, - type: String, + type: Boolean, desc: 'Whether the variable is masked' + optional :raw, + type: Boolean, + desc: 'Whether the variable will be expanded' + optional :variable_type, type: String, values: ::Ci::InstanceVariable.variable_types.keys, diff --git a/lib/api/ci/variables.rb b/lib/api/ci/variables.rb index b5eecc844d5..04c77555132 100644 --- a/lib/api/ci/variables.rb +++ b/lib/api/ci/variables.rb @@ -55,6 +55,7 @@ module API requires :value, type: String, desc: 'The value of the variable' optional :protected, type: Boolean, desc: 'Whether the variable is protected' optional :masked, type: Boolean, desc: 'Whether the variable is masked' + optional :raw, type: Boolean, desc: 'Whether the variable will be expanded' optional :variable_type, type: String, values: ::Ci::Variable.variable_types.keys, desc: 'The type of variable, must be one of env_var or file. Defaults to env_var' optional :environment_scope, type: String, desc: 'The environment_scope of the variable' end @@ -81,6 +82,7 @@ module API optional :value, type: String, desc: 'The value of the variable' optional :protected, type: Boolean, desc: 'Whether the variable is protected' optional :masked, type: Boolean, desc: 'Whether the variable is masked' + optional :raw, type: Boolean, desc: 'Whether the variable will be expanded' optional :variable_type, type: String, values: ::Ci::Variable.variable_types.keys, desc: 'The type of variable, must be one of env_var or file' optional :environment_scope, type: String, desc: 'The environment_scope of the variable' optional :filter, type: Hash, desc: 'Available filters: [environment_scope]. Example: filter[environment_scope]=production' do diff --git a/lib/api/entities/ci/variable.rb b/lib/api/entities/ci/variable.rb index da5f5cc5cb1..47597cb77be 100644 --- a/lib/api/entities/ci/variable.rb +++ b/lib/api/entities/ci/variable.rb @@ -11,6 +11,7 @@ module API documentation: { type: 'boolean' } expose :masked?, as: :masked, if: -> (entity, _) { entity.respond_to?(:masked?) }, documentation: { type: 'boolean' } + expose :raw?, as: :raw, if: -> (entity, _) { entity.respond_to?(:raw?) }, documentation: { type: 'boolean' } expose :environment_scope, if: -> (entity, _) { entity.respond_to?(:environment_scope) }, documentation: { type: 'string', example: '*' } end diff --git a/lib/api/group_variables.rb b/lib/api/group_variables.rb index cc24fb6fc4d..e60f58a62e8 100644 --- a/lib/api/group_variables.rb +++ b/lib/api/group_variables.rb @@ -49,6 +49,7 @@ module API requires :value, type: String, desc: 'The value of the variable' optional :protected, type: String, desc: 'Whether the variable is protected' optional :masked, type: String, desc: 'Whether the variable is masked' + optional :raw, type: String, desc: 'Whether the variable will be expanded' optional :variable_type, type: String, values: ::Ci::GroupVariable.variable_types.keys, desc: 'The type of variable, must be one of env_var or file. Defaults to env_var' use :optional_group_variable_params_ee @@ -81,6 +82,7 @@ module API optional :value, type: String, desc: 'The value of the variable' optional :protected, type: String, desc: 'Whether the variable is protected' optional :masked, type: String, desc: 'Whether the variable is masked' + optional :raw, type: String, desc: 'Whether the variable will be expanded' optional :variable_type, type: String, values: ::Ci::GroupVariable.variable_types.keys, desc: 'The type of variable, must be one of env_var or file' use :optional_group_variable_params_ee diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index a5eab9aae8c..dc7ecb7ec45 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -534,9 +534,9 @@ module Gitlab # Returns matching refs for OID # # Limit of 0 means there is no limit. - def refs_by_oid(oid:, limit: 0) + def refs_by_oid(oid:, limit: 0, ref_patterns: nil) wrapped_gitaly_errors do - gitaly_ref_client.find_refs_by_oid(oid: oid, limit: limit) + gitaly_ref_client.find_refs_by_oid(oid: oid, limit: limit, ref_patterns: ref_patterns) end rescue CommandError, TypeError, NoRepository nil diff --git a/lib/gitlab/gitaly_client/ref_service.rb b/lib/gitlab/gitaly_client/ref_service.rb index d2b702f3a6d..bd6ff30df98 100644 --- a/lib/gitlab/gitaly_client/ref_service.rb +++ b/lib/gitlab/gitaly_client/ref_service.rb @@ -232,8 +232,8 @@ module Gitlab GitalyClient.call(@storage, :ref_service, :pack_refs, request, timeout: GitalyClient.long_timeout) end - def find_refs_by_oid(oid:, limit:) - request = Gitaly::FindRefsByOIDRequest.new(repository: @gitaly_repo, sort_field: :refname, oid: oid, limit: limit) + def find_refs_by_oid(oid:, limit:, ref_patterns: nil) + request = Gitaly::FindRefsByOIDRequest.new(repository: @gitaly_repo, sort_field: :refname, oid: oid, limit: limit, ref_patterns: ref_patterns) response = GitalyClient.call(@storage, :ref_service, :find_refs_by_oid, request, timeout: GitalyClient.medium_timeout) response&.refs&.to_a diff --git a/lib/gitlab/patch/sidekiq_cron_poller.rb b/lib/gitlab/patch/sidekiq_cron_poller.rb index 1c24707499e..c9eae2f899f 100644 --- a/lib/gitlab/patch/sidekiq_cron_poller.rb +++ b/lib/gitlab/patch/sidekiq_cron_poller.rb @@ -1,12 +1,13 @@ # frozen_string_literal: true # Patch to address https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1932 -# It restores the behavior of `poll_internal_average` to the one from Sidekiq 6.4.2 -# (see https://github.com/mperham/sidekiq/blob/v6.4.2/lib/sidekiq/scheduled.rb#L173-L175) +# It restores the behavior of `poll_internal_average` to the one from Sidekiq 6.5.7 +# when the cron poll interval is not configured. +# (see https://github.com/mperham/sidekiq/blob/v6.5.7/lib/sidekiq/scheduled.rb#L176-L178) require 'sidekiq/version' require 'sidekiq/cron/version' -if Gem::Version.new(Sidekiq::VERSION) != Gem::Version.new('6.4.2') +if Gem::Version.new(Sidekiq::VERSION) != Gem::Version.new('6.5.7') raise 'New version of sidekiq detected, please remove or update this patch' end @@ -17,11 +18,8 @@ end module Gitlab module Patch module SidekiqCronPoller - def poll_interval_average - # Note: This diverges from the Sidekiq implementation in 6.4.2 to address a bug where the poll interval wouldn't - # scale properly when the process count changes, and to take into account the `cron_poll_interval` setting. See - # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/99030#note_1117078517 for more details - Gitlab.config.cron_jobs.poll_interval || Sidekiq.options[:poll_interval_average] || scaled_poll_interval + def poll_interval_average(count) + Gitlab.config.cron_jobs.poll_interval || @config[:poll_interval_average] || scaled_poll_interval(count) # rubocop:disable Gitlab/ModuleWithInstanceVariables end end end diff --git a/lib/gitlab/query_limiting/transaction.rb b/lib/gitlab/query_limiting/transaction.rb index 46c0a0ddf7a..498da38e268 100644 --- a/lib/gitlab/query_limiting/transaction.rb +++ b/lib/gitlab/query_limiting/transaction.rb @@ -68,14 +68,14 @@ module Gitlab GEO_NODES_LOAD = 'SELECT 1 AS one FROM "geo_nodes" LIMIT 1' LICENSES_LOAD = 'SELECT "licenses".* FROM "licenses" ORDER BY "licenses"."id"' - ATTR_INTROSPECTION = %r/SELECT .*\ba.attname\b.* (FROM|JOIN) pg_attribute a/m.freeze + SCHEMA_INTROSPECTION = %r/SELECT.*(FROM|JOIN) (pg_attribute|pg_class)/m.freeze # queries can be safely ignored if they are amoritized in regular usage # (i.e. only requested occasionally and otherwise cached). def ignorable?(sql) return true if sql&.include?(GEO_NODES_LOAD) return true if sql&.include?(LICENSES_LOAD) - return true if ATTR_INTROSPECTION =~ sql + return true if SCHEMA_INTROSPECTION.match?(sql) false end diff --git a/lib/gitlab/runtime.rb b/lib/gitlab/runtime.rb index 6d95cb9a87b..7e9fb82fb8b 100644 --- a/lib/gitlab/runtime.rb +++ b/lib/gitlab/runtime.rb @@ -42,7 +42,7 @@ module Gitlab end def sidekiq? - !!(defined?(::Sidekiq) && Sidekiq.server?) + !!(defined?(::Sidekiq) && Sidekiq.try(:server?)) end def rake? @@ -94,7 +94,7 @@ module Gitlab # # These threads execute Sidekiq client middleware when jobs # are enqueued and those can access DB / Redis. - threads += Sidekiq.options[:concurrency] + 2 + threads += Sidekiq[:concurrency] + 2 end if puma? diff --git a/lib/gitlab/sidekiq_config.rb b/lib/gitlab/sidekiq_config.rb index 3e7bdfbe89a..7e2a934b3dd 100644 --- a/lib/gitlab/sidekiq_config.rb +++ b/lib/gitlab/sidekiq_config.rb @@ -162,7 +162,7 @@ module Gitlab # the current Sidekiq process def current_worker_queue_mappings worker_queue_mappings - .select { |worker, queue| Sidekiq.options[:queues].include?(queue) } + .select { |worker, queue| Sidekiq[:queues].include?(queue) } .to_h end diff --git a/lib/gitlab/sidekiq_daemon/memory_killer.rb b/lib/gitlab/sidekiq_daemon/memory_killer.rb index b440ee5dd21..d5227e7a007 100644 --- a/lib/gitlab/sidekiq_daemon/memory_killer.rb +++ b/lib/gitlab/sidekiq_daemon/memory_killer.rb @@ -118,9 +118,9 @@ module Gitlab return unless enabled? # Tell sidekiq to restart itself - # Keep extra safe to wait `Sidekiq.options[:timeout] + 2` seconds before SIGKILL + # Keep extra safe to wait `Sidekiq[:timeout] + 2` seconds before SIGKILL refresh_state(:shutting_down) - signal_and_wait(Sidekiq.options[:timeout] + 2, 'SIGTERM', 'gracefully shut down') + signal_and_wait(Sidekiq[:timeout] + 2, 'SIGTERM', 'gracefully shut down') return unless enabled? # Ideally we should never reach this condition diff --git a/lib/gitlab/sidekiq_middleware/arguments_logger.rb b/lib/gitlab/sidekiq_middleware/arguments_logger.rb index fe5213fc5d7..2c506786d83 100644 --- a/lib/gitlab/sidekiq_middleware/arguments_logger.rb +++ b/lib/gitlab/sidekiq_middleware/arguments_logger.rb @@ -3,8 +3,10 @@ module Gitlab module SidekiqMiddleware class ArgumentsLogger + include Sidekiq::ServerMiddleware + def call(worker, job, queue) - Sidekiq.logger.info "arguments: #{Gitlab::Json.dump(job['args'])}" + logger.info "arguments: #{Gitlab::Json.dump(job['args'])}" yield end end diff --git a/lib/gitlab/sidekiq_middleware/server_metrics.rb b/lib/gitlab/sidekiq_middleware/server_metrics.rb index 3dd5355d3a3..e36f61be3b3 100644 --- a/lib/gitlab/sidekiq_middleware/server_metrics.rb +++ b/lib/gitlab/sidekiq_middleware/server_metrics.rb @@ -43,7 +43,7 @@ module Gitlab def initialize_process_metrics metrics = self.metrics - metrics[:sidekiq_concurrency].set({}, Sidekiq.options[:concurrency].to_i) + metrics[:sidekiq_concurrency].set({}, Sidekiq[:concurrency].to_i) return unless ::Feature.enabled?(:sidekiq_job_completion_metric_initialize) diff --git a/rubocop/cop/migration/schema_addition_methods_no_post.rb b/rubocop/cop/migration/schema_addition_methods_no_post.rb new file mode 100644 index 00000000000..5bb5bb63f0c --- /dev/null +++ b/rubocop/cop/migration/schema_addition_methods_no_post.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require_relative '../../migration_helpers' + +module RuboCop + module Cop + module Migration + # Cop that checks that no background batched migration helpers are called by regular migrations. + class SchemaAdditionMethodsNoPost < RuboCop::Cop::Base + include MigrationHelpers + + MSG = "This method may not be used in post migrations. Please see documentation here: https://docs.gitlab.com/ee/development/migration_style_guide.html#choose-an-appropriate-migration-type" + + FORBIDDEN_METHODS = %w[ + add_column + create_table + ].freeze + + SYMBOLIZED_MATCHER = FORBIDDEN_METHODS.map { |w| ":#{w}" }.join(' | ') + + def_node_matcher :on_forbidden_method, <<~PATTERN + (send nil? {#{SYMBOLIZED_MATCHER}} ...) + PATTERN + + def on_send(node) + return unless time_enforced?(node) + + on_forbidden_method(node) do + add_offense(node, message: MSG) + end + end + end + end + end +end diff --git a/rubocop/migration_helpers.rb b/rubocop/migration_helpers.rb index 16a9aa53cd3..22f3931be73 100644 --- a/rubocop/migration_helpers.rb +++ b/rubocop/migration_helpers.rb @@ -49,6 +49,14 @@ module RuboCop dirname(node).end_with?('db/post_migrate', 'db/geo/post_migrate') end + # Returns true if we've defined an 'EnforcedSince' variable in rubocop.yml and the migration version + # is greater. + def time_enforced?(node) + return false unless enforced_since + + version(node) > enforced_since + end + def version(node) File.basename(node.location.expression.source_buffer.name).split('_').first.to_i end @@ -80,5 +88,9 @@ module RuboCop def rubocop_path File.expand_path(__dir__) end + + def enforced_since + @enforced_since ||= config.for_cop(name)['EnforcedSince'] + end end end diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index 3a25d179e84..6e3a7a3f5ef 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -252,6 +252,7 @@ FactoryBot.define do transient do create_templates { nil } create_branch { nil } + create_tag { nil } end after :create do |project, evaluator| @@ -288,6 +289,13 @@ FactoryBot.define do end + if evaluator.create_tag + project.repository.add_tag( + project.creator, + evaluator.create_tag, + project.repository.commit.sha) + end + project.track_project_repository end end diff --git a/spec/fixtures/api/schemas/pipeline_schedule_variable.json b/spec/fixtures/api/schemas/pipeline_schedule_variable.json index 022d36cb88c..83eed11f458 100644 --- a/spec/fixtures/api/schemas/pipeline_schedule_variable.json +++ b/spec/fixtures/api/schemas/pipeline_schedule_variable.json @@ -6,9 +6,18 @@ "variable_type" ], "properties": { - "key": { "type": "string" }, - "value": { "type": "string" }, - "variable_type": { "type": "string" } + "key": { + "type": "string" + }, + "value": { + "type": "string" + }, + "variable_type": { + "type": "string" + }, + "raw": { + "type": "boolean" + } }, "additionalProperties": false -} +}
\ No newline at end of file diff --git a/spec/frontend/search/sidebar/components/app_spec.js b/spec/frontend/search/sidebar/components/app_spec.js index b4e3388f067..e87217950cd 100644 --- a/spec/frontend/search/sidebar/components/app_spec.js +++ b/spec/frontend/search/sidebar/components/app_spec.js @@ -4,6 +4,7 @@ import Vuex from 'vuex'; import { MOCK_QUERY } from 'jest/search/mock_data'; import GlobalSearchSidebar from '~/search/sidebar/components/app.vue'; import ResultsFilters from '~/search/sidebar/components/results_filters.vue'; +import ScopeNavigation from '~/search/sidebar/components/scope_navigation.vue'; Vue.use(Vuex); @@ -15,7 +16,7 @@ describe('GlobalSearchSidebar', () => { resetQuery: jest.fn(), }; - const createComponent = (initialState) => { + const createComponent = (initialState, featureFlags) => { const store = new Vuex.Store({ state: { urlQuery: MOCK_QUERY, @@ -26,6 +27,11 @@ describe('GlobalSearchSidebar', () => { wrapper = shallowMount(GlobalSearchSidebar, { store, + provide: { + glFeatures: { + ...featureFlags, + }, + }, }); }; @@ -35,6 +41,7 @@ describe('GlobalSearchSidebar', () => { const findSidebarSection = () => wrapper.find('section'); const findFilters = () => wrapper.findComponent(ResultsFilters); + const findSidebarNavigation = () => wrapper.findComponent(ScopeNavigation); describe('renders properly', () => { describe('scope=projects', () => { @@ -78,4 +85,22 @@ describe('GlobalSearchSidebar', () => { }); }); }); + + describe('when search_page_vertical_nav is enabled', () => { + beforeEach(() => { + createComponent({}, { searchPageVerticalNav: true }); + }); + it('shows the vertical navigation', () => { + expect(findSidebarNavigation().exists()).toBe(true); + }); + }); + + describe('when search_page_vertical_nav is disabled', () => { + beforeEach(() => { + createComponent({}, { searchPageVerticalNav: false }); + }); + it('hides the vertical navigation', () => { + expect(findSidebarNavigation().exists()).toBe(false); + }); + }); }); diff --git a/spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb b/spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb index 88007de53d3..61b63016f1a 100644 --- a/spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb +++ b/spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb @@ -358,7 +358,7 @@ RSpec.describe Gitlab::Database::LoadBalancing::SidekiqServerMiddleware, :clean_ end def process_job(job) - Sidekiq::JobRetry.new.local(worker_class, job.to_json, 'default') do + Sidekiq::JobRetry.new(Sidekiq).local(worker_class, job.to_json, 'default') do worker_class.process_job(job) end end diff --git a/spec/lib/gitlab/gitaly_client/ref_service_spec.rb b/spec/lib/gitlab/gitaly_client/ref_service_spec.rb index 5ce88b06241..bd96e9baf1d 100644 --- a/spec/lib/gitlab/gitaly_client/ref_service_spec.rb +++ b/spec/lib/gitlab/gitaly_client/ref_service_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe Gitlab::GitalyClient::RefService do - let_it_be(:project) { create(:project, :repository) } + let_it_be(:project) { create(:project, :repository, create_tag: 'test') } let(:storage_name) { project.repository_storage } let(:relative_path) { project.disk_path + '.git' } @@ -438,12 +438,28 @@ RSpec.describe Gitlab::GitalyClient::RefService do it 'sends a find_refs_by_oid message' do expect_any_instance_of(Gitaly::RefService::Stub) .to receive(:find_refs_by_oid) - .with(gitaly_request_with_params(sort_field: 'refname', oid: oid, limit: 1), kind_of(Hash)) + .with(gitaly_request_with_params(sort_field: 'refname', + oid: oid, + limit: 1), kind_of(Hash)) .and_call_original refs = client.find_refs_by_oid(oid: oid, limit: 1) expect(refs.to_a).to eq([Gitlab::Git::BRANCH_REF_PREFIX + project.repository.root_ref]) end + + it 'filters by ref_patterns' do + expect_any_instance_of(Gitaly::RefService::Stub) + .to receive(:find_refs_by_oid) + .with(gitaly_request_with_params(sort_field: 'refname', + oid: oid, + limit: 1, + ref_patterns: [Gitlab::Git::TAG_REF_PREFIX]), kind_of(Hash)) + .and_call_original + + refs = client.find_refs_by_oid(oid: oid, limit: 1, ref_patterns: [Gitlab::Git::TAG_REF_PREFIX]) + + expect(refs.to_a).to eq([Gitlab::Git::TAG_REF_PREFIX + 'test']) + end end end diff --git a/spec/lib/gitlab/query_limiting/transaction_spec.rb b/spec/lib/gitlab/query_limiting/transaction_spec.rb index d8eb2040ccc..c11d0a7c18d 100644 --- a/spec/lib/gitlab/query_limiting/transaction_spec.rb +++ b/spec/lib/gitlab/query_limiting/transaction_spec.rb @@ -91,6 +91,9 @@ RSpec.describe Gitlab::QueryLimiting::Transaction do SELECT a.attname, a.other_column FROM pg_attribute a SQL + transaction.increment( + "SELECT a.attnum, a.attname\nFROM pg_attribute a\nWHERE a.attrelid = 10605202\nAND a.attnum IN (3)\n" + ) end.not_to change(transaction, :count) end end diff --git a/spec/lib/gitlab/runtime_spec.rb b/spec/lib/gitlab/runtime_spec.rb index 86640efed5a..181a911c667 100644 --- a/spec/lib/gitlab/runtime_spec.rb +++ b/spec/lib/gitlab/runtime_spec.rb @@ -113,7 +113,7 @@ RSpec.describe Gitlab::Runtime do before do stub_const('::Sidekiq', sidekiq_type) allow(sidekiq_type).to receive(:server?).and_return(true) - allow(sidekiq_type).to receive(:options).and_return(concurrency: 2) + allow(sidekiq_type).to receive(:[]).with(:concurrency).and_return(2) end it_behaves_like "valid runtime", :sidekiq, 5 diff --git a/spec/lib/gitlab/sidekiq_config_spec.rb b/spec/lib/gitlab/sidekiq_config_spec.rb index c5b00afe672..5f72a3feba7 100644 --- a/spec/lib/gitlab/sidekiq_config_spec.rb +++ b/spec/lib/gitlab/sidekiq_config_spec.rb @@ -157,7 +157,7 @@ RSpec.describe Gitlab::SidekiqConfig do allow(::Gitlab::SidekiqConfig::WorkerRouter) .to receive(:global).and_return(::Gitlab::SidekiqConfig::WorkerRouter.new(test_routes)) - allow(Sidekiq).to receive(:options).and_return(queues: %w[default background_migration]) + allow(Sidekiq).to receive(:[]).with(:queues).and_return(%w[default background_migration]) mappings = described_class.current_worker_queue_mappings diff --git a/spec/lib/gitlab/sidekiq_daemon/memory_killer_spec.rb b/spec/lib/gitlab/sidekiq_daemon/memory_killer_spec.rb index 62681b21756..8c9a1abba5a 100644 --- a/spec/lib/gitlab/sidekiq_daemon/memory_killer_spec.rb +++ b/spec/lib/gitlab/sidekiq_daemon/memory_killer_spec.rb @@ -126,7 +126,7 @@ RSpec.describe Gitlab::SidekiqDaemon::MemoryKiller do stub_const("#{described_class}::CHECK_INTERVAL_SECONDS", check_interval_seconds) stub_const("#{described_class}::GRACE_BALLOON_SECONDS", grace_balloon_seconds) allow(Process).to receive(:getpgrp).and_return(pid) - allow(Sidekiq).to receive(:options).and_return(timeout: 9) + allow(Sidekiq).to receive(:[]).with(:timeout).and_return(9) end it 'return true when everything is within limit', :aggregate_failures do @@ -257,7 +257,7 @@ RSpec.describe Gitlab::SidekiqDaemon::MemoryKiller do before do stub_const("#{described_class}::SHUTDOWN_TIMEOUT_SECONDS", shutdown_timeout_seconds) stub_feature_flags(sidekiq_memory_killer_read_only_mode: false) - allow(Sidekiq).to receive(:options).and_return(timeout: 9) + allow(Sidekiq).to receive(:[]).with(:timeout).and_return(9) allow(memory_killer).to receive(:get_rss_kb).and_return(100) allow(memory_killer).to receive(:get_soft_limit_rss_kb).and_return(200) allow(memory_killer).to receive(:get_hard_limit_rss_kb).and_return(300) diff --git a/spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb b/spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb index 54a1723afbc..1a53a9b8701 100644 --- a/spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb +++ b/spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb @@ -10,7 +10,7 @@ RSpec.describe Gitlab::SidekiqMiddleware::ServerMetrics do describe '.initialize_process_metrics' do it 'sets concurrency metrics' do - expect(concurrency_metric).to receive(:set).with({}, Sidekiq.options[:concurrency].to_i) + expect(concurrency_metric).to receive(:set).with({}, Sidekiq[:concurrency].to_i) described_class.initialize_process_metrics end @@ -65,7 +65,7 @@ RSpec.describe Gitlab::SidekiqMiddleware::ServerMetrics do end it 'sets the concurrency metric' do - expect(concurrency_metric).to receive(:set).with({}, Sidekiq.options[:concurrency].to_i) + expect(concurrency_metric).to receive(:set).with({}, Sidekiq[:concurrency].to_i) described_class.initialize_process_metrics end diff --git a/spec/lib/gitlab/sidekiq_middleware_spec.rb b/spec/lib/gitlab/sidekiq_middleware_spec.rb index 14dbeac37e8..af9075f5aa0 100644 --- a/spec/lib/gitlab/sidekiq_middleware_spec.rb +++ b/spec/lib/gitlab/sidekiq_middleware_spec.rb @@ -6,7 +6,7 @@ require 'sidekiq/testing' RSpec.describe Gitlab::SidekiqMiddleware do let(:job_args) { [0.01] } let(:disabled_sidekiq_middlewares) { [] } - let(:chain) { Sidekiq::Middleware::Chain.new } + let(:chain) { Sidekiq::Middleware::Chain.new(Sidekiq) } let(:queue) { 'test' } let(:enabled_sidekiq_middlewares) { all_sidekiq_middlewares - disabled_sidekiq_middlewares } let(:worker_class) do diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb index b91d836f82f..7d068235f18 100644 --- a/spec/models/deployment_spec.rb +++ b/spec/models/deployment_spec.rb @@ -1323,9 +1323,12 @@ RSpec.describe Deployment do subject { deployment.tags } it 'will return tags related to this deployment' do - expect(project.repository).to receive(:tag_names_contains).with(deployment.sha, limit: 100).and_return(['test']) + expect(project.repository).to receive(:refs_by_oid).with(oid: deployment.sha, + limit: 100, + ref_patterns: [Gitlab::Git::TAG_REF_PREFIX]) + .and_return(["#{Gitlab::Git::TAG_REF_PREFIX}test"]) - is_expected.to match_array(['test']) + is_expected.to match_array(['refs/tags/test']) end end diff --git a/spec/models/pages_domain_spec.rb b/spec/models/pages_domain_spec.rb index 463ec904e9a..e5f2e849a0a 100644 --- a/spec/models/pages_domain_spec.rb +++ b/spec/models/pages_domain_spec.rb @@ -209,6 +209,10 @@ RSpec.describe PagesDomain do expect(subject.wildcard).to eq(false) end + it 'defaults auto_ssl_enabled to false' do + expect(subject.auto_ssl_enabled).to eq(false) + end + it 'defaults scope to project' do expect(subject.scope).to eq('project') end diff --git a/spec/models/project_setting_spec.rb b/spec/models/project_setting_spec.rb index b33cf0219d3..94a2e2fe3f9 100644 --- a/spec/models/project_setting_spec.rb +++ b/spec/models/project_setting_spec.rb @@ -6,6 +6,10 @@ RSpec.describe ProjectSetting, type: :model do using RSpec::Parameterized::TableSyntax it { is_expected.to belong_to(:project) } + describe 'default values' do + it { expect(subject.legacy_open_source_license_available).to be_truthy } + end + describe 'scopes' do let_it_be(:project_1) { create(:project) } let_it_be(:project_2) { create(:project) } diff --git a/spec/models/serverless/domain_cluster_spec.rb b/spec/models/serverless/domain_cluster_spec.rb index fdae0483c19..487385c62c1 100644 --- a/spec/models/serverless/domain_cluster_spec.rb +++ b/spec/models/serverless/domain_cluster_spec.rb @@ -5,6 +5,16 @@ require 'spec_helper' RSpec.describe ::Serverless::DomainCluster do subject { create(:serverless_domain_cluster) } + describe 'default values' do + subject(:domain_cluster) { build(:serverless_domain_cluster) } + + before do + allow(::Serverless::Domain).to receive(:generate_uuid).and_return('randomtoken') + end + + it { expect(domain_cluster.uuid).to eq('randomtoken') } + end + describe 'validations' do it { is_expected.to validate_presence_of(:pages_domain) } it { is_expected.to validate_presence_of(:knative) } diff --git a/spec/presenters/deployments/deployment_presenter_spec.rb b/spec/presenters/deployments/deployment_presenter_spec.rb index 689451677f4..51da7b9fd12 100644 --- a/spec/presenters/deployments/deployment_presenter_spec.rb +++ b/spec/presenters/deployments/deployment_presenter_spec.rb @@ -8,7 +8,7 @@ RSpec.describe Deployments::DeploymentPresenter do describe '#tags' do it do - expect(deployment).to receive(:tags).and_return(['test']) + expect(deployment).to receive(:tags).and_return(['refs/tags/test']) expect(presenter.tags).to eq([{ name: 'test', path: 'tags/test' }]) end end diff --git a/spec/requests/api/admin/ci/variables_spec.rb b/spec/requests/api/admin/ci/variables_spec.rb index 93036bfe413..4bdc44cb583 100644 --- a/spec/requests/api/admin/ci/variables_spec.rb +++ b/spec/requests/api/admin/ci/variables_spec.rb @@ -71,7 +71,8 @@ RSpec.describe ::API::Admin::Ci::Variables do key: 'TEST_VARIABLE_2', value: 'PROTECTED_VALUE_2', protected: true, - masked: true + masked: true, + raw: true } end.to change { ::Ci::InstanceVariable.count }.by(1) @@ -80,6 +81,7 @@ RSpec.describe ::API::Admin::Ci::Variables do expect(json_response['value']).to eq('PROTECTED_VALUE_2') expect(json_response['protected']).to be_truthy expect(json_response['masked']).to be_truthy + expect(json_response['raw']).to be_truthy expect(json_response['variable_type']).to eq('env_var') end @@ -107,6 +109,7 @@ RSpec.describe ::API::Admin::Ci::Variables do expect(json_response['value']).to eq('VALUE_2') expect(json_response['protected']).to be_falsey expect(json_response['masked']).to be_falsey + expect(json_response['raw']).to be_falsey expect(json_response['variable_type']).to eq('file') end @@ -162,7 +165,8 @@ RSpec.describe ::API::Admin::Ci::Variables do variable_type: 'file', value: 'VALUE_1_UP', protected: true, - masked: true + masked: true, + raw: true } expect(response).to have_gitlab_http_status(:ok) @@ -170,6 +174,7 @@ RSpec.describe ::API::Admin::Ci::Variables do expect(variable.reload).to be_protected expect(json_response['variable_type']).to eq('file') expect(json_response['masked']).to be_truthy + expect(json_response['raw']).to be_truthy end it 'masks the new value when logging' do diff --git a/spec/requests/api/ci/pipelines_spec.rb b/spec/requests/api/ci/pipelines_spec.rb index 697fe16e222..c9d06f37c8b 100644 --- a/spec/requests/api/ci/pipelines_spec.rb +++ b/spec/requests/api/ci/pipelines_spec.rb @@ -940,7 +940,12 @@ RSpec.describe API::Ci::Pipelines do subject expect(response).to have_gitlab_http_status(:ok) - expect(json_response).to contain_exactly({ "variable_type" => "env_var", "key" => "foo", "value" => "bar" }) + expect(json_response).to contain_exactly({ + "variable_type" => "env_var", + "key" => "foo", + "value" => "bar", + "raw" => false + }) end end end @@ -961,7 +966,12 @@ RSpec.describe API::Ci::Pipelines do subject expect(response).to have_gitlab_http_status(:ok) - expect(json_response).to contain_exactly({ "variable_type" => "env_var", "key" => "foo", "value" => "bar" }) + expect(json_response).to contain_exactly({ + "variable_type" => "env_var", + "key" => "foo", + "value" => "bar", + "raw" => false + }) end end diff --git a/spec/requests/api/ci/variables_spec.rb b/spec/requests/api/ci/variables_spec.rb index 99e3541acdd..cafb841995d 100644 --- a/spec/requests/api/ci/variables_spec.rb +++ b/spec/requests/api/ci/variables_spec.rb @@ -46,6 +46,7 @@ RSpec.describe API::Ci::Variables do expect(json_response['value']).to eq(variable.value) expect(json_response['protected']).to eq(variable.protected?) expect(json_response['masked']).to eq(variable.masked?) + expect(json_response['raw']).to eq(variable.raw?) expect(json_response['variable_type']).to eq('env_var') end @@ -115,7 +116,7 @@ RSpec.describe API::Ci::Variables do context 'authorized user with proper permissions' do it 'creates variable' do expect do - post api("/projects/#{project.id}/variables", user), params: { key: 'TEST_VARIABLE_2', value: 'PROTECTED_VALUE_2', protected: true, masked: true } + post api("/projects/#{project.id}/variables", user), params: { key: 'TEST_VARIABLE_2', value: 'PROTECTED_VALUE_2', protected: true, masked: true, raw: true } end.to change { project.variables.count }.by(1) expect(response).to have_gitlab_http_status(:created) @@ -123,6 +124,7 @@ RSpec.describe API::Ci::Variables do expect(json_response['value']).to eq('PROTECTED_VALUE_2') expect(json_response['protected']).to be_truthy expect(json_response['masked']).to be_truthy + expect(json_response['raw']).to be_truthy expect(json_response['variable_type']).to eq('env_var') end @@ -145,6 +147,7 @@ RSpec.describe API::Ci::Variables do expect(json_response['value']).to eq('VALUE_2') expect(json_response['protected']).to be_falsey expect(json_response['masked']).to be_falsey + expect(json_response['raw']).to be_falsey expect(json_response['variable_type']).to eq('file') end diff --git a/spec/requests/api/group_variables_spec.rb b/spec/requests/api/group_variables_spec.rb index 979a9d61d15..a07a8ae4292 100644 --- a/spec/requests/api/group_variables_spec.rb +++ b/spec/requests/api/group_variables_spec.rb @@ -90,7 +90,7 @@ RSpec.describe API::GroupVariables do it 'creates variable' do expect do - post api("/groups/#{group.id}/variables", user), params: { key: 'TEST_VARIABLE_2', value: 'PROTECTED_VALUE_2', protected: true, masked: true } + post api("/groups/#{group.id}/variables", user), params: { key: 'TEST_VARIABLE_2', value: 'PROTECTED_VALUE_2', protected: true, masked: true, raw: true } end.to change { group.variables.count }.by(1) expect(response).to have_gitlab_http_status(:created) @@ -100,6 +100,7 @@ RSpec.describe API::GroupVariables do expect(json_response['masked']).to be_truthy expect(json_response['variable_type']).to eq('env_var') expect(json_response['environment_scope']).to eq('*') + expect(json_response['raw']).to be_truthy end it 'masks the new value when logging' do @@ -121,6 +122,7 @@ RSpec.describe API::GroupVariables do expect(json_response['value']).to eq('VALUE_2') expect(json_response['protected']).to be_falsey expect(json_response['masked']).to be_falsey + expect(json_response['raw']).to be_falsey expect(json_response['variable_type']).to eq('file') expect(json_response['environment_scope']).to eq('*') end @@ -161,7 +163,7 @@ RSpec.describe API::GroupVariables do initial_variable = group.variables.reload.first value_before = initial_variable.value - put api("/groups/#{group.id}/variables/#{variable.key}", user), params: { variable_type: 'file', value: 'VALUE_1_UP', protected: true, masked: true } + put api("/groups/#{group.id}/variables/#{variable.key}", user), params: { variable_type: 'file', value: 'VALUE_1_UP', protected: true, masked: true, raw: true } updated_variable = group.variables.reload.first @@ -171,6 +173,7 @@ RSpec.describe API::GroupVariables do expect(updated_variable).to be_protected expect(json_response['variable_type']).to eq('file') expect(json_response['masked']).to be_truthy + expect(json_response['raw']).to be_truthy end it 'masks the new value when logging' do diff --git a/spec/rubocop/cop/migration/schema_addition_methods_no_post_spec.rb b/spec/rubocop/cop/migration/schema_addition_methods_no_post_spec.rb new file mode 100644 index 00000000000..fb087269e2d --- /dev/null +++ b/spec/rubocop/cop/migration/schema_addition_methods_no_post_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'rubocop_spec_helper' +require_relative '../../../../rubocop/cop/migration/schema_addition_methods_no_post' + +RSpec.describe RuboCop::Cop::Migration::SchemaAdditionMethodsNoPost do + before do + allow(cop).to receive(:time_enforced?).and_return true + end + + it "does not allow 'add_column' to be called" do + expect_offense(<<~CODE) + add_column + ^^^^^^^^^^ #{described_class::MSG} + CODE + end + + it "does not allow 'create_table' to be called" do + expect_offense(<<~CODE) + create_table + ^^^^^^^^^^^^ #{described_class::MSG} + CODE + end +end diff --git a/spec/rubocop/migration_helpers_spec.rb b/spec/rubocop/migration_helpers_spec.rb index 997d4071c29..6e6c3a7a0b9 100644 --- a/spec/rubocop/migration_helpers_spec.rb +++ b/spec/rubocop/migration_helpers_spec.rb @@ -52,4 +52,21 @@ RSpec.describe RuboCop::MigrationHelpers do it { expect(fake_cop.version(node)).to eq(20200210184420) } end + + describe '#time_enforced?' do + before do + allow(fake_cop).to receive(:name).and_return("TestCop") + allow(fake_cop).to receive(:config).and_return(double(for_cop: { 'EnforcedSince' => 20221018000000 })) + end + + where(:name, :expected) do + '/gitlab/db/post_migrate/20200210184420_create_operations_scopes_table.rb' | false + '/gitlab/db/post_migrate/20220210184420_create_fake_table.rb' | false + '/gitlab/db/post_migrate/20221019184420_add_id_to_reports_table.rb' | true + end + + with_them do + it { expect(fake_cop.time_enforced?(node)).to eq(expected) } + end + end end diff --git a/spec/support/shared_contexts/jobs/handling_retried_jobs_shared_context.rb b/spec/support/shared_contexts/jobs/handling_retried_jobs_shared_context.rb index ac6d58af344..428eff77373 100644 --- a/spec/support/shared_contexts/jobs/handling_retried_jobs_shared_context.rb +++ b/spec/support/shared_contexts/jobs/handling_retried_jobs_shared_context.rb @@ -15,10 +15,10 @@ RSpec.shared_context 'when handling retried jobs' do |url| 'retry' => true ) - allow(klass).to receive(:sidekiq_retry_in_block).and_return(proc { time }) + allow(klass).to receive(:sidekiq_retry_in_block).and_return(proc { time.to_i }) begin - Sidekiq::JobRetry.new.local(klass, message, klass.queue) { raise 'boom' } + Sidekiq::JobRetry.new(Sidekiq).local(klass, message, klass.queue) { raise 'boom' } rescue Sidekiq::JobRetry::Skip # Sidekiq scheduled the retry end diff --git a/spec/support/sidekiq_middleware.rb b/spec/support/sidekiq_middleware.rb index cbd6163d46b..73f43487d7c 100644 --- a/spec/support/sidekiq_middleware.rb +++ b/spec/support/sidekiq_middleware.rb @@ -6,6 +6,15 @@ require 'sidekiq/testing' module SidekiqMiddleware def with_sidekiq_server_middleware(&block) Sidekiq::Testing.server_middleware.clear + + if Gem::Version.new(Sidekiq::VERSION) != Gem::Version.new('6.5.7') + raise 'New version of sidekiq detected, please remove this line' + end + + # This line is a workaround for a Sidekiq bug that is already fixed in v7.0.0 + # https://github.com/mperham/sidekiq/commit/1b83a152786ed382f07fff12d2608534f1e3c922 + Sidekiq::Testing.server_middleware.instance_variable_set(:@config, Sidekiq) + Sidekiq::Testing.server_middleware(&block) ensure Sidekiq::Testing.server_middleware.clear |