Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-11-08 18:11:09 +00:00
parent b5bdf6e521
commit da576e4a0b
65 changed files with 500 additions and 157 deletions

View File

@ -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'

View File

@ -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'

View File

@ -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"},

View File

@ -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)

View File

@ -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>

View File

@ -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,

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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'

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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": "*"
}
```

View File

@ -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
}
```

View File

@ -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": "*"
}
```

View File

@ -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`.

View File

@ -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

View File

@ -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))

View File

@ -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
```

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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?

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}
}

View File

@ -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);
});
});
});

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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) }

View File

@ -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) }

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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