diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-11-22 18:11:26 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-11-22 18:11:26 +0300 |
commit | 5e44c2ba46e780552317dec29e3b51282dfd5696 (patch) | |
tree | ce3ad8f5d8ea5384ded1c537979e392ebe1b0182 | |
parent | 25bf8a36335fa281dc8fe56f355f3829ace703a5 (diff) |
Add latest changes from gitlab-org/gitlab@master
54 files changed, 717 insertions, 419 deletions
diff --git a/.gitlab/ci/build-images.gitlab-ci.yml b/.gitlab/ci/build-images.gitlab-ci.yml index 3c7056a92c1..a60a5f6040c 100644 --- a/.gitlab/ci/build-images.gitlab-ci.yml +++ b/.gitlab/ci/build-images.gitlab-ci.yml @@ -1,7 +1,13 @@ .base-image-build: extends: .use-kaniko variables: - GIT_LFS_SKIP_SMUDGE: 1 + GIT_LFS_SKIP_SMUDGE: 1 # disable pulling objects from lfs + retry: 2 + +.base-image-build-buildx: + extends: .use-buildx + variables: + GIT_LFS_SKIP_SMUDGE: 1 # disable pulling objects from lfs retry: 2 # This image is used by: @@ -10,12 +16,12 @@ # See https://docs.gitlab.com/ee/development/testing_guide/end_to_end/index.html#testing-code-in-merge-requests for more details. build-qa-image: extends: - - .base-image-build + - .base-image-build-buildx - .build-images:rules:build-qa-image stage: build-images needs: [] script: - - ./scripts/build_qa_image + - run_timed_command "scripts/build_qa_image" # This image is used by: # - The `CNG` pipelines (via the `review-build-cng` job): https://gitlab.com/gitlab-org/build/CNG/-/blob/cfc67136d711e1c8c409bf8e57427a644393da2f/.gitlab-ci.yml#L335 diff --git a/.gitlab/ci/global.gitlab-ci.yml b/.gitlab/ci/global.gitlab-ci.yml index 40e9b55aa27..0c178f349a5 100644 --- a/.gitlab/ci/global.gitlab-ci.yml +++ b/.gitlab/ci/global.gitlab-ci.yml @@ -348,3 +348,20 @@ tags: # See https://gitlab.com/gitlab-com/www-gitlab-com/-/issues/7019 for tag descriptions - gitlab-org-docker + +.use-buildx: + extends: .use-docker-in-docker + image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/debian-bullseye-slim:docker-${DOCKER_VERSION}-buildx-0.8 + variables: + QEMU_IMAGE: tonistiigi/binfmt:qemu-v7.0.0 + before_script: + - source scripts/utils.sh + - echo "$CI_REGISTRY_PASSWORD" | docker login "$CI_REGISTRY" -u "$CI_REGISTRY_USER" --password-stdin + - | + if [[ "${ARCH}" =~ arm64 ]]; then + echo -e "\033[1;33mInstalling latest qemu emulators\033[0m" + docker pull -q ${QEMU_IMAGE}; + docker run --rm --privileged ${QEMU_IMAGE} --uninstall qemu-*; + docker run --rm --privileged ${QEMU_IMAGE} --install all; + fi + - docker buildx create --use # creates and set's to active buildkit builder diff --git a/.gitlab/ci/review-apps/main.gitlab-ci.yml b/.gitlab/ci/review-apps/main.gitlab-ci.yml index 89ff59a9f3f..8971d328179 100644 --- a/.gitlab/ci/review-apps/main.gitlab-ci.yml +++ b/.gitlab/ci/review-apps/main.gitlab-ci.yml @@ -108,6 +108,8 @@ review-deploy: key: "review-deploy-dependencies-charts-${GITLAB_HELM_CHART_REF}-v1" paths: - "gitlab-${GITLAB_HELM_CHART_REF}" + environment: + action: start before_script: - export GITLAB_SHELL_VERSION=$(<GITLAB_SHELL_VERSION) - export GITALY_VERSION=$(<GITALY_SERVER_VERSION) @@ -140,6 +142,8 @@ review-deploy-sample-projects: - .review:rules:review-deploy stage: deploy needs: ["review-deploy"] + environment: + action: prepare before_script: - export GITLAB_SHELL_VERSION=$(<GITLAB_SHELL_VERSION) - export GITALY_VERSION=$(<GITALY_SERVER_VERSION) diff --git a/.gitlab/ci/review.gitlab-ci.yml b/.gitlab/ci/review.gitlab-ci.yml index 35df4de6513..0838de602f3 100644 --- a/.gitlab/ci/review.gitlab-ci.yml +++ b/.gitlab/ci/review.gitlab-ci.yml @@ -6,7 +6,7 @@ review-cleanup: stage: prepare environment: name: review/regular-cleanup - action: stop + action: access before_script: - source scripts/utils.sh - source scripts/review_apps/gcp_cleanup.sh diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml index 29c02c5e5bf..04afb98ddf8 100644 --- a/.gitlab/ci/rules.gitlab-ci.yml +++ b/.gitlab/ci/rules.gitlab-ci.yml @@ -688,8 +688,14 @@ - <<: *if-dot-com-gitlab-org-and-security-merge-request changes: *code-qa-patterns - <<: *if-auto-deploy-branches + variables: + ARCH: amd64,arm64 - <<: *if-default-branch-or-tag + variables: + ARCH: amd64,arm64 - <<: *if-dot-com-gitlab-org-schedule + variables: + ARCH: amd64,arm64 - <<: *if-force-ci - <<: *if-ruby3-branch @@ -2016,6 +2022,8 @@ rules: - <<: *if-default-branch-or-tag allow_failure: true + - <<: *if-schedule-maintenance + allow_failure: true - <<: *if-auto-deploy-branches allow_failure: true - when: manual diff --git a/.rubocop_todo/layout/line_length.yml b/.rubocop_todo/layout/line_length.yml index b5fc199c0ca..919d025b10e 100644 --- a/.rubocop_todo/layout/line_length.yml +++ b/.rubocop_todo/layout/line_length.yml @@ -3717,7 +3717,6 @@ Layout/LineLength: - 'rubocop/cop/rspec/top_level_describe_path.rb' - 'rubocop/cop/usage_data/large_table.rb' - 'scripts/api/cancel_pipeline.rb' - - 'scripts/api/download_job_artifact.rb' - 'scripts/api/get_job_id.rb' - 'scripts/changed-feature-flags' - 'scripts/failed_tests.rb' diff --git a/.rubocop_todo/performance/method_object_as_block.yml b/.rubocop_todo/performance/method_object_as_block.yml index acb1e2d621b..b28f56babfd 100644 --- a/.rubocop_todo/performance/method_object_as_block.yml +++ b/.rubocop_todo/performance/method_object_as_block.yml @@ -81,7 +81,6 @@ Performance/MethodObjectAsBlock: - 'rubocop/cop/avoid_return_from_blocks.rb' - 'rubocop/cop/gitlab/mark_used_feature_flags.rb' - 'rubocop/rubocop.rb' - - 'scripts/api/download_job_artifact.rb' - 'spec/graphql/resolvers/concerns/caching_array_resolver_spec.rb' - 'spec/lib/api/entities/merge_request_basic_spec.rb' - 'spec/lib/gitlab/import_export/import_test_coverage_spec.rb' diff --git a/app/models/group.rb b/app/models/group.rb index 098116ed800..edbc8825663 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -550,6 +550,11 @@ class Group < Namespace members_with_parents.pluck(Arel.sql('DISTINCT members.user_id')) end + def self_and_hierarchy_intersecting_with_user_groups(user) + user_groups = GroupsFinder.new(user).execute.unscope(:order) + self_and_hierarchy.unscope(:order).where(id: user_groups) + end + def self_and_ancestors_ids strong_memoize(:self_and_ancestors_ids) do self_and_ancestors.pluck(:id) diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 735c0df1529..9b7c14c6a0e 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -121,6 +121,7 @@ class MergeRequest < ApplicationRecord has_many :draft_notes has_many :reviews, inverse_of: :merge_request + has_many :reviewed_by_users, -> { distinct }, through: :reviews, source: :author has_many :created_environments, class_name: 'Environment', foreign_key: :merge_request_id, inverse_of: :merge_request KNOWN_MERGE_PARAMS = [ diff --git a/app/uploaders/packages/composer/cache_uploader.rb b/app/uploaders/packages/composer/cache_uploader.rb index f8052ec4810..ad7c017c4ba 100644 --- a/app/uploaders/packages/composer/cache_uploader.rb +++ b/app/uploaders/packages/composer/cache_uploader.rb @@ -4,8 +4,6 @@ class Packages::Composer::CacheUploader < GitlabUploader storage_options Gitlab.config.packages - after :store, :schedule_background_upload - alias_method :upload, :model def filename diff --git a/app/uploaders/packages/debian/component_file_uploader.rb b/app/uploaders/packages/debian/component_file_uploader.rb index e4d637fecac..2de4743d7f7 100644 --- a/app/uploaders/packages/debian/component_file_uploader.rb +++ b/app/uploaders/packages/debian/component_file_uploader.rb @@ -5,8 +5,6 @@ class Packages::Debian::ComponentFileUploader < GitlabUploader storage_options Gitlab.config.packages - after :store, :schedule_background_upload - alias_method :upload, :model def filename diff --git a/app/uploaders/packages/debian/distribution_release_file_uploader.rb b/app/uploaders/packages/debian/distribution_release_file_uploader.rb index a6ff3767b22..268d42796e9 100644 --- a/app/uploaders/packages/debian/distribution_release_file_uploader.rb +++ b/app/uploaders/packages/debian/distribution_release_file_uploader.rb @@ -5,8 +5,6 @@ class Packages::Debian::DistributionReleaseFileUploader < GitlabUploader storage_options Gitlab.config.packages - after :store, :schedule_background_upload - alias_method :upload, :model def filename diff --git a/app/uploaders/packages/package_file_uploader.rb b/app/uploaders/packages/package_file_uploader.rb index 9c0a88c9bf8..c8a09c50dc6 100644 --- a/app/uploaders/packages/package_file_uploader.rb +++ b/app/uploaders/packages/package_file_uploader.rb @@ -5,8 +5,6 @@ class Packages::PackageFileUploader < GitlabUploader storage_options Gitlab.config.packages - after :store, :schedule_background_upload - alias_method :upload, :model def filename diff --git a/app/uploaders/packages/rpm/repository_file_uploader.rb b/app/uploaders/packages/rpm/repository_file_uploader.rb index ff7e2bc719a..f95f861585c 100644 --- a/app/uploaders/packages/rpm/repository_file_uploader.rb +++ b/app/uploaders/packages/rpm/repository_file_uploader.rb @@ -6,8 +6,6 @@ module Packages storage_options Gitlab.config.packages - after :store, :schedule_background_upload - alias_method :upload, :model def filename diff --git a/data/whats_new/202211220001_15_06.yml b/data/whats_new/202211220001_15_06.yml new file mode 100644 index 00000000000..b20f72c6149 --- /dev/null +++ b/data/whats_new/202211220001_15_06.yml @@ -0,0 +1,87 @@ +- name: "Group and subgroup-level scan result policies" + description: | + GitLab now supports managing scan result policies at both the group and subgroup levels. + These policies automatically flow down and apply to all projects inside the group. This + makes it considerably easier to enforce these policies uniformly for large organizations + that have large numbers of projects. To get started, have a group or subgroup Owner link + an associated security policy project on the **Security & Compliance > Policies** page. + stage: Govern + self-managed: true + gitlab-com: true + available_in: [Ultimate] + documentation_link: 'https://docs.gitlab.com/ee/user/application_security/policies/scan-result-policies.html' + image_url: 'https://www.youtube-nocookie.com/embed/jfbNo5IE-2s' + published_at: 2022-11-22 + release: 15.6 +- name: "Git abuse rate limiting" + description: | + In GitLab 15.6, we're introducing [Git abuse rate limiting](https://docs.gitlab.com/ee/user/group/reporting/git_abuse_rate_limit.html). + Enable this feature to automatically notify administrators when a user downloads + or clones more than a specified number of repositories in a group or any of its + subgroups within a given time frame. + + You can also automatically ban users who exceed the rate limit. + Banned users cannot access the main group or any of its non-public subgroups. + Access to unrelated groups is unaffected. Bans are permanent by default, but + group administrators can always unban a banned user. + stage: anti-abuse + self-managed: true + gitlab-com: false + available_in: [Ultimate] + documentation_link: 'https://docs.gitlab.com/ee/user/group/reporting/git_abuse_rate_limit.html' + image_url: 'https://about.gitlab.com/images/15_6/git-abuse-rate-limiting.png' + published_at: 2022-11-22 + release: 15.6 +- name: "DAST API analyzer for on-demand DAST API scans" + description: | + With GitLab 15.6, the DAST API analyzer is now being used for GitLab on-demand DAST API scans. + In previous versions of GitLab, the analyzer used in these on-demand scans was our legacy DAST + analyzer. Our internal benchmarking shows that our DAST API analyzer finds more vulnerabilities, + with a lower false-positive rate than our legacy analyzer. The DAST API analyzer also introduces + new functionality such as GraphQL scans, support for authentication tokens that expire, scans using + Postman collections, and scans using HAR files. With the switch to the DAST API analyzer, some of + that functionality is already available in the on-demand site profile. + + In addition to using an OpenAPI specification in the site profile to define an API test, you can now + use a Postman collection or HAR file to make sure that your test gets the API coverage that you expect. + Also, we've added basic authentication as an option for on-demand API scans, adding to the previous + functionality of using token authentication in authorization headers. + + Next, we will be working next on adding GraphQL support for on-demand API scans. Look for more improvements + over the next few releases as we incorporate more of the advanced functionality of the DAST API analyzer. + stage: secure + self-managed: true + gitlab-com: true + available_in: [Ultimate] + documentation_link: 'https://docs.gitlab.com/ee/user/application_security/dast_api/' + image_url: 'https://about.gitlab.com/images/15_6/on_demand_api_security.png' + published_at: 2022-11-22 + release: 15.6 +- name: "Support for special characters in CI/CD variables" + description: | + Previously, it was difficult to use the $ character in a CI/CD variable because $ normally signifies the + start of another variable. GitLab would interpret it as a variable and try to expand it. In this release, + we are introducing the variable: expand: keyword which will allow you to mark a variable as “raw”. A raw + variable can contain any special characters and is not expanded when passed to the GitLab runner. + stage: verify + self-managed: true + gitlab-com: true + available_in: [Free, Premium, Ultimate] + documentation_link: 'https://docs.gitlab.com/ee/ci/yaml/#variablesexpand' + image_url: 'https://about.gitlab.com/images/15_6/special_character_support.png' + published_at: 2022-11-22 + release: 15.6 +- name: "CI/CD variable support in rules:exists configuration" + description: | + The more complex your .gitlab-ci.yml configuration is, the more difficult it is to maintain and scale. By + adding support for CI/CD variables with the rules: exists keyword, you can now use variables for paths + or filenames. Having a single source of truth by storing frequently used values in variables ensures + consistent behavior and makes your configuration easier to manage. + stage: verify + self-managed: true + gitlab-com: true + available_in: [Free, Premium, Ultimate] + documentation_link: 'https://docs.gitlab.com/ee/ci/yaml/#rulesexists' + image_url: 'https://about.gitlab.com/images/15_6/variable_support_rule_exists.png' + published_at: 2022-11-22 + release: 15.6 diff --git a/doc/administration/pages/index.md b/doc/administration/pages/index.md index 3d31491a9d2..a25385d3328 100644 --- a/doc/administration/pages/index.md +++ b/doc/administration/pages/index.md @@ -247,20 +247,20 @@ control over how the Pages daemon runs and serves content in your environment. | `enable` | Enable or disable GitLab Pages on the current system. | | `external_http` | Configure Pages to bind to one or more secondary IP addresses, serving HTTP requests. Multiple addresses can be given as an array, along with exact ports, for example `['1.2.3.4', '1.2.3.5:8063']`. Sets value for `listen_http`. | | `external_https` | Configure Pages to bind to one or more secondary IP addresses, serving HTTPS requests. Multiple addresses can be given as an array, along with exact ports, for example `['1.2.3.4', '1.2.3.5:8063']`. Sets value for `listen_https`. | -| `server_shutdown_timeout` | GitLab Pages server shutdown timeout in seconds (default: 30s). | -| `gitlab_client_http_timeout` | GitLab API HTTP client connection timeout in seconds (default: 10s). | -| `gitlab_client_jwt_expiry` | JWT Token expiry time in seconds (default: 30s). | -| `gitlab_cache_expiry` | The maximum time a domain's configuration is stored in the cache (default: 600s). | -| `gitlab_cache_refresh` | The interval at which a domain's configuration is set to be due to refresh (default: 60s). | -| `gitlab_cache_cleanup` | The interval at which expired items are removed from the cache (default: 60s). | -| `gitlab_retrieval_timeout` | The maximum time to wait for a response from the GitLab API per request (default: 30s). | -| `gitlab_retrieval_interval` | The interval to wait before retrying to resolve a domain's configuration via the GitLab API (default: 1s). | +| `server_shutdown_timeout` | GitLab Pages server shutdown timeout in seconds (default: 30 s). | +| `gitlab_client_http_timeout` | GitLab API HTTP client connection timeout in seconds (default: 10 s). | +| `gitlab_client_jwt_expiry` | JWT Token expiry time in seconds (default: 30 s). | +| `gitlab_cache_expiry` | The maximum time a domain's configuration is stored in the cache (default: 600 s). | +| `gitlab_cache_refresh` | The interval at which a domain's configuration is set to be due to refresh (default: 60 s). | +| `gitlab_cache_cleanup` | The interval at which expired items are removed from the cache (default: 60 s). | +| `gitlab_retrieval_timeout` | The maximum time to wait for a response from the GitLab API per request (default: 30 s). | +| `gitlab_retrieval_interval` | The interval to wait before retrying to resolve a domain's configuration via the GitLab API (default: 1 s). | | `gitlab_retrieval_retries` | The maximum number of times to retry to resolve a domain's configuration via the API (default: 3). | | `domain_config_source` | This parameter was removed in 14.0, on earlier versions it can be used to enable and test API domain configuration source | | `gitlab_id` | The OAuth application public ID. Leave blank to automatically fill when Pages authenticates with GitLab. | | `gitlab_secret` | The OAuth application secret. Leave blank to automatically fill when Pages authenticates with GitLab. | | `auth_scope` | The OAuth application scope to use for authentication. Must match GitLab Pages OAuth application settings. Leave blank to use `api` scope by default. | -| `auth_cookie_session_timeout` | Authentication cookie session timeout in seconds (default: 600s). A value of `0` means the cookie is deleted after the browser session ends. | +| `auth_cookie_session_timeout` | Authentication cookie session timeout in seconds (default: 600 s). A value of `0` means the cookie is deleted after the browser session ends. | | `gitlab_server` | Server to use for authentication when access control is enabled; defaults to GitLab `external_url`. | | `headers` | Specify any additional http headers that should be sent to the client with each response. Multiple headers can be given as an array, header and value as one string, for example `['my-header: myvalue', 'my-other-header: my-other-value']` | | `enable_disk` | Allows the GitLab Pages daemon to serve content from disk. Shall be disabled if shared disk storage isn't available. | @@ -540,22 +540,22 @@ archive. You can modify the cache behavior by changing the following configurati | Setting | Description | | ------- | ----------- | -| `zip_cache_expiration` | The cache expiration interval of ZIP archives. Must be greater than zero to avoid serving stale content. Default is 60s. | -| `zip_cache_cleanup` | The interval at which archives are cleaned from memory if they have already expired. Default is 30s. | -| `zip_cache_refresh` | The time interval in which an archive is extended in memory if accessed before `zip_cache_expiration`. This works together with `zip_cache_expiration` to determine if an archive is extended in memory. See the [example below](#zip-cache-refresh-example) for important details. Default is 30s. | -| `zip_open_timeout` | The maximum time allowed to open a ZIP archive. Increase this time for big archives or slow network connections, as doing so may affect the latency of serving Pages. Default is 30s. | -| `zip_http_client_timeout` | The maximum time for the ZIP HTTP client. Default is 30m. | +| `zip_cache_expiration` | The cache expiration interval of ZIP archives. Must be greater than zero to avoid serving stale content. Default is 60 s. | +| `zip_cache_cleanup` | The interval at which archives are cleaned from memory if they have already expired. Default is 30 s. | +| `zip_cache_refresh` | The time interval in which an archive is extended in memory if accessed before `zip_cache_expiration`. This works together with `zip_cache_expiration` to determine if an archive is extended in memory. See the [example below](#zip-cache-refresh-example) for important details. Default is 30 s. | +| `zip_open_timeout` | The maximum time allowed to open a ZIP archive. Increase this time for big archives or slow network connections, as doing so may affect the latency of serving Pages. Default is 30 s. | +| `zip_http_client_timeout` | The maximum time for the ZIP HTTP client. Default is 30 m. | #### ZIP cache refresh example Archives are refreshed in the cache (extending the time they are held in memory) if they're accessed before `zip_cache_expiration`, and the time left before expiring is less than or equal to -`zip_cache_refresh`. For example, if `archive.zip` is accessed at time 0s, it expires in 60s (the -default for `zip_cache_expiration`). In the example below, if the archive is opened again after 15s -it is **not** refreshed because the time left for expiry (45s) is greater than `zip_cache_refresh` -(default 30s). However, if the archive is accessed again after 45s (from the first time it was +`zip_cache_refresh`. For example, if `archive.zip` is accessed at time 0 s, it expires in 60 s (the +default for `zip_cache_expiration`). In the example below, if the archive is opened again after 15 s +it is **not** refreshed because the time left for expiry (45 s) is greater than `zip_cache_refresh` +(default 30 s). However, if the archive is accessed again after 45 s (from the first time it was opened) it's refreshed. This extends the time the archive remains in memory from -`45s + zip_cache_expiration (60s)`, for a total of 105s. +`45s + zip_cache_expiration (60s)`, for a total of 105 s. After an archive reaches `zip_cache_expiration`, it's marked as expired and removed on the next `zip_cache_cleanup` interval. diff --git a/doc/administration/reference_architectures/25k_users.md b/doc/administration/reference_architectures/25k_users.md index 84eba01fe11..f90e9443aa1 100644 --- a/doc/administration/reference_architectures/25k_users.md +++ b/doc/administration/reference_architectures/25k_users.md @@ -2362,7 +2362,7 @@ services where applicable): | Consul<sup>1</sup> | 3 | 2 vCPU, 1.8 GB memory | `n1-highcpu-2` | `c5.large` | | PostgreSQL<sup>1</sup> | 3 | 16 vCPU, 60 GB memory | `n1-standard-16` | `m5.4xlarge` | | PgBouncer<sup>1</sup> | 3 | 2 vCPU, 1.8 GB memory | `n1-highcpu-2` | `c5.large` | -| Internal load balancing node<sup>3</sup> | 1 | 4 vCPU, 3.6GB memory | `n1-highcpu-4` | `c5.xlarge` | +| Internal load balancing node<sup>3</sup> | 1 | 4 vCPU, 3.6 GB memory | `n1-highcpu-4` | `c5.xlarge` | | Redis/Sentinel - Cache<sup>2</sup> | 3 | 4 vCPU, 15 GB memory | `n1-standard-4` | `m5.xlarge` | | Redis/Sentinel - Persistent<sup>2</sup> | 3 | 4 vCPU, 15 GB memory | `n1-standard-4` | `m5.xlarge` | | Gitaly<sup>5 6</sup> | 3 | 32 vCPU, 120 GB memory | `n1-standard-32` | `m5.8xlarge` | diff --git a/doc/administration/reference_architectures/index.md b/doc/administration/reference_architectures/index.md index 467cc332e25..9ce87df534a 100644 --- a/doc/administration/reference_architectures/index.md +++ b/doc/administration/reference_architectures/index.md @@ -216,7 +216,7 @@ Due to performance issues that we found with several key Azure services, we only In addition to the above, you should be aware of the additional specific guidance for Azure: - **We outright strongly do not recommend [Azure Database for PostgreSQL Single Server](https://learn.microsoft.com/en-us/azure/postgresql/single-server/overview-single-server)** specifically due to significant performance and stability issues found. **For GitLab 14.0 and higher the service is not supported** due to it only supporting up to PostgreSQL 11. - - A new service, [Azure Database for Postgres Flexible Server](https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/) has been released but due to it missing some functionality we don't recommend it at this time. + - A new service, [Azure Database for PostgreSQL Flexible Server](https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/) has been released but due to it missing some functionality we don't recommend it at this time. - [Azure Blob Storage](https://azure.microsoft.com/en-gb/products/storage/blobs/) has been found to have performance limits that can impact production use at certain times. However, this has only been seen in larger architectures. ## Validation and test results @@ -240,11 +240,11 @@ Testing occurs against all reference architectures and cloud providers in an aut - The [GitLab Environment Toolkit](https://gitlab.com/gitlab-org/gitlab-environment-toolkit) for building the environments. - The [GitLab Performance Tool](https://gitlab.com/gitlab-org/quality/performance) for performance testing. -Network latency on the test environments between components on all Cloud Providers were measured at <5ms. Note that this is shared as an observation and not as an implicit recommendation. +Network latency on the test environments between components on all Cloud Providers were measured at <5 ms. Note that this is shared as an observation and not as an implicit recommendation. We aim to have a "test smart" approach where architectures tested have a good range that can also apply to others. Testing focuses on 10k Omnibus on GCP as the testing has shown this is a good bellwether for the other architectures and cloud providers as well as Cloud Native Hybrids. -The Standard Reference Architectures are designed to be platform-agnostic, with everything being run on VMs via [Omnibus GitLab](https://docs.gitlab.com/omnibus/). While testing occurs primarily on GCP, ad-hoc testing has shown that they perform similarly on equivalently specced hardware on other Cloud Providers or if run on premises (bare-metal). +The Standard Reference Architectures are designed to be platform-agnostic, with everything being run on VMs via [Omnibus GitLab](https://docs.gitlab.com/omnibus/). While testing occurs primarily on GCP, ad-hoc testing has shown that they perform similarly on hardware with equivalent specs on other Cloud Providers or if run on premises (bare-metal). Testing on these reference architectures is performed with the [GitLab Performance Tool](https://gitlab.com/gitlab-org/quality/performance) diff --git a/doc/administration/sidekiq/sidekiq_troubleshooting.md b/doc/administration/sidekiq/sidekiq_troubleshooting.md index d2afe171e9c..b261e385949 100644 --- a/doc/administration/sidekiq/sidekiq_troubleshooting.md +++ b/doc/administration/sidekiq/sidekiq_troubleshooting.md @@ -56,6 +56,120 @@ gitlab_rails['env'] = {"SIDEKIQ_LOG_ARGUMENTS" => "0"} In GitLab 13.5 and earlier, set `SIDEKIQ_LOG_ARGUMENTS` to `1` to start logging arguments passed to Sidekiq. +## Investigating Sidekiq queue backlogs or slow performance + +Symptoms of slow Sidekiq performance include problems with merge request status updates, +and delays before CI pipelines start running. + +Potential causes include: + +- The GitLab instance may need more Sidekiq workers. By default, a single-node Omnibus GitLab + runs one worker, restricting the execution of Sidekiq jobs to a maximum of one CPU core. + [Read more about running multiple Sidekiq workers](extra_sidekiq_processes.md). + +- The instance is configured with more Sidekiq workers, but most of the extra workers are + not configured to run any job that is queued. This can result in a backlog of jobs + when the instance is busy, if the workload has changed in the months or years since + the workers were configured, or as a result of GitLab product changes. + +Gather data on the state of the Sidekiq workers with the following Ruby script. + +1. Create the script: + + ```ruby + cat > /var/opt/gitlab/sidekiqcheck.rb <<EOF + require 'sidekiq/monitor' + Sidekiq::Monitor::Status.new.display('overview') + Sidekiq::Monitor::Status.new.display('processes'); nil + Sidekiq::Monitor::Status.new.display('queues'); nil + puts "----------- workers ----------- " + workers = Sidekiq::Workers.new + workers.each do |_process_id, _thread_id, work| + pp work + end + puts "----------- Queued Jobs ----------- " + Sidekiq::Queue.all.each do |queue| + queue.each do |job| + pp job + end + end ;nil + puts "----------- done! ----------- " + EOF + ``` + +1. Execute and capture the output: + + ```shell + sudo gitlab-rails runner /var/opt/gitlab/sidekiqcheck.rb > /tmp/sidekiqcheck_$(date '+%Y%m%d-%H:%M').out + ``` + + If the performance issue is intermittent: + + - Run this in a cron job every five minutes. Write the files to a location with enough space: allow for 500KB per file. + - Refer back to the data to see what went wrong. + +1. Analyze the output. The following commands assume that you have a directory of output files. + + 1. `grep 'Busy: ' *` shows how many jobs were being run. `grep 'Enqueued: ' *` + shows the backlog of work at that time. + + 1. Look at the number of busy threads across the workers in samples where Sidekiq is under load: + + ```shell + ls | while read f ; do if grep -q 'Enqueued: 0' $f; then : + else echo $f; egrep 'Busy:|Enqueued:|---- Processes' $f + grep 'Threads:' $f ; fi + done | more + ``` + + Example output: + + ```plaintext + sidekiqcheck_20221024-14:00.out + Busy: 47 + Enqueued: 363 + ---- Processes (13) ---- + Threads: 30 (0 busy) + Threads: 30 (0 busy) + Threads: 30 (0 busy) + Threads: 30 (0 busy) + Threads: 23 (0 busy) + Threads: 30 (0 busy) + Threads: 30 (0 busy) + Threads: 30 (0 busy) + Threads: 30 (0 busy) + Threads: 30 (0 busy) + Threads: 30 (0 busy) + Threads: 30 (24 busy) + Threads: 30 (23 busy) + ``` + + - In this output file, 47 threads were busy, and there was a backlog of 363 jobs. + - Of the 13 worker processes, only two were busy. + - This indicates that the other workers are configured too specifically. + - Look at the full output to work out which workers were busy. + Correlate with your `sidekiq_queues` configuration in `gitlab.rb`. + - An overloaded single-worker environment might look like this: + + ```plaintext + sidekiqcheck_20221024-14:00.out + Busy: 25 + Enqueued: 363 + ---- Processes (1) ---- + Threads: 25 (25 busy) + ``` + + 1. Look at the `---- Queues (xxx) ----` section of the output file to + determine what jobs were queued up at the time. + + 1. The files also include low level details about the state of Sidekiq at the time. + This could be useful for identifying where spikes in workload are coming from. + + - The `----------- workers -----------` section details the jobs that make up the + `Busy` count in the summary. + - The `----------- Queued Jobs -----------` section provides details on + jobs that are `Enqueued`. + ## Thread dump Send the Sidekiq process ID the `TTIN` signal to output thread @@ -379,3 +493,60 @@ has number of drawbacks, as mentioned in [Why Ruby's Timeout is dangerous (and T > - in any of your code, regardless of whether it could have possibly raised an exception before > > Nobody writes code to defend against an exception being raised on literally any line. That's not even possible. So Thread.raise is basically like a sneak attack on your code that could result in almost anything. It would probably be okay if it were pure-functional code that did not modify any state. But this is Ruby, so that's unlikely :) + +## Omnibus GitLab 14.0 and later: remove the `sidekiq-cluster` service + +Omnibus GitLab instances that were configured to run `sidekiq-cluster` prior to GitLab 14.0 +might still have this service running along side `sidekiq` in later releases. + +The code to manage `sidekiq-cluster` was removed in GitLab 14.0. +The configuration files remain on disk so the `sidekiq-cluster` process continues +to be started by the GitLab systemd service . + +The extra service can be identified as running by: + +- `gitlab-ctl status` showing both services: + + ```plaintext + run: sidekiq: (pid 1386) 445s; run: log: (pid 1385) 445s + run: sidekiq-cluster: (pid 1388) 445s; run: log: (pid 1381) 445s + ``` + +- `ps -ef | grep 'runsv sidekiq'` showing two processes: + + ```plaintext + root 31047 31045 0 13:54 ? 00:00:00 runsv sidekiq-cluster + root 31054 31045 0 13:54 ? 00:00:00 runsv sidekiq + ``` + +To remove the `sidekiq-cluster` service from servers running GitLab 14.0 and later: + +1. Stop GitLab and the systemd service: + + ```shell + sudo gitlab-ctl stop + sudo systemctl stop gitlab-runsvdir.service + ``` + +1. Remove the `runsv` service definition: + + ```shell + sudo rm -rf /opt/gitlab/sv/sidekiq-cluster + ``` + +1. Restart GitLab: + + ```shell + sudo systemctl start gitlab-runsvdir.service + ``` + +1. Check that all services are up, and the `sidekiq-cluster` service is not listed: + + ```shell + sudo gitlab-ctl status + ``` + +This change might reduce the amount of work Sidekiq can do. Symptoms like delays creating pipelines +indicate that additional Sidekiq processes would be beneficial. +Consider [adding additional Sidekiq processes](extra_sidekiq_processes.md) +to compensate for removing the `sidekiq-cluster` service. diff --git a/doc/administration/troubleshooting/linux_cheat_sheet.md b/doc/administration/troubleshooting/linux_cheat_sheet.md index 90cd1e24c79..ae0ef44f0b1 100644 --- a/doc/administration/troubleshooting/linux_cheat_sheet.md +++ b/doc/administration/troubleshooting/linux_cheat_sheet.md @@ -294,8 +294,8 @@ small differences should not be considered significant. |Setup | access times | |:--------------|:--------------| -| EFS | 10 - 30ms | -| Local Storage | 0.01 - 1ms | +| EFS | 10 - 30 ms | +| Local Storage | 0.01 - 1 ms | ## Networking diff --git a/doc/administration/troubleshooting/postgresql.md b/doc/administration/troubleshooting/postgresql.md index 829fed38060..6aabe9a5e3d 100644 --- a/doc/administration/troubleshooting/postgresql.md +++ b/doc/administration/troubleshooting/postgresql.md @@ -111,7 +111,7 @@ PostgresSQL defaults: Comments in issue [#30528](https://gitlab.com/gitlab-org/gitlab/-/issues/30528) indicate that these should both be set to at least a number of minutes for all -Omnibus GitLab installations (so they don't hang indefinitely). However, 15s +Omnibus GitLab installations (so they don't hang indefinitely). However, 15 s for `statement_timeout` is very short, and is only effective if the underlying infrastructure is very performant. diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 35792b3b1ad..89fdb200f08 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -16742,6 +16742,18 @@ Represents a product analytics dashboard. | <a id="productanalyticsdashboardtitle"></a>`title` | [`String!`](#string) | Title of the dashboard. | | <a id="productanalyticsdashboardwidgets"></a>`widgets` | [`ProductAnalyticsDashboardWidgetConnection!`](#productanalyticsdashboardwidgetconnection) | Widgets shown on the dashboard. (see [Connections](#connections)) | +### `ProductAnalyticsDashboardVisualization` + +Represents a product analytics dashboard visualization. + +#### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="productanalyticsdashboardvisualizationdata"></a>`data` | [`JSON!`](#json) | Data of the visualization. | +| <a id="productanalyticsdashboardvisualizationoptions"></a>`options` | [`JSON!`](#json) | Options of the visualization. | +| <a id="productanalyticsdashboardvisualizationtype"></a>`type` | [`String!`](#string) | Type of the visualization. | + ### `ProductAnalyticsDashboardWidget` Represents a product analytics dashboard widget. @@ -16752,6 +16764,7 @@ Represents a product analytics dashboard widget. | ---- | ---- | ----------- | | <a id="productanalyticsdashboardwidgetgridattributes"></a>`gridAttributes` | [`JSON`](#json) | Description of the position and size of the widget. | | <a id="productanalyticsdashboardwidgettitle"></a>`title` | [`String!`](#string) | Title of the widget. | +| <a id="productanalyticsdashboardwidgetvisualization"></a>`visualization` | [`ProductAnalyticsDashboardVisualization!`](#productanalyticsdashboardvisualization) | Visualization of the widget. | ### `Project` diff --git a/doc/architecture/blueprints/ci_data_decay/pipeline_partitioning.md b/doc/architecture/blueprints/ci_data_decay/pipeline_partitioning.md index 9987118b6bc..85bf22234b9 100644 --- a/doc/architecture/blueprints/ci_data_decay/pipeline_partitioning.md +++ b/doc/architecture/blueprints/ci_data_decay/pipeline_partitioning.md @@ -272,6 +272,37 @@ during a low traffic period([after `00:00 UTC`](https://dashboards.gitlab.net/d/ See an example of this strategy in our [partition tooling](../../../development/database/table_partitioning.md#step-6---create-parent-table-and-attach-existing-table-as-the-initial-partition)). +### Partitioning steps + +The database [partition tooling](../../../development/database/table_partitioning.md#partitioning-a-table-list) +docs contain a list of steps to partition a table, but the steps are not enough +for our iterative strategy. As our dataset continues to grow we want to take +advantage of partitioning performance right away and not wait until all tables +are partitioned. For example, after partitioning the `ci_builds_metadata` table +we want to start writing and reading data to/from a new partition. This means +that we will increase the `partition_id` value from `100`, the default value, +to `101`. Now all of the new resources for the pipeline hierarchy will be +persisted with `partition_id = 101`. We can continue following the database +tooling instructions for the next table that will be partitioned, but we require +a few extra steps: + +- add `partition_id` column for the FK references with default value of `100` + since the majority of records should have that value. +- change application logic to cascade the `partition_id` value +- correct partition_id values for recent records with a post deploy/background + migration, similar to this: + + ```sql + UPDATE ci_pipeline_metadata + SET partition_id = ci_pipelines.partition_id + FROM ci_pipelines + WHERE ci_pipelines.id = ci_pipeline_metadata.pipeline_id + AND ci_pipelines.partition_id in (101, 102); + ``` + +- change the foreign key definitions +- ... + ## Storing partitions metadata in the database To build an efficient mechanism that will be responsible for creating diff --git a/doc/development/documentation/styleguide/word_list.md b/doc/development/documentation/styleguide/word_list.md index ed1c668a7a6..1f58d5252e1 100644 --- a/doc/development/documentation/styleguide/word_list.md +++ b/doc/development/documentation/styleguide/word_list.md @@ -745,6 +745,11 @@ For **MB** and **GB**, follow the [Microsoft guidance](https://learn.microsoft.c Do not use first-person singular. Use **you**, **we**, or **us** instead. ([Vale](../testing.md#vale) rule: [`FirstPerson.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/FirstPerson.yml)) +## member + +When you add a [user account](#user-account) to a group or project, +the user account becomes a **member**. + ## merge requests Use lowercase for **merge requests**. If you use **MR** as the acronym, spell it out on first use. @@ -1225,18 +1230,10 @@ See also [downgrade](#downgrade) and [roll back](#roll-back). Do not use **useful**. If the user doesn't find the process to be useful, we lose their trust. ([Vale](../testing.md#vale) rule: [`Simplicity.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/Simplicity.yml)) -## user, users - -When possible, address the reader directly, instead of calling them **users**. -Use the [second person](#you-your-yours), **you**, instead. - -Use: - -- You can configure a pipeline. +## user account -Instead of: - -- Users can configure a pipeline. +You create a **user account**. The user account has an [access level](#access-level). +When you add a **user account** to a group or project, the user account becomes a **member**. ## utilize @@ -1297,7 +1294,7 @@ in present tense, active voice. ## you, your, yours -Use **you**, **your**, and **yours** instead of [**the user** and **the user's**](#user-users). +Use **you**, **your**, and **yours** instead of **the user** and **the user's**. Documentation should be from the [point of view](https://design.gitlab.com/content/voice-tone/#point-of-view) of the reader. Use: diff --git a/doc/development/project_templates.md b/doc/development/project_templates.md index 2f1ded23e38..50d0bfd3c62 100644 --- a/doc/development/project_templates.md +++ b/doc/development/project_templates.md @@ -4,7 +4,9 @@ group: Workspace 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" --- -# Contribute a built-in project template +# Contribute to built-in project templates + +## Adding a new built-in project template This page provides instructions about how to contribute a [built-in project template](../user/project/working_with_projects.md#create-a-project-from-a-built-in-template). @@ -20,7 +22,7 @@ You can contribute the following types of project templates: - Enterprise: For users with GitLab Premium and above. - Non-enterprise: For users with GitLab Free and above. -## Prerequisites +### Prerequisites To add or update an existing template, you must have the following tools installed: @@ -28,22 +30,22 @@ installed: - `wget` - `tar` -## Create a project template for review +### Create a project template for review 1. In your selected namespace, create a public project. 1. Add the project content you want to use in the template. Do not include unnecessary assets or dependencies. For an example, [see this project](https://gitlab.com/gitlab-org/project-templates/dotnetcore). 1. When the project is ready for review, [create an issue](https://gitlab.com/gitlab-org/gitlab/issues) with a link to your project. - In your issue, mention the relevant [Backend Engineering Manager and Product Manager](https://about.gitlab.com/handbook/product/categories/#source-code-group) + In your issue, mention the Create:Source Code [Backend Engineering Manager and Product Manager](https://about.gitlab.com/handbook/product/categories/#source-code-group) for the Templates feature. -## Add the template SVG icon to GitLab SVGs +### Add the template SVG icon to GitLab SVGs If the project template has an SVG icon, you must add it to the [GitLab SVGs project](https://gitlab.com/gitlab-org/gitlab-svgs/-/blob/main/README.md#adding-icons-or-illustrations) before you can create a merge request with vendor details. -## Create a merge request with vendor details +### Create a merge request with vendor details Before GitLab can implement the project template, you must [create a merge request](../user/project/merge_requests/creating_merge_requests.md) in [`gitlab-org/gitlab`](https://gitlab.com/gitlab-org/gitlab) that includes vendor details about the project. @@ -111,7 +113,7 @@ Before GitLab can implement the project template, you must [create a merge reque 1. After you run the scripts, there is one new file in `vendor/project_templates/` and four changed files. Commit all changes and push your branch to update the merge request. For an example, see this [merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25318). -## Test your built-in project with the GitLab Development Kit +### Test your built-in project with the GitLab Development Kit Complete the following steps to test the project template in your own GitLab Development Kit instance: @@ -124,9 +126,15 @@ Complete the following steps to test the project template in your own GitLab Dev ## Contribute an improvement to an existing template -To update an existing built-in project template: +To update an existing built-in project template, changes are usually made to the existing template, found in the [project-templates](https://gitlab.com/gitlab-org/project-templates) group. A merge request is made directly against the template and the Create:Source Code [Backend Engineering Manager and Product Manager](https://about.gitlab.com/handbook/product/categories/#source-code-group) pinged for review. + +Sometimes it is necessary to completely replace the template files. In this case the process would be: 1. Create a merge request in the relevant project of the `project-templates` and `pages` group and mention `@gitlab-org/manage/import/backend` when you are ready for a review. 1. If your merge request is accepted, either: - [Create an issue](https://gitlab.com/gitlab-org/gitlab/-/issues) to ask for the template to get updated. - [Create a merge request with vendor details](#create-a-merge-request-with-vendor-details) to update the template. + +## For GitLab team members + +Please ensure the merge request has been reviewed by the Security Counterpart before merging. diff --git a/doc/update/index.md b/doc/update/index.md index 31df17c4138..dd743daf13e 100644 --- a/doc/update/index.md +++ b/doc/update/index.md @@ -384,7 +384,7 @@ Find where your version sits in the upgrade path below, and upgrade GitLab accordingly, while also consulting the [version-specific upgrade instructions](#version-specific-upgrading-instructions): -`8.11.Z` -> `8.12.0` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> [`11.11.8`](#1200) -> `12.0.12` -> [`12.1.17`](#1210) -> [`12.10.14`](#12100) -> `13.0.14` -> [`13.1.11`](#1310) -> [`13.8.8`](#1388) -> [`13.12.15`](#13120) -> [`14.0.12`](#1400) -> [`14.3.6`](#1430) -> [`14.9.5`](#1490) -> [`14.10.Z`](#14100) -> [`15.0.Z`](#1500) -> [`15.1.Z`](#1510) (for GitLab instances with multiple web nodes) -> [`15.4.0`](#1540) -> [latest `15.Y.Z`](https://gitlab.com/gitlab-org/gitlab/-/releases) +`8.11.Z` -> `8.12.0` -> `8.17.7` -> `9.0.13` -> `9.5.10` -> `10.0.7` -> `10.8.7` -> `11.0.6` -> [`11.11.8`](#1200) -> `12.0.12` -> [`12.1.17`](#1210) -> [`12.10.14`](#12100) -> `13.0.14` -> [`13.1.11`](#1310) -> [`13.8.8`](#1388) -> [`13.12.15`](#13120) -> [`14.0.12`](#1400) -> [`14.3.6`](#1430) -> [`14.9.5`](#1490) -> [`14.10.Z`](#14100) -> [`15.0.Z`](#1500) -> [`15.1.Z`](#1510) (for GitLab instances with multiple web nodes) -> [`15.4.0`](#1540) -> [latest `15.Y.Z`](https://gitlab.com/gitlab-org/gitlab/-/releases) NOTE: When not explicitly specified, upgrade GitLab to the latest available patch @@ -398,18 +398,18 @@ The following table, while not exhaustive, shows some examples of the supported upgrade paths. Additional steps between the mentioned versions are possible. We list the minimally necessary steps only. -| Target version | Your version | Supported upgrade path | Note | -| -------------- | ------------ | ---------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | -| `15.1.0` | `14.6.2` | `14.6.2` -> `14.9.5` -> `14.10.5` -> `15.0.2` -> `15.1.0` | Three intermediate versions are required: `14.9` and `14.10`, `15.0`, then `15.1.0`. | -| `15.0.0` | `14.6.2` | `14.6.2` -> `14.9.5` -> `14.10.5` -> `15.0.2` | Two intermediate versions are required: `14.9` and `14.10`, then `15.0.0`. | -| `14.6.2` | `13.10.2` | `13.10.2` -> `13.12.15` -> `14.0.12` -> `14.3.6` => `14.6.2` | Three intermediate versions are required: `13.12` and `14.0`, `14.3`, then `14.6.2`. | -| `14.1.8` | `13.9.2` | `13.9.2` -> `13.12.15` -> `14.0.12` -> `14.1.8` | Two intermediate versions are required: `13.12` and `14.0`, then `14.1.8`. | -| `13.12.15` | `12.9.2` | `12.9.2` -> `12.10.14` -> `13.0.14` -> `13.1.11` -> `13.8.8` -> `13.12.15` | Four intermediate versions are required: `12.10`, `13.0`, `13.1` and `13.8.8`, then `13.12.15`. | -| `13.2.10` | `11.5.0` | `11.5.0` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` -> `13.0.14` -> `13.1.11` -> `13.2.10` | Six intermediate versions are required: `11.11`, `12.0`, `12.1`, `12.10`, `13.0` and `13.1`, then `13.2.10`. | -| `12.10.14` | `11.3.4` | `11.3.4` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` | Three intermediate versions are required: `11.11`, `12.0` and `12.1`, then `12.10.14`. | -| `12.9.5` | `10.4.5` | `10.4.5` -> `10.8.7` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.9.5` | Four intermediate versions are required: `10.8`, `11.11`, `12.0` and `12.1`, then `12.9.5`. | -| `12.2.5` | `9.2.6` | `9.2.6` -> `9.5.10` -> `10.8.7` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.2.5` | Five intermediate versions are required: `9.5`, `10.8`, `11.11`, `12.0`, and `12.1`, then `12.2.5`. | -| `11.3.4` | `8.13.4` | `8.13.4` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> `11.3.4` | `8.17.7` is the last version in version 8, `9.5.10` is the last version in version 9, `10.8.7` is the last version in version 10. | +| Target version | Your version | Supported upgrade path | Note | +| -------------- | ------------ | ---------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| `15.1.0` | `14.6.2` | `14.6.2` -> `14.9.5` -> `14.10.5` -> `15.0.2` -> `15.1.0` | Three intermediate versions are required: `14.9`, `14.10`, and `15.0`. | +| `15.0.0` | `14.6.2` | `14.6.2` -> `14.9.5` -> `14.10.5` -> `15.0.2` | Two intermediate versions are required: `14.9` and `14.10`. | +| `14.6.2` | `13.10.2` | `13.10.2` -> `13.12.15` -> `14.0.12` -> `14.3.6` => `14.6.2` | Three intermediate versions are required: `13.12`, `14.0`, and `14.3`. | +| `14.1.8` | `13.9.2` | `13.9.2` -> `13.12.15` -> `14.0.12` -> `14.1.8` | Two intermediate versions are required: `13.12` and `14.0`. | +| `13.12.15` | `12.9.2` | `12.9.2` -> `12.10.14` -> `13.0.14` -> `13.1.11` -> `13.8.8` -> `13.12.15` | Four intermediate versions are required: `12.10`, `13.0`, `13.1`, and `13.8`. | +| `13.2.10` | `11.5.0` | `11.5.0` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` -> `13.0.14` -> `13.1.11` -> `13.2.10` | Six intermediate versions are required: `11.11`, `12.0`, `12.1`, `12.10`, `13.0`, and `13.1`. | +| `12.10.14` | `11.3.4` | `11.3.4` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` | Three intermediate versions are required: `11.11`, `12.0`, and `12.1`. | +| `12.9.5` | `10.4.5` | `10.4.5` -> `10.8.7` -> `11.0.6` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.9.5` | Five intermediate versions are required: `10.8`, `11.0`, `11.11`, `12.0`, and `12.1`. | +| `12.2.5` | `9.2.6` | `9.2.6` -> `9.5.10` -> `10.0.7` -> `10.8.7` -> `11.0.6` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.2.5` | Seven intermediate versions are required: `9.5`, `10.0`, `10.8`, `11.0`, `11.11`, `12.0`, and `12.1`. | +| `11.3.4` | `8.13.4` | `8.13.4` -> `8.17.7` -> `9.0.13` -> `9.5.10` -> `10.0.7` -> `10.8.7` -> `11.0.6` -> `11.3.4` | Six intermediate versions are required: `8.17`, `9.0`, `9.5`, `10.0`, `10.8`, and `11.0`. | ## Upgrading between editions diff --git a/doc/user/project/merge_requests/commit_templates.md b/doc/user/project/merge_requests/commit_templates.md index 75c2bdffae8..a14d8bddd24 100644 --- a/doc/user/project/merge_requests/commit_templates.md +++ b/doc/user/project/merge_requests/commit_templates.md @@ -70,6 +70,7 @@ GitLab creates a squash commit message with this template: > - [Added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75639) `url`, `approved_by`, and `merged_by` variables in GitLab 14.7. > - [Added](https://gitlab.com/gitlab-org/gitlab/-/issues/20421) `co_authored_by` variable in GitLab 14.7. > - [Added](https://gitlab.com/gitlab-org/gitlab/-/issues/26303) `all_commits` variable in GitLab 14.9. +> - [Added](https://gitlab.com/gitlab-org/gitlab/-/issues/378352) `reviewed_by` variable in GitLab 15.7. Commit message templates support these variables: @@ -84,7 +85,8 @@ Commit message templates support these variables: | `%{first_commit}` | Full message of the first commit in merge request diff. | `Update README.md` | | `%{first_multiline_commit}` | Full message of the first commit that's not a merge commit and has more than one line in message body. Merge request title if all commits aren't multiline. | `Update README.md`<br><br>`Improved project description in readme file.` | | `%{url}` | Full URL to the merge request. | `https://gitlab.com/gitlab-org/gitlab/-/merge_requests/1` | -| `%{approved_by}` | Line-separated list of the merge request approvers. | `Approved-by: Sidney Jones <sjones@example.com>` <br> `Approved-by: Zhang Wei <zwei@example.com>` | +| `%{reviewed_by}` | Line-separated list of the merge request reviewers, based on users who submit a review via batch comments, in a `Reviewed-by` Git commit trailer format. | `Reviewed-by: Sidney Jones <sjones@example.com>` <br> `Reviewed-by: Zhang Wei <zwei@example.com>` | +| `%{approved_by}` | Line-separated list of the merge request approvers in a `Approved-by` Git commit trailer format. | `Approved-by: Sidney Jones <sjones@example.com>` <br> `Approved-by: Zhang Wei <zwei@example.com>` | | `%{merged_by}` | User who merged the merge request. | `Alex Garcia <agarcia@example.com>` | | `%{co_authored_by}` | Names and emails of commit authors in a `Co-authored-by` Git commit trailer format. Limited to authors of 100 most recent commits in merge request. | `Co-authored-by: Zane Doe <zdoe@example.com>` <br> `Co-authored-by: Blake Smith <bsmith@example.com>` | | `%{all_commits}` | Messages from all commits in the merge request. Limited to 100 most recent commits. Skips commit bodies exceeding 100KiB and merge commit messages. | `* Feature introduced` <br><br> `This commit implements feature` <br> `Changelog:added` <br><br> `* Bug fixed` <br><br> `* Documentation improved` <br><br>`This commit introduced better docs.`| diff --git a/doc/user/project/repository/gpg_signed_commits/index.md b/doc/user/project/repository/gpg_signed_commits/index.md index a1f57f51f26..61fc0b88d05 100644 --- a/doc/user/project/repository/gpg_signed_commits/index.md +++ b/doc/user/project/repository/gpg_signed_commits/index.md @@ -160,14 +160,6 @@ to use this key: git config --global user.signingkey <KEY ID> ``` -1. Optional. If Git uses `gpg` and you get errors like `secret key not available` - or `gpg: signing failed: secret key not available`, run this command to - use `gpg2` instead: - - ```shell - git config --global gpg.program gpg2 - ``` - ### Sign your Git commits After you [add your public key to your account](#add-a-gpg-key-to-your-account), @@ -269,3 +261,27 @@ or a GPG key. The verification process for both methods can fail for multiple re | `UNVERIFIED_KEY` | The key associated with the GPG signature has no verified email address associated with the committer. | Add and verify the email to your GitLab profile, [update the GPG key to include the email address](https://security.stackexchange.com/a/261468), or amend the commit to use a different committer email address. | | `UNKNOWN_KEY` | The GPG key associated with the GPG signature for this commit is unknown to GitLab. | [Add the GPG key](#add-a-gpg-key-to-your-account) to your GitLab profile. | | `MULTIPLE_SIGNATURES` | Multiple GPG or X.509 signatures have been found for the commit. | Amend the commit to use only one GPG or X.509 signature. | + +### Secret key not available + +If you receive the errors `secret key not available` +or `gpg: signing failed: secret key not available`, try using `gpg2` instead of `gpg`: + +```shell +git config --global gpg.program gpg2 +``` + +If your GPG key is password protected and the password entry prompt does not appear, +add `export GPG_TTY=$(tty)` to your shell's `rc` file (commonly `~/.bashrc` or `~/.zshrc`) + +### GPG failed to sign the data + +If your GPG key is password protected and you receive the error: + +```shell +error: gpg failed to sign the data +fatal: failed to write commit object +``` + +If the password entry prompt does not appear, add `export GPG_TTY=$(tty)` to your shell's `rc` file +(commonly `~/.bashrc` or `~/.zshrc`) and restart your terminal. diff --git a/lib/gitlab/audit/type/definition.rb b/lib/gitlab/audit/type/definition.rb index f64f66f4ca4..eb7f86bc823 100644 --- a/lib/gitlab/audit/type/definition.rb +++ b/lib/gitlab/audit/type/definition.rb @@ -59,19 +59,25 @@ module Gitlab end class << self + include ::Gitlab::Utils::StrongMemoize + def paths @paths ||= [Rails.root.join('config', 'audit_events', 'types', '*.yml')] end def definitions - # We lazily load all definitions - @definitions ||= load_all! + load_all! end + strong_memoize_attr :definitions def get(key) definitions[key.to_sym] end + def event_names + definitions.keys.map(&:to_s) + end + private def load_all! diff --git a/lib/gitlab/group_search_results.rb b/lib/gitlab/group_search_results.rb index 4eea96f8344..b112740c4ad 100644 --- a/lib/gitlab/group_search_results.rb +++ b/lib/gitlab/group_search_results.rb @@ -12,23 +12,11 @@ module Gitlab # rubocop:disable CodeReuse/ActiveRecord def users - # get all groups the current user has access to - # ignore order inherited from GroupsFinder to improve performance - current_user_groups = GroupsFinder.new(current_user).execute.unscope(:order) + groups = group.self_and_hierarchy_intersecting_with_user_groups(current_user) + members = GroupMember.where(group: groups).non_invite - # the hierarchy of the current group - group_groups = @group.self_and_hierarchy.unscope(:order) - - # the groups where the above hierarchies intersect - intersect_groups = group_groups.where(id: current_user_groups) - - # members of @group hierarchy where the user has access to the groups - members = GroupMember.where(group: intersect_groups).non_invite - - # get all users the current user has access to (-> `SearchResults#users`), which also applies the query users = super - # filter users that belong to the previously selected groups users.where(id: members.select(:user_id)) end # rubocop:enable CodeReuse/ActiveRecord diff --git a/lib/gitlab/merge_requests/commit_message_generator.rb b/lib/gitlab/merge_requests/commit_message_generator.rb index ef5c63925c2..b09e2150012 100644 --- a/lib/gitlab/merge_requests/commit_message_generator.rb +++ b/lib/gitlab/merge_requests/commit_message_generator.rb @@ -41,6 +41,7 @@ module Gitlab 'first_commit' => -> (merge_request, _, _) { merge_request.first_commit&.safe_message&.strip }, 'first_multiline_commit' => -> (merge_request, _, _) { merge_request.first_multiline_commit&.safe_message&.strip.presence || merge_request.title }, 'url' => ->(merge_request, _, _) { Gitlab::UrlBuilder.build(merge_request) }, + 'reviewed_by' => ->(merge_request, _, _) { merge_request.reviewed_by_users.map { |user| "Reviewed-by: #{user.name} <#{user.commit_email_or_default}>" }.join("\n") }, 'approved_by' => ->(merge_request, _, _) { merge_request.approved_by_users.map { |user| "Approved-by: #{user.name} <#{user.commit_email_or_default}>" }.join("\n") }, 'merged_by' => ->(_, user, _) { "#{user&.name} <#{user&.commit_email_or_default}>" }, 'co_authored_by' => ->(merge_request, merged_by, squash) do diff --git a/qa/Dockerfile b/qa/Dockerfile index 7f236a25288..d3662d07a1d 100644 --- a/qa/Dockerfile +++ b/qa/Dockerfile @@ -1,9 +1,9 @@ ARG DOCKER_VERSION=20.10.14 ARG CHROME_VERSION=106 -ARG QA_BUILD_TARGET=qa +ARG QA_BUILD_TARGET=ee ARG RUBY_VERSION=2.7 -FROM registry.gitlab.com/gitlab-org/gitlab-build-images/debian-bullseye-ruby-${RUBY_VERSION}:bundler-2.3-git-2.36-lfs-2.9-chrome-${CHROME_VERSION}-docker-${DOCKER_VERSION}-gcloud-383-kubectl-1.23 AS qa +FROM registry.gitlab.com/gitlab-org/gitlab-build-images/debian-bullseye-ruby-${RUBY_VERSION}:bundler-2.3-git-2.36-lfs-2.9-chrome-${CHROME_VERSION}-docker-${DOCKER_VERSION}-gcloud-383-kubectl-1.23 AS foss LABEL maintainer="GitLab Quality Department <quality@gitlab.com>" ENV DEBIAN_FRONTEND="noninteractive" @@ -39,10 +39,6 @@ RUN bundle config set --local without development \ && bundle install --retry=3 COPY ./config/initializers/0_inject_enterprise_edition_module.rb /home/gitlab/config/initializers/ -# Copy VERSION to ensure the COPY succeeds to copy at least one file since ee/app/models/license.rb isn't present in FOSS -# The [b] part makes ./ee/app/models/license.r[b] a pattern that is allowed to return no files (which is the case in FOSS) -COPY VERSION ./ee/app/models/license.r[b] /home/gitlab/ee/app/models/ -COPY VERSION ./ee/config/feature_flag[s] /home/gitlab/ee/config/feature_flags/ COPY ./config/feature_flags /home/gitlab/config/feature_flags COPY ./config/bundler_setup.rb /home/gitlab/config/ COPY ./lib/gitlab_edition.rb /home/gitlab/lib/ @@ -53,8 +49,13 @@ COPY ./qa /home/gitlab/qa ENTRYPOINT ["bin/test"] -# Add JH files when pass the parameter: `--build-arg QA_BUILD_TARGET=jhqa` -FROM qa AS jhqa +# Add ee files when passing the parameter: `--build-arg QA_BUILD_TARGET=ee` +FROM foss as ee +ONBUILD COPY ./ee/app/models/license.rb /home/gitlab/ee/app/models/ +ONBUILD COPY ./ee/config/feature_flags /home/gitlab/ee/config/feature_flags/ + +# Add JH files when passing the parameter: `--build-arg QA_BUILD_TARGET=jhqa` +FROM ee AS jhqa ONBUILD COPY ./jh/qa /home/gitlab/jh/qa ONBUILD COPY ./jh/lib /home/gitlab/jh/lib ONBUILD COPY ./jh/config/feature_flags /home/gitlab/jh/config/feature_flags diff --git a/qa/qa/specs/features/api/1_manage/user_inherited_access_spec.rb b/qa/qa/specs/features/api/1_manage/user_inherited_access_spec.rb index 16d4fd35b69..0a55ec5e017 100644 --- a/qa/qa/specs/features/api/1_manage/user_inherited_access_spec.rb +++ b/qa/qa/specs/features/api/1_manage/user_inherited_access_spec.rb @@ -87,6 +87,9 @@ module QA commit.commit_message = 'Add new file' commit.add_files([{ file_path: 'test.txt', content: 'new file' }]) end + rescue StandardError => e + QA::Runtime::Logger.error("Full failure message: #{e.message}") + raise end.not_to raise_error end diff --git a/scripts/api/download_job_artifact.rb b/scripts/api/download_job_artifact.rb deleted file mode 100755 index 394ad8f3a3d..00000000000 --- a/scripts/api/download_job_artifact.rb +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -require 'optparse' -require 'fileutils' -require 'uri' -require 'cgi' -require 'net/http' -require_relative 'default_options' - -class ArtifactFinder - def initialize(options) - @project = options.delete(:project) - @job_id = options.delete(:job_id) - @api_token = options.delete(:api_token) - @endpoint = options.delete(:endpoint) || API::DEFAULT_OPTIONS[:endpoint] - @artifact_path = options.delete(:artifact_path) - - warn "No API token given." unless api_token - end - - def execute - url = "#{endpoint}/projects/#{CGI.escape(project)}/jobs/#{job_id}/artifacts" - - if artifact_path - FileUtils.mkdir_p(File.dirname(artifact_path)) - url += "/#{artifact_path}" - end - - fetch(url) - end - - private - - attr_reader :project, :job_id, :api_token, :endpoint, :artifact_path - - def fetch(uri_str, limit = 10) - raise 'Too many HTTP redirects' if limit == 0 - - uri = URI(uri_str) - request = Net::HTTP::Get.new(uri) - request['Private-Token'] = api_token if api_token - - Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http| - http.request(request) do |response| - case response - when Net::HTTPSuccess then - File.open(artifact_path || 'artifacts.zip', 'w') do |file| - response.read_body(&file.method(:write)) - end - when Net::HTTPRedirection then - location = response['location'] - warn "Redirected (#{limit - 1} redirections remaining)." - fetch(location, limit - 1) - else - raise "Unexpected response: #{response.value}" - end - end - end - end -end - -if $PROGRAM_NAME == __FILE__ - options = API::DEFAULT_OPTIONS.dup - - OptionParser.new do |opts| - opts.on("-p", "--project PROJECT", String, "Project where to find the job (defaults to $CI_PROJECT_ID)") do |value| - options[:project] = value - end - - opts.on("-j", "--job-id JOB_ID", String, "A job ID") do |value| - options[:job_id] = value - end - - opts.on("-a", "--artifact-path ARTIFACT_PATH", String, "A valid artifact path") do |value| - options[:artifact_path] = value - end - - opts.on("-t", "--api-token API_TOKEN", String, "A value API token with the `read_api` scope") do |value| - options[:api_token] = value - end - - opts.on("-E", "--endpoint ENDPOINT", String, "The API endpoint for the API token. (defaults to $CI_API_V4_URL and fallback to https://gitlab.com/api/v4)") do |value| - options[:endpoint] = value - end - - opts.on("-h", "--help", "Prints this help") do - puts opts - exit - end - end.parse! - - ArtifactFinder.new(options).execute -end diff --git a/scripts/build_qa_image b/scripts/build_qa_image index 4b7eb73e784..3728608e32c 100755 --- a/scripts/build_qa_image +++ b/scripts/build_qa_image @@ -1,9 +1,11 @@ -#!/bin/sh +#!/bin/bash QA_IMAGE_NAME="gitlab-ee-qa" +QA_BUILD_TARGET="ee" -if [ "${CI_PROJECT_NAME}" == "gitlabhq" ] || [ "${CI_PROJECT_NAME}" == "gitlab-foss" ]; then +if [[ "${CI_PROJECT_NAME}" == "gitlabhq" || "${CI_PROJECT_NAME}" == "gitlab-foss" ]]; then QA_IMAGE_NAME="gitlab-ce-qa" + QA_BUILD_TARGET="foss" fi # Tag with commit SHA by default @@ -15,24 +17,29 @@ IMAGE_TAG=${CI_COMMIT_TAG#v} IMAGE_TAG=${IMAGE_TAG:-$CI_COMMIT_REF_SLUG} QA_IMAGE_BRANCH="${CI_REGISTRY}/${CI_PROJECT_PATH}/${QA_IMAGE_NAME}:${IMAGE_TAG}" +QA_IMAGE_MASTER="${CI_REGISTRY}/${CI_PROJECT_PATH}/${QA_IMAGE_NAME}:master" -DESTINATIONS="--destination=${QA_IMAGE} --destination=${QA_IMAGE_BRANCH}" +DESTINATIONS="--tag ${QA_IMAGE} --tag ${QA_IMAGE_BRANCH}" # Auto-deploy tag format uses first 12 letters of commit SHA. Tag with that # reference also for EE images. if [ "${QA_IMAGE_NAME}" == "gitlab-ee-qa" ]; then QA_IMAGE_FOR_AUTO_DEPLOY="${CI_REGISTRY}/${CI_PROJECT_PATH}/${QA_IMAGE_NAME}:${CI_COMMIT_SHA:0:11}" - DESTINATIONS="${DESTINATIONS} --destination=$QA_IMAGE_FOR_AUTO_DEPLOY" + DESTINATIONS="${DESTINATIONS} --tag $QA_IMAGE_FOR_AUTO_DEPLOY" fi echo "Building QA image for destinations: ${DESTINATIONS}" -/kaniko/executor \ - --context="${CI_PROJECT_DIR}" \ - --dockerfile="${CI_PROJECT_DIR}/qa/Dockerfile" \ +docker buildx build \ + --cache-to=type=inline \ + --cache-from="$QA_IMAGE_BRANCH" \ + --cache-from="$QA_IMAGE_MASTER" \ + --platform=${ARCH:-amd64} \ --build-arg=CHROME_VERSION="${CHROME_VERSION}" \ --build-arg=DOCKER_VERSION="${DOCKER_VERSION}" \ --build-arg=RUBY_VERSION="${RUBY_VERSION}" \ - --build-arg=QA_BUILD_TARGET="${QA_BUILD_TARGET:-qa}" \ - --cache=true \ - ${DESTINATIONS} + --build-arg=QA_BUILD_TARGET="${QA_BUILD_TARGET}" \ + --file="${CI_PROJECT_DIR}/qa/Dockerfile" \ + --push \ + ${DESTINATIONS} \ + ${CI_PROJECT_DIR} diff --git a/scripts/rspec_helpers.sh b/scripts/rspec_helpers.sh index 14c5b94e921..cdf397ed72d 100644 --- a/scripts/rspec_helpers.sh +++ b/scripts/rspec_helpers.sh @@ -3,44 +3,14 @@ function retrieve_tests_metadata() { mkdir -p $(dirname "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}") $(dirname "${FLAKY_RSPEC_SUITE_REPORT_PATH}") "${RSPEC_PROFILING_FOLDER_PATH}" - if [[ -n "${RETRIEVE_TESTS_METADATA_FROM_PAGES}" ]]; then - if [[ ! -f "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" ]]; then - curl --location -o "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" "https://gitlab-org.gitlab.io/gitlab/${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" || - echo "{}" > "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" - fi - - if [[ ! -f "${FLAKY_RSPEC_SUITE_REPORT_PATH}" ]]; then - curl --location -o "${FLAKY_RSPEC_SUITE_REPORT_PATH}" "https://gitlab-org.gitlab.io/gitlab/${FLAKY_RSPEC_SUITE_REPORT_PATH}" || - echo "{}" > "${FLAKY_RSPEC_SUITE_REPORT_PATH}" - fi - else - # ${CI_DEFAULT_BRANCH} might not be master in other forks but we want to - # always target the canonical project here, so the branch must be hardcoded - local project_path="gitlab-org/gitlab" - local artifact_branch="master" - local username="gitlab-bot" - local job_name="update-tests-metadata" - local test_metadata_job_id - - # Ruby - test_metadata_job_id=$(scripts/api/get_job_id.rb --endpoint "https://gitlab.com/api/v4" --project "${project_path}" -q "status=success" -q "ref=${artifact_branch}" -q "username=${username}" -Q "scope=success" --job-name "${job_name}") - - if [[ -n "${test_metadata_job_id}" ]]; then - echo "test_metadata_job_id: ${test_metadata_job_id}" - - if [[ ! -f "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" ]]; then - scripts/api/download_job_artifact.rb --endpoint "https://gitlab.com/api/v4" --project "${project_path}" --job-id "${test_metadata_job_id}" --artifact-path "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" || echo "{}" > "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" - fi - - if [[ ! -f "${FLAKY_RSPEC_SUITE_REPORT_PATH}" ]]; then - scripts/api/download_job_artifact.rb --endpoint "https://gitlab.com/api/v4" --project "${project_path}" --job-id "${test_metadata_job_id}" --artifact-path "${FLAKY_RSPEC_SUITE_REPORT_PATH}" || - echo "{}" > "${FLAKY_RSPEC_SUITE_REPORT_PATH}" - fi - else - echo "test_metadata_job_id couldn't be found!" + if [[ ! -f "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" ]]; then + curl --location -o "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" "https://gitlab-org.gitlab.io/gitlab/${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" || echo "{}" > "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" + fi + + if [[ ! -f "${FLAKY_RSPEC_SUITE_REPORT_PATH}" ]]; then + curl --location -o "${FLAKY_RSPEC_SUITE_REPORT_PATH}" "https://gitlab-org.gitlab.io/gitlab/${FLAKY_RSPEC_SUITE_REPORT_PATH}" || echo "{}" > "${FLAKY_RSPEC_SUITE_REPORT_PATH}" - fi fi } @@ -74,31 +44,8 @@ function update_tests_metadata() { function retrieve_tests_mapping() { mkdir -p $(dirname "$RSPEC_PACKED_TESTS_MAPPING_PATH") - if [[ -n "${RETRIEVE_TESTS_METADATA_FROM_PAGES}" ]]; then - if [[ ! -f "${RSPEC_PACKED_TESTS_MAPPING_PATH}" ]]; then - (curl --location -o "${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz" "https://gitlab-org.gitlab.io/gitlab/${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz" && gzip -d "${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz") || echo "{}" > "${RSPEC_PACKED_TESTS_MAPPING_PATH}" - fi - else - # ${CI_DEFAULT_BRANCH} might not be master in other forks but we want to - # always target the canonical project here, so the branch must be hardcoded - local project_path="gitlab-org/gitlab" - local artifact_branch="master" - local username="gitlab-bot" - local job_name="update-tests-metadata" - local test_metadata_with_mapping_job_id - - test_metadata_with_mapping_job_id=$(scripts/api/get_job_id.rb --endpoint "https://gitlab.com/api/v4" --project "${project_path}" -q "status=success" -q "ref=${artifact_branch}" -q "username=${username}" -Q "scope=success" --job-name "${job_name}") - - if [[ -n "${test_metadata_with_mapping_job_id}" ]]; then - echo "test_metadata_with_mapping_job_id: ${test_metadata_with_mapping_job_id}" - - if [[ ! -f "${RSPEC_PACKED_TESTS_MAPPING_PATH}" ]]; then - (scripts/api/download_job_artifact.rb --endpoint "https://gitlab.com/api/v4" --project "${project_path}" --job-id "${test_metadata_with_mapping_job_id}" --artifact-path "${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz" && gzip -d "${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz") || echo "{}" > "${RSPEC_PACKED_TESTS_MAPPING_PATH}" - fi - else - echo "test_metadata_with_mapping_job_id couldn't be found!" - echo "{}" > "${RSPEC_PACKED_TESTS_MAPPING_PATH}" - fi + if [[ ! -f "${RSPEC_PACKED_TESTS_MAPPING_PATH}" ]]; then + (curl --location -o "${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz" "https://gitlab-org.gitlab.io/gitlab/${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz" && gzip -d "${RSPEC_PACKED_TESTS_MAPPING_PATH}.gz") || echo "{}" > "${RSPEC_PACKED_TESTS_MAPPING_PATH}" fi scripts/unpack-test-mapping "${RSPEC_PACKED_TESTS_MAPPING_PATH}" "${RSPEC_TESTS_MAPPING_PATH}" @@ -107,31 +54,8 @@ function retrieve_tests_mapping() { function retrieve_frontend_fixtures_mapping() { mkdir -p $(dirname "$FRONTEND_FIXTURES_MAPPING_PATH") - if [[ -n "${RETRIEVE_TESTS_METADATA_FROM_PAGES}" ]]; then - if [[ ! -f "${FRONTEND_FIXTURES_MAPPING_PATH}" ]]; then - (curl --location -o "${FRONTEND_FIXTURES_MAPPING_PATH}" "https://gitlab-org.gitlab.io/gitlab/${FRONTEND_FIXTURES_MAPPING_PATH}") || echo "{}" > "${FRONTEND_FIXTURES_MAPPING_PATH}" - fi - else - # ${CI_DEFAULT_BRANCH} might not be master in other forks but we want to - # always target the canonical project here, so the branch must be hardcoded - local project_path="gitlab-org/gitlab" - local artifact_branch="master" - local username="gitlab-bot" - local job_name="generate-frontend-fixtures-mapping" - local test_metadata_with_mapping_job_id - - test_metadata_with_mapping_job_id=$(scripts/api/get_job_id.rb --endpoint "https://gitlab.com/api/v4" --project "${project_path}" -q "ref=${artifact_branch}" -q "username=${username}" -Q "scope=success" --job-name "${job_name}") - - if [[ $? -eq 0 ]] && [[ -n "${test_metadata_with_mapping_job_id}" ]]; then - echo "test_metadata_with_mapping_job_id: ${test_metadata_with_mapping_job_id}" - - if [[ ! -f "${FRONTEND_FIXTURES_MAPPING_PATH}" ]]; then - (scripts/api/download_job_artifact.rb --endpoint "https://gitlab.com/api/v4" --project "${project_path}" --job-id "${test_metadata_with_mapping_job_id}" --artifact-path "${FRONTEND_FIXTURES_MAPPING_PATH}") || echo "{}" > "${FRONTEND_FIXTURES_MAPPING_PATH}" - fi - else - echo "test_metadata_with_mapping_job_id couldn't be found!" - echo "{}" > "${FRONTEND_FIXTURES_MAPPING_PATH}" - fi + if [[ ! -f "${FRONTEND_FIXTURES_MAPPING_PATH}" ]]; then + (curl --location -o "${FRONTEND_FIXTURES_MAPPING_PATH}" "https://gitlab-org.gitlab.io/gitlab/${FRONTEND_FIXTURES_MAPPING_PATH}") || echo "{}" > "${FRONTEND_FIXTURES_MAPPING_PATH}" fi } diff --git a/spec/lib/gitlab/audit/type/definition_spec.rb b/spec/lib/gitlab/audit/type/definition_spec.rb index 9f4282a4ec0..b106f158924 100644 --- a/spec/lib/gitlab/audit/type/definition_spec.rb +++ b/spec/lib/gitlab/audit/type/definition_spec.rb @@ -18,6 +18,12 @@ RSpec.describe Gitlab::Audit::Type::Definition do let(:definition) { described_class.new(path, attributes) } let(:yaml_content) { attributes.deep_stringify_keys.to_yaml } + around do |example| + described_class.clear_memoization(:definitions) + example.run + described_class.clear_memoization(:definitions) + end + describe '#key' do subject { definition.key } @@ -111,6 +117,18 @@ RSpec.describe Gitlab::Audit::Type::Definition do end end + describe '.event_names' do + before do + allow(described_class).to receive(:definitions) do + { definition.key => definition } + end + end + + it 'returns names of event types as string array' do + expect(described_class.event_names).to match_array([definition.attributes[:name]]) + end + end + describe '.load_from_file' do it 'properly loads a definition from file' do expect_file_read(path, content: yaml_content) diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index e9dde1c6180..add7ab6bd37 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -157,6 +157,7 @@ merge_requests: - author - assignee - reviewers +- reviewed_by_users - updated_by - milestone - iteration diff --git a/spec/lib/gitlab/merge_requests/commit_message_generator_spec.rb b/spec/lib/gitlab/merge_requests/commit_message_generator_spec.rb index ad528dca81a..bdc9879f362 100644 --- a/spec/lib/gitlab/merge_requests/commit_message_generator_spec.rb +++ b/spec/lib/gitlab/merge_requests/commit_message_generator_spec.rb @@ -289,6 +289,93 @@ RSpec.describe Gitlab::MergeRequests::CommitMessageGenerator do end end + context 'when project has merge commit template with reviewers' do + let(:user1) { create(:user) } + let(:user2) { create(:user) } + let(message_template_name) { <<~MSG.rstrip } + Merge branch '%{source_branch}' into '%{target_branch}' + + %{reviewed_by} + MSG + + context 'and mr has no reviewers' do + before do + merge_request.reviews = [] + end + + it 'removes variable and blank line' do + expect(result_message).to eq <<~MSG.rstrip + Merge branch 'feature' into 'master' + MSG + end + + context 'when there is blank line after reviewed_by' do + let(message_template_name) { <<~MSG.rstrip } + Merge branch '%{source_branch}' into '%{target_branch}' + + %{reviewed_by} + + Type: merge + MSG + + it 'removes blank line before it' do + expect(result_message).to eq <<~MSG.rstrip + Merge branch 'feature' into 'master' + + Type: merge + MSG + end + end + + context 'when there is no blank line after reviewed_by' do + let(message_template_name) { <<~MSG.rstrip } + Merge branch '%{source_branch}' into '%{target_branch}' + + %{reviewed_by} + Type: merge + MSG + + it 'does not remove blank line before it' do + expect(result_message).to eq <<~MSG.rstrip + Merge branch 'feature' into 'master' + + Type: merge + MSG + end + end + end + + context 'and mr has one reviewer' do + before do + merge_request.reviews.create!(project: merge_request.project, author: user1) + end + + it 'returns user name and email' do + expect(result_message).to eq <<~MSG.rstrip + Merge branch 'feature' into 'master' + + Reviewed-by: #{user1.name} <#{user1.email}> + MSG + end + end + + context 'and mr has multiple reviewers' do + before do + merge_request.reviews.create!(project: merge_request.project, author: user1) + merge_request.reviews.create!(project: merge_request.project, author: user2) + end + + it 'returns users names and emails' do + expect(result_message).to eq <<~MSG.rstrip + Merge branch 'feature' into 'master' + + Reviewed-by: #{user1.name} <#{user1.email}> + Reviewed-by: #{user2.name} <#{user2.email}> + MSG + end + end + end + context 'when project has merge commit template with approvers' do let(:user1) { create(:user) } let(:user2) { create(:user) } @@ -547,6 +634,7 @@ RSpec.describe Gitlab::MergeRequests::CommitMessageGenerator do first_commit:%{first_commit} first_multiline_commit:%{first_multiline_commit} url:%{url} + reviewed_by:%{reviewed_by} approved_by:%{approved_by} merged_by:%{merged_by} co_authored_by:%{co_authored_by} @@ -568,6 +656,7 @@ RSpec.describe Gitlab::MergeRequests::CommitMessageGenerator do Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> url:#{Gitlab::UrlBuilder.build(merge_request)} + reviewed_by: approved_by: merged_by:#{current_user.name} <#{current_user.commit_email_or_default}> co_authored_by:Co-authored-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> diff --git a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb index 08c712889a8..0bea06f602f 100644 --- a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb +++ b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb @@ -90,31 +90,32 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s describe '.categories' do it 'gets CE unique category names' do expect(described_class.categories).to include( + 'analytics', + 'ci_templates', + 'ci_users', + 'code_review', 'deploy_token_packages', - 'user_packages', 'ecosystem', - 'analytics', + 'environments', + 'error_tracking', + 'geo', 'ide_edit', - 'search', - 'source_code', - 'incident_management', + 'importer', 'incident_management_alerts', - 'testing', + 'incident_management', 'issues_edit', - 'snippets', - 'code_review', - 'terraform', - 'ci_templates', - 'quickactions', + 'kubernetes_agent', + 'manage', 'pipeline_authoring', + 'quickactions', + 'search', 'secure', - 'importer', - 'geo', - 'work_items', - 'ci_users', - 'error_tracking', - 'manage', - 'kubernetes_agent' + 'snippets', + 'source_code', + 'terraform', + 'testing', + 'user_packages', + 'work_items' ) end end diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index 6ba450b6d57..50b90253e39 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -1955,6 +1955,78 @@ RSpec.describe Group do end end + describe '#self_and_hierarchy_intersecting_with_user_groups' do + let_it_be(:user) { create(:user) } + let(:subject) { group.self_and_hierarchy_intersecting_with_user_groups(user) } + + it 'makes a call to GroupsFinder' do + expect(GroupsFinder).to receive_message_chain(:new, :execute, :unscope) + + subject + end + + context 'when the group is private' do + let_it_be(:group) { create(:group, :private) } + + context 'when the user is not a member of the group' do + it 'is an empty array' do + expect(subject).to eq([]) + end + end + + context 'when the user is a member of the group' do + before do + group.add_developer(user) + end + + it 'is equal to the group' do + expect(subject).to match_array([group]) + end + end + + context 'when the group has a sub group' do + let_it_be(:subgroup) { create(:group, :private, parent: group) } + + context 'when the user is not a member of the subgroup' do + it 'is an empty array' do + expect(subject).to eq([]) + end + end + + context 'when the user is a member of the subgroup' do + before do + subgroup.add_developer(user) + end + + it 'is equal to the group and subgroup' do + expect(subject).to match_array([group, subgroup]) + end + + context 'when the group has an ancestor' do + let_it_be(:ancestor) { create(:group, :private) } + + before do + group.parent = ancestor + group.save! + end + + it 'is equal to the ancestor, group and subgroup' do + expect(subject).to match_array([ancestor, group, subgroup]) + end + end + end + end + end + + context 'when the group is public' do + let_it_be(:group) { create(:group, :public) } + + it 'is equal to the public group regardless of membership' do + expect(subject).to match_array([group]) + end + end + end + describe '#update_two_factor_requirement_for_members' do let_it_be_with_reload(:user) { create(:user) } diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index cf4f58f558c..ccc77c7259f 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -30,6 +30,7 @@ RSpec.describe MergeRequest, factory_default: :keep do it { is_expected.to have_many(:resource_state_events) } it { is_expected.to have_many(:draft_notes) } it { is_expected.to have_many(:reviews).inverse_of(:merge_request) } + it { is_expected.to have_many(:reviewed_by_users).through(:reviews).source(:author) } it { is_expected.to have_one(:cleanup_schedule).inverse_of(:merge_request) } it { is_expected.to have_many(:created_environments).class_name('Environment').inverse_of(:merge_request) } @@ -46,6 +47,20 @@ RSpec.describe MergeRequest, factory_default: :keep do expect(project.merge_requests.find(merge_request.id)).to eq(merge_request) end end + + describe '#reviewed_by_users' do + let!(:merge_request) { create(:merge_request) } + + context 'when the same user has several reviews' do + before do + 2.times { create(:review, merge_request: merge_request, project: merge_request.project, author: merge_request.author) } + end + + it 'returns distinct users' do + expect(merge_request.reviewed_by_users).to match_array([merge_request.author]) + end + end + end end describe '.from_and_to_forks' do diff --git a/spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb index 629d93676eb..dab9ee27dab 100644 --- a/spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb +++ b/spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb @@ -849,12 +849,6 @@ RSpec.shared_examples 'uploads a package file' do expect(package_file.file_name).to eq(params[:file].original_filename) end - it "doesn't attempt to migrate file to object storage" do - expect(ObjectStorage::BackgroundMoveWorker).not_to receive(:perform_async) - - subject - end - context 'with existing package' do let!(:existing_package) { create(:conan_package, name: 'foo', version: 'bar', project: project) } @@ -936,8 +930,6 @@ RSpec.shared_examples 'uploads a package file' do end end end - - it_behaves_like 'background upload schedules a file migration' end end diff --git a/spec/support/shared_examples/requests/api/helm_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/helm_packages_shared_examples.rb index 8bf6b162508..7803f0ff04d 100644 --- a/spec/support/shared_examples/requests/api/helm_packages_shared_examples.rb +++ b/spec/support/shared_examples/requests/api/helm_packages_shared_examples.rb @@ -156,25 +156,13 @@ RSpec.shared_examples 'process helm upload' do |user_type, status| end context 'and direct upload disabled' do - context 'and background upload disabled' do - let(:fog_connection) do - stub_package_file_object_storage(direct_upload: false, background_upload: false) - end - - it_behaves_like 'creates helm package files' + let(:fog_connection) do + stub_package_file_object_storage(direct_upload: false) end - context 'and background upload enabled' do - let(:fog_connection) do - stub_package_file_object_storage(direct_upload: false, background_upload: true) - end - - it_behaves_like 'creates helm package files' - end + it_behaves_like 'creates helm package files' end end - - it_behaves_like 'background upload schedules a file migration' end end diff --git a/spec/support/shared_examples/requests/api/nuget_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/nuget_packages_shared_examples.rb index fdd55893deb..0eae689ab01 100644 --- a/spec/support/shared_examples/requests/api/nuget_packages_shared_examples.rb +++ b/spec/support/shared_examples/requests/api/nuget_packages_shared_examples.rb @@ -224,25 +224,13 @@ RSpec.shared_examples 'process nuget upload' do |user_type, status, add_member = end context 'and direct upload disabled' do - context 'and background upload disabled' do - let(:fog_connection) do - stub_package_file_object_storage(direct_upload: false, background_upload: false) - end - - it_behaves_like 'creates nuget package files' + let(:fog_connection) do + stub_package_file_object_storage(direct_upload: false) end - context 'and background upload enabled' do - let(:fog_connection) do - stub_package_file_object_storage(direct_upload: false, background_upload: true) - end - - it_behaves_like 'creates nuget package files' - end + it_behaves_like 'creates nuget package files' end end - - it_behaves_like 'background upload schedules a file migration' end end diff --git a/spec/support/shared_examples/requests/api/pypi_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/pypi_packages_shared_examples.rb index a9b44015206..e74841a44e7 100644 --- a/spec/support/shared_examples/requests/api/pypi_packages_shared_examples.rb +++ b/spec/support/shared_examples/requests/api/pypi_packages_shared_examples.rb @@ -95,25 +95,13 @@ RSpec.shared_examples 'PyPI package creation' do |user_type, status, add_member end context 'and direct upload disabled' do - context 'and background upload disabled' do - let(:fog_connection) do - stub_package_file_object_storage(direct_upload: false, background_upload: false) - end - - it_behaves_like 'creating pypi package files' + let(:fog_connection) do + stub_package_file_object_storage(direct_upload: false) end - context 'and background upload enabled' do - let(:fog_connection) do - stub_package_file_object_storage(direct_upload: false, background_upload: true) - end - - it_behaves_like 'creating pypi package files' - end + it_behaves_like 'creating pypi package files' end end - - it_behaves_like 'background upload schedules a file migration' end end diff --git a/spec/support/shared_examples/requests/api/rubygems_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/rubygems_packages_shared_examples.rb index f075927e7bf..da09d70c777 100644 --- a/spec/support/shared_examples/requests/api/rubygems_packages_shared_examples.rb +++ b/spec/support/shared_examples/requests/api/rubygems_packages_shared_examples.rb @@ -122,21 +122,11 @@ RSpec.shared_examples 'process rubygems upload' do |user_type, status, add_membe end context 'and direct upload disabled' do - context 'and background upload disabled' do - let(:fog_connection) do - stub_package_file_object_storage(direct_upload: false, background_upload: false) - end - - it_behaves_like 'creates rubygems package files' + let(:fog_connection) do + stub_package_file_object_storage(direct_upload: false) end - context 'and background upload enabled' do - let(:fog_connection) do - stub_package_file_object_storage(direct_upload: false, background_upload: true) - end - - it_behaves_like 'creates rubygems package files' - end + it_behaves_like 'creates rubygems package files' end end end diff --git a/spec/support/shared_examples/requests/api/terraform/modules/v1/packages_shared_examples.rb b/spec/support/shared_examples/requests/api/terraform/modules/v1/packages_shared_examples.rb index bdff2c65691..ae2855083f6 100644 --- a/spec/support/shared_examples/requests/api/terraform/modules/v1/packages_shared_examples.rb +++ b/spec/support/shared_examples/requests/api/terraform/modules/v1/packages_shared_examples.rb @@ -264,21 +264,11 @@ RSpec.shared_examples 'process terraform module upload' do |user_type, status, a end context 'and direct upload disabled' do - context 'and background upload disabled' do - let(:fog_connection) do - stub_package_file_object_storage(direct_upload: false, background_upload: false) - end - - it_behaves_like 'creates terraform module package files' + let(:fog_connection) do + stub_package_file_object_storage(direct_upload: false) end - context 'and background upload enabled' do - let(:fog_connection) do - stub_package_file_object_storage(direct_upload: false, background_upload: true) - end - - it_behaves_like 'creates terraform module package files' - end + it_behaves_like 'creates terraform module package files' end end end diff --git a/spec/support/shared_examples/services/packages_shared_examples.rb b/spec/support/shared_examples/services/packages_shared_examples.rb index ca4dea90c55..e0dd08ec50e 100644 --- a/spec/support/shared_examples/services/packages_shared_examples.rb +++ b/spec/support/shared_examples/services/packages_shared_examples.rb @@ -188,20 +188,6 @@ RSpec.shared_examples 'returns paginated packages' do end end -RSpec.shared_examples 'background upload schedules a file migration' do - context 'background upload enabled' do - before do - stub_package_file_object_storage(background_upload: true) - end - - it 'schedules migration of file to object storage' do - expect(ObjectStorage::BackgroundMoveWorker).to receive(:perform_async).with('Packages::PackageFileUploader', 'Packages::PackageFile', :file, kind_of(Numeric)) - - subject - end - end -end - RSpec.shared_context 'package filter context' do def package_filter_url(filter, param) "/projects/#{project.id}/packages?package_#{filter}=#{param}" diff --git a/spec/uploaders/packages/composer/cache_uploader_spec.rb b/spec/uploaders/packages/composer/cache_uploader_spec.rb index a4ba4cc2a1e..7ceaa24f463 100644 --- a/spec/uploaders/packages/composer/cache_uploader_spec.rb +++ b/spec/uploaders/packages/composer/cache_uploader_spec.rb @@ -33,8 +33,6 @@ RSpec.describe Packages::Composer::CacheUploader do end it 'can store file remotely' do - allow(ObjectStorage::BackgroundMoveWorker).to receive(:perform_async) - cache_file expect(cache_file.file_store).to eq(described_class::Store::REMOTE) diff --git a/spec/uploaders/packages/debian/component_file_uploader_spec.rb b/spec/uploaders/packages/debian/component_file_uploader_spec.rb index de60ec94acf..bee82fb2715 100644 --- a/spec/uploaders/packages/debian/component_file_uploader_spec.rb +++ b/spec/uploaders/packages/debian/component_file_uploader_spec.rb @@ -38,8 +38,6 @@ RSpec.describe Packages::Debian::ComponentFileUploader do end it 'can store file remotely' do - allow(ObjectStorage::BackgroundMoveWorker).to receive(:perform_async) - component_file expect(component_file.file_store).to eq(described_class::Store::REMOTE) diff --git a/spec/uploaders/packages/debian/distribution_release_file_uploader_spec.rb b/spec/uploaders/packages/debian/distribution_release_file_uploader_spec.rb index dbbf69e3c8d..96655edb186 100644 --- a/spec/uploaders/packages/debian/distribution_release_file_uploader_spec.rb +++ b/spec/uploaders/packages/debian/distribution_release_file_uploader_spec.rb @@ -38,8 +38,6 @@ RSpec.describe Packages::Debian::DistributionReleaseFileUploader do end it 'can store file remotely' do - allow(ObjectStorage::BackgroundMoveWorker).to receive(:perform_async) - distribution expect(distribution.file_store).to eq(described_class::Store::REMOTE) diff --git a/spec/uploaders/packages/package_file_uploader_spec.rb b/spec/uploaders/packages/package_file_uploader_spec.rb index 0c7bf6432cb..7d270ad03c9 100644 --- a/spec/uploaders/packages/package_file_uploader_spec.rb +++ b/spec/uploaders/packages/package_file_uploader_spec.rb @@ -33,8 +33,6 @@ RSpec.describe Packages::PackageFileUploader do end it 'can store file remotely' do - allow(ObjectStorage::BackgroundMoveWorker).to receive(:perform_async) - package_file expect(package_file.file_store).to eq(described_class::Store::REMOTE) diff --git a/spec/uploaders/packages/rpm/repository_file_uploader_spec.rb b/spec/uploaders/packages/rpm/repository_file_uploader_spec.rb index 720e109533b..b3767ae179a 100644 --- a/spec/uploaders/packages/rpm/repository_file_uploader_spec.rb +++ b/spec/uploaders/packages/rpm/repository_file_uploader_spec.rb @@ -33,8 +33,6 @@ RSpec.describe Packages::Rpm::RepositoryFileUploader do end it 'can store file remotely' do - allow(ObjectStorage::BackgroundMoveWorker).to receive(:perform_async) - repository_file expect(repository_file.file_store).to eq(described_class::Store::REMOTE) |