diff --git a/.gitlab/ci/gitlab-com/danger-review.gitlab-ci.yml b/.gitlab/ci/gitlab-com/danger-review.gitlab-ci.yml index 7f093a7cbc6..8fe9706d913 100644 --- a/.gitlab/ci/gitlab-com/danger-review.gitlab-ci.yml +++ b/.gitlab/ci/gitlab-com/danger-review.gitlab-ci.yml @@ -1,6 +1,6 @@ include: - project: gitlab-org/quality/pipeline-common - ref: 8.3.2 + ref: 8.4.0 file: - /ci/danger-review.yml diff --git a/.gitlab/ci/observability-backend.gitlab-ci.yml b/.gitlab/ci/observability-backend.gitlab-ci.yml new file mode 100644 index 00000000000..108e09491c9 --- /dev/null +++ b/.gitlab/ci/observability-backend.gitlab-ci.yml @@ -0,0 +1,39 @@ +# Triggers downstream e2e tests in gitlab-org/opstrace/opstrace +# These e2e tests live in gitlab-org/opstrace/opstrace as a result +# of opstrace being brought in through an acquisition. +.e2e-observability-backend-base: + stage: test + needs: [] + extends: + - .observability-backend:rules + inherit: + variables: false + variables: + TEST_GITLAB_COMMIT: $CI_COMMIT_SHA + trigger: + project: gitlab-org/opstrace/opstrace + strategy: depend + +# e2e:observability-backend uses $CI_COMMIT_REF_NAME to +# checkout a branch in gitlab-org/opstrace/opstrace with +# the same name as the branch in this repo. Because opstrace +# is a different codebase, we match branch names without +# commit SHA. +e2e:observability-backend: + extends: .e2e-observability-backend-base + trigger: + project: gitlab-org/opstrace/opstrace + branch: $CI_COMMIT_REF_NAME + +# e2e:observability-backend-main-branch will trigger +# an e2e test pipeline that checks out GitLab to +# $CI_COMMIT_SHA and Opstrace to the latest commit +# on main branch. Devs run this manually on local +# installs today periodically during development +# and this manual job increases dev velocity +# and testing reliablity. +e2e:observability-backend-main-branch: + extends: .e2e-observability-backend-base + trigger: + project: gitlab-org/opstrace/opstrace + branch: main diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml index bca285d3f14..ce4f8386ca7 100644 --- a/.gitlab/ci/rules.gitlab-ci.yml +++ b/.gitlab/ci/rules.gitlab-ci.yml @@ -3013,3 +3013,17 @@ when: manual - <<: *if-merge-request-labels-run-all-rspec when: manual + +############################### +# Observability Backend rules # +############################### +.observability-backend:rules: + rules: + - <<: *if-merge-request + changes: *code-patterns + when: manual + allow_failure: true + - <<: *if-merge-request + changes: *ci-patterns + when: manual + allow_failure: true diff --git a/app/assets/javascripts/error_tracking/components/error_details_info.vue b/app/assets/javascripts/error_tracking/components/error_details_info.vue index 0b4eabe25d1..3db946acdfc 100644 --- a/app/assets/javascripts/error_tracking/components/error_details_info.vue +++ b/app/assets/javascripts/error_tracking/components/error_details_info.vue @@ -74,7 +74,9 @@ export default { + field.key !== 'users'); + } + return this.$options.fields; + }, }, watch: { pagination() { @@ -417,7 +424,7 @@ export default { {}, group: -> {}) - if two_factor_authentication_required? - if Gitlab::CurrentSettings.require_two_factor_authentication? - global.call - else - groups = current_user.source_groups_of_two_factor_authentication_requirement.reorder(name: :asc) - group.call(groups) - end - end + def execute_action_for_2fa_reason(actions) + reason = two_factor_verifier.two_factor_authentication_reason + groups_enforcing_two_factor = current_user.source_groups_of_two_factor_authentication_requirement + .reorder(name: :asc) + actions[reason].call(groups_enforcing_two_factor) end # rubocop: enable CodeReuse/ActiveRecord diff --git a/app/controllers/profiles/two_factor_auths_controller.rb b/app/controllers/profiles/two_factor_auths_controller.rb index f1646027e8e..5a956a14552 100644 --- a/app/controllers/profiles/two_factor_auths_controller.rb +++ b/app/controllers/profiles/two_factor_auths_controller.rb @@ -207,15 +207,19 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController def setup_show_page if two_factor_authentication_required? && !current_user.two_factor_enabled? - two_factor_authentication_reason( - global: lambda do + two_factor_auth_actions = { + global: lambda do |_| flash.now[:alert] = _('The global settings require you to enable Two-Factor Authentication for your account.') end, + admin_2fa: lambda do |_| + flash.now[:alert] = _('Administrator users are required to enable Two-Factor Authentication for their account.') + end, group: lambda do |groups| flash.now[:alert] = groups_notification(groups) end - ) + } + execute_action_for_2fa_reason(two_factor_auth_actions) unless two_factor_grace_period_expired? grace_period_deadline = current_user.otp_grace_period_started_at + two_factor_grace_period.hours diff --git a/app/graphql/types/ci/catalog/resources/version_type.rb b/app/graphql/types/ci/catalog/resources/version_type.rb index c568403f320..b52a1c6b13d 100644 --- a/app/graphql/types/ci/catalog/resources/version_type.rb +++ b/app/graphql/types/ci/catalog/resources/version_type.rb @@ -20,18 +20,10 @@ module Types field :released_at, Types::TimeType, null: true, description: 'Timestamp of when the version was released.', alpha: { milestone: '16.7' } - field :tag_name, GraphQL::Types::String, null: true, method: :name, - description: 'Deprecated in 16.8. Use name.', - alpha: { milestone: '16.7' } - field :name, GraphQL::Types::String, null: true, description: 'Name that uniquely identifies the version within the catalog resource.', alpha: { milestone: '16.8' } - field :tag_path, GraphQL::Types::String, null: true, method: :path, - description: 'Deprecated in 16.8. Use path.', - alpha: { milestone: '16.7' } - field :path, GraphQL::Types::String, null: true, description: 'Relative web path to the version.', alpha: { milestone: '16.8' } diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index 919fc485d64..b9a59047238 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -353,6 +353,7 @@ module ApplicationSettingsHelper :repository_checks_enabled, :repository_storages_weighted, :require_admin_approval_after_user_signup, + :require_admin_two_factor_authentication, :require_two_factor_authentication, :remember_me_enabled, :restricted_visibility_levels, diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index cb533a5e99d..d1dfc051b25 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -835,6 +835,9 @@ class ApplicationSetting < MainClusterwide::ApplicationRecord validates :math_rendering_limits_enabled, inclusion: { in: [true, false], message: N_('must be a boolean value') } + validates :require_admin_two_factor_authentication, + inclusion: { in: [true, false], message: N_('must be a boolean value') } + before_validation :ensure_uuid! before_validation :coerce_repository_storages_weighted, if: :repository_storages_weighted_changed? before_validation :normalize_default_branch_name diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb index eddc508a6ee..e18476bbae6 100644 --- a/app/models/application_setting_implementation.rb +++ b/app/models/application_setting_implementation.rb @@ -79,6 +79,7 @@ module ApplicationSettingImplementation ecdsa_sk_key_restriction: default_min_key_size(:ecdsa_sk), ed25519_key_restriction: default_min_key_size(:ed25519), ed25519_sk_key_restriction: default_min_key_size(:ed25519_sk), + require_admin_two_factor_authentication: false, eks_access_key_id: nil, eks_account_id: nil, eks_integration_enabled: false, diff --git a/app/views/admin/application_settings/_signin.html.haml b/app/views/admin/application_settings/_signin.html.haml index 2b972a2d7f1..3d3d4ab29d1 100644 --- a/app/views/admin/application_settings/_signin.html.haml +++ b/app/views/admin/application_settings/_signin.html.haml @@ -23,6 +23,9 @@ = f.gitlab_ui_checkbox_component :require_two_factor_authentication, _('Enforce two-factor authentication'), help_text: '%{help_text} %{help_link}'.html_safe % { help_text: help_text, help_link: help_link } + .form-group + = f.label :require_admin_two_factor_authentication, _('Enforce Two-Factor authentication for administrator users'), class: 'label-bold' + = f.gitlab_ui_checkbox_component :require_admin_two_factor_authentication, _('Require administrators to enable 2FA') .form-group = f.label :two_factor_authentication, _('Two-factor grace period'), class: 'label-bold' = f.number_field :two_factor_grace_period, min: 0, class: 'form-control gl-form-input', placeholder: '0' diff --git a/app/views/layouts/_snowplow.html.haml b/app/views/layouts/_snowplow.html.haml index 7cb4abd06d6..503b38496f7 100644 --- a/app/views/layouts/_snowplow.html.haml +++ b/app/views/layouts/_snowplow.html.haml @@ -2,7 +2,7 @@ - namespace = @group || @project&.namespace || @namespace = webpack_bundle_tag 'tracker' -- if Gitlab.com? && Feature.enabled?(:browsersdk_tracking) && Feature.enabled?(:gl_analytics_tracking, Feature.current_request) +- if Gitlab.com? && Feature.enabled?(:gl_analytics_tracking, Feature.current_request) = webpack_bundle_tag 'analytics' = javascript_tag do :plain diff --git a/config/feature_flags/development/browsersdk_tracking.yml b/config/feature_flags/development/browsersdk_tracking.yml deleted file mode 100644 index 688d559904b..00000000000 --- a/config/feature_flags/development/browsersdk_tracking.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: browsersdk_tracking -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/129517 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/422264 -milestone: '16.4' -type: development -group: group::analytics instrumentation -default_enabled: false diff --git a/config/feature_flags/development/use_500_page_size_for_contribution_analytics.yml b/config/feature_flags/development/use_500_page_size_for_contribution_analytics.yml deleted file mode 100644 index edc696fc9ac..00000000000 --- a/config/feature_flags/development/use_500_page_size_for_contribution_analytics.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: use_500_page_size_for_contribution_analytics -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136724 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/431595 -milestone: '16.7' -type: development -group: group::optimize -default_enabled: true diff --git a/data/deprecations/15-8-deprecate-slack-notifications-integration.yml b/data/deprecations/15-8-deprecate-slack-notifications-integration.yml index 33f9e6ce3a7..21c6cb7d0cf 100644 --- a/data/deprecations/15-8-deprecate-slack-notifications-integration.yml +++ b/data/deprecations/15-8-deprecate-slack-notifications-integration.yml @@ -1,17 +1,16 @@ - title: "Slack notifications integration" # (required) Clearly explain the change, or planned change. For example, "The `confidential` field for a `Note` is deprecated" or "CI/CD job names will be limited to 250 characters." announcement_milestone: "15.9" # (required) The milestone when this feature was first announced as deprecated. - removal_milestone: "17.0" # (required) The milestone when this feature is planned to be removed + removal_milestone: "18.0" # (required) The milestone when this feature is planned to be removed breaking_change: true # (required) Change to false if this is not a breaking change. reporter: g.hickman # (required) GitLab username of the person reporting the change stage: manage # (required) String value of the stage that the feature was created in. e.g., Growth - issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/372411 # (required) Link to the deprecation issue in GitLab + issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/435909 # (required) Link to the deprecation issue in GitLab body: | # (required) Do not modify this line, instead modify the lines below. As we're consolidating all Slack capabilities into the - GitLab for Slack app, we're [deprecating the Slack notifications - integration](https://gitlab.com/gitlab-org/gitlab/-/issues/372411). - GitLab.com users can now use the GitLab for Slack app to manage notifications - to their Slack workspace. For self-managed users of the Slack notifications integration, - we'll be introducing support in [this epic](https://gitlab.com/groups/gitlab-org/-/epics/1211). + GitLab for Slack app, we've deprecated the Slack notifications + integration. + Use the GitLab for Slack app to manage notifications + to your Slack workspace. # # OPTIONAL END OF SUPPORT FIELDS diff --git a/data/deprecations/16-7-remove-slsa-0.2-statement.yml b/data/deprecations/16-7-remove-slsa-0.2-statement.yml new file mode 100644 index 00000000000..745036d2ecc --- /dev/null +++ b/data/deprecations/16-7-remove-slsa-0.2-statement.yml @@ -0,0 +1,12 @@ +# +# REQUIRED FIELDS +# +- title: "GitLab Runner provenance metadata SLSA v0.2 statement" + removal_milestone: "17.0" # (required) The milestone when this feature is planned to be removed + announcement_milestone: "16.8" # (required) The milestone when this feature was first announced as deprecated. + breaking_change: true # (required) Change to false if this is not a breaking change. + reporter: sam.white # (required) GitLab username of the person reporting the change + stage: verify # (required) String value of the stage that the feature was created in. e.g., Growth + issue_url: https://gitlab.com/gitlab-org/gitlab-runner/-/issues/36869 # (required) Link to the deprecation issue in GitLab + body: | # (required) Do not modify this line, instead modify the lines below. + Runners generate provenance metadata and currently defaults to generating statements that adhere to SLSA v0.2. Because SLSA v1.0 has been released and is now supported by GitLab, the v0.2 statement is now deprecated and removal is planned in GitLab 17.0. The SLSA v1.0 statement is planned to become the new default statement format in GitLab 17.0. diff --git a/db/migrate/20231116201338_add_require_admin_two_factor_authentication_to_application_settings.rb b/db/migrate/20231116201338_add_require_admin_two_factor_authentication_to_application_settings.rb new file mode 100644 index 00000000000..9f6c4feff34 --- /dev/null +++ b/db/migrate/20231116201338_add_require_admin_two_factor_authentication_to_application_settings.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# See https://docs.gitlab.com/ee/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddRequireAdminTwoFactorAuthenticationToApplicationSettings < Gitlab::Database::Migration[2.2] + milestone '16.8' + + def change + add_column :application_settings, :require_admin_two_factor_authentication, :boolean, default: false, null: false + end +end diff --git a/db/post_migrate/20240102065444_remove_milestone_id_column_from_vulnerabilities.rb b/db/post_migrate/20240102065444_remove_milestone_id_column_from_vulnerabilities.rb new file mode 100644 index 00000000000..f74c15a97fb --- /dev/null +++ b/db/post_migrate/20240102065444_remove_milestone_id_column_from_vulnerabilities.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class RemoveMilestoneIdColumnFromVulnerabilities < Gitlab::Database::Migration[2.2] + disable_ddl_transaction! + + milestone '16.8' + + def up + with_lock_retries do + remove_column :vulnerabilities, :milestone_id + end + end + + def down + add_column :vulnerabilities, :milestone_id, :bigint unless column_exists?(:vulnerabilities, :milestone_id) + + # Add back index and constraint that were dropped in `up` + add_concurrent_index(:vulnerabilities, :milestone_id) + add_concurrent_foreign_key(:vulnerabilities, :milestones, column: :milestone_id, on_delete: :nullify) + end +end diff --git a/db/schema_migrations/20231116201338 b/db/schema_migrations/20231116201338 new file mode 100644 index 00000000000..7266a7a36bc --- /dev/null +++ b/db/schema_migrations/20231116201338 @@ -0,0 +1 @@ +bb86e8dd465b6bfa394c16e27a7ebc16b63545f9b7675e57399ac159d4b53711 \ No newline at end of file diff --git a/db/schema_migrations/20240102065444 b/db/schema_migrations/20240102065444 new file mode 100644 index 00000000000..5f5db30dc4e --- /dev/null +++ b/db/schema_migrations/20240102065444 @@ -0,0 +1 @@ +e3fce3184c7e9c3e84e73caeaee94ab14dafc46c046e8477d5762b3d41a11a02 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 3133cfe6c6e..c444798f901 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -12083,6 +12083,7 @@ CREATE TABLE application_settings ( session_expire_delay integer DEFAULT 10080 NOT NULL, import_sources text, help_page_text text, + require_admin_two_factor_authentication boolean DEFAULT false NOT NULL, shared_runners_enabled boolean DEFAULT true NOT NULL, max_artifacts_size integer DEFAULT 100 NOT NULL, runners_registration_token character varying, @@ -25200,7 +25201,6 @@ ALTER SEQUENCE vs_code_settings_id_seq OWNED BY vs_code_settings.id; CREATE TABLE vulnerabilities ( id bigint NOT NULL, - milestone_id bigint, epic_id bigint, project_id bigint NOT NULL, author_id bigint NOT NULL, @@ -35687,8 +35687,6 @@ CREATE INDEX index_vulnerabilities_on_epic_id ON vulnerabilities USING btree (ep CREATE INDEX index_vulnerabilities_on_finding_id ON vulnerabilities USING btree (finding_id); -CREATE INDEX index_vulnerabilities_on_milestone_id ON vulnerabilities USING btree (milestone_id); - CREATE INDEX index_vulnerabilities_on_project_id_and_id ON vulnerabilities USING btree (project_id, id); CREATE INDEX index_vulnerabilities_on_project_id_and_state_and_severity ON vulnerabilities USING btree (project_id, state, severity); @@ -38056,9 +38054,6 @@ ALTER TABLE ONLY project_pages_metadata ALTER TABLE ONLY group_deletion_schedules ADD CONSTRAINT fk_11e3ebfcdd FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; -ALTER TABLE ONLY vulnerabilities - ADD CONSTRAINT fk_131d289c65 FOREIGN KEY (milestone_id) REFERENCES milestones(id) ON DELETE SET NULL; - ALTER TABLE ONLY approval_group_rules ADD CONSTRAINT fk_1485c451e3 FOREIGN KEY (scan_result_policy_id) REFERENCES scan_result_policies(id) ON DELETE CASCADE; diff --git a/doc/administration/analytics/dev_ops_reports.md b/doc/administration/analytics/dev_ops_reports.md index 057dc5d48ee..313e99c1e57 100644 --- a/doc/administration/analytics/dev_ops_reports.md +++ b/doc/administration/analytics/dev_ops_reports.md @@ -49,18 +49,18 @@ feature is available. DevOps Adoption shows feature adoption for development, security, and operations. -| Category | Feature | -| --- | --- | -| Development | Approvals
Code owners
Issues
Merge requests | -| Security | DAST
Dependency Scanning
Fuzz Testing
SAST | -| Operations | Deployments
Pipelines
Runners | +| Category | Feature | +|-------------|---------| +| Development | Approvals
Code owners
Issues
Merge requests | +| Security | DAST
Dependency Scanning
Fuzz Testing
SAST | +| Operations | Deployments
Pipelines
Runners | You can use Group DevOps Adoption to: - Identify specific subgroups that are lagging in their adoption of GitLab features, so you can guide them on -their DevOps journey. + their DevOps journey. - Find subgroups that have adopted certain features, and provide guidance to other subgroups on -how to use those features. + how to use those features. - Verify if you are getting the return on investment that you expected from GitLab. ## Add or remove a group diff --git a/doc/administration/auth/ldap/ldap-troubleshooting.md b/doc/administration/auth/ldap/ldap-troubleshooting.md index 9cd306d979f..eb1ee203469 100644 --- a/doc/administration/auth/ldap/ldap-troubleshooting.md +++ b/doc/administration/auth/ldap/ldap-troubleshooting.md @@ -774,10 +774,10 @@ If a connection can't be established, it is likely either because of a problem with your configuration or a firewall blocking the connection. - Ensure you don't have a firewall blocking the -connection, and that the LDAP server is accessible to the GitLab host. + connection, and that the LDAP server is accessible to the GitLab host. - Look for an error message in the Rake check output, which may lead to your LDAP configuration to -confirm that the configuration values (specifically `host`, `port`, `bind_dn`, and -`password`) are correct. + confirm that the configuration values (specifically `host`, `port`, `bind_dn`, and + `password`) are correct. - Look for [errors](#connection) in [the logs](#gitlab-logs) to further debug connection failures. If GitLab can successfully connect to LDAP but doesn't return any diff --git a/doc/administration/backup_restore/backup_gitlab.md b/doc/administration/backup_restore/backup_gitlab.md index 40f93a2b7de..ac04709f8b2 100644 --- a/doc/administration/backup_restore/backup_gitlab.md +++ b/doc/administration/backup_restore/backup_gitlab.md @@ -136,13 +136,13 @@ For more information, see [Backup and restore Linux package (Omnibus) configurat :::TabTitle Docker - Back up the volume where the configuration files are stored. If you created -the GitLab container according to the documentation, it should be in the -`/srv/gitlab/config` directory. + the GitLab container according to the documentation, it should be in the + `/srv/gitlab/config` directory. :::TabTitle GitLab Helm chart - Follow the [Back up the secrets](https://docs.gitlab.com/charts/backup-restore/backup.html#back-up-the-secrets) -instructions. + instructions. ::EndTabs diff --git a/doc/administration/docs_self_host.md b/doc/administration/docs_self_host.md index 5b9bfe82294..30ec21ef660 100644 --- a/doc/administration/docs_self_host.md +++ b/doc/administration/docs_self_host.md @@ -175,7 +175,7 @@ documentation URL requests as needed. For example, if your GitLab version is - The GitLab documentation URL becomes `http://0.0.0.0:4000/14.5/`. - The link in GitLab displays as `/help/administration/settings/help_page#destination-requirements`. - When you select the link, you are redirected to -`http://0.0.0.0:4000/14.5/ee/administration/settings/help_page/#destination-requirements`. + `http://0.0.0.0:4000/14.5/ee/administration/settings/help_page/#destination-requirements`. To test the setting, in GitLab, select a **Learn more** link. For example: diff --git a/doc/administration/geo/disaster_recovery/planned_failover.md b/doc/administration/geo/disaster_recovery/planned_failover.md index 01e5c33a726..1e19dc9e4c7 100644 --- a/doc/administration/geo/disaster_recovery/planned_failover.md +++ b/doc/administration/geo/disaster_recovery/planned_failover.md @@ -68,10 +68,10 @@ site: ``` 1. Copy the backup tarball generated from your primary site to the `/var/opt/gitlab/backups` folder -on your secondary site. + on your secondary site. 1. On your secondary site, restore the registry following the [Restore GitLab](../../../administration/backup_restore/index.md#restore-gitlab) -documentation. + documentation. ## Preflight checks diff --git a/doc/administration/geo/replication/location_aware_git_url.md b/doc/administration/geo/replication/location_aware_git_url.md index 6849a648991..2491b7c8bc8 100644 --- a/doc/administration/geo/replication/location_aware_git_url.md +++ b/doc/administration/geo/replication/location_aware_git_url.md @@ -51,8 +51,8 @@ In a Route53 Hosted Zone, traffic policies can be used to set up a variety of routing configurations. 1. Go to the -[Route53 dashboard](https://console.aws.amazon.com/route53/home) and select -**Traffic policies**. + [Route53 dashboard](https://console.aws.amazon.com/route53/home) and select + **Traffic policies**. ![Traffic policies](img/single_git_traffic_policies.png) diff --git a/doc/administration/geo/secondary_proxy/index.md b/doc/administration/geo/secondary_proxy/index.md index 16ae0d8606e..376f3f3958e 100644 --- a/doc/administration/geo/secondary_proxy/index.md +++ b/doc/administration/geo/secondary_proxy/index.md @@ -145,27 +145,21 @@ It does not cover all data types. In this context, accelerated reads refer to read requests served from the secondary site, provided that the data is up to date for the component on the secondary site. If the data on the secondary site is determined to be out of date, the request is forwarded to the primary site. Read requests for components not listed in the table below are always automatically forwarded to the primary site. -| Feature / component | Accelerated reads? | -|:----------------------------------------------------|:-----------------------| -| Project, wiki, design repository (using the web UI) | **{dotted-circle}** No | -| Project, wiki repository (using Git) | **{check-circle}** Yes 1 | -| Project, Personal Snippet (using the web UI) | **{dotted-circle}** No | -| Project, Personal Snippet (using Git) | **{check-circle}** Yes 1 | -| Group wiki repository (using the web UI) | **{dotted-circle}** No | -| Group wiki repository (using Git) | **{check-circle}** Yes 1 | -| User uploads | **{dotted-circle}** No | -| LFS objects (using the web UI) | **{dotted-circle}** No | -| LFS objects (using Git) | **{check-circle}** Yes | -| Pages | **{dotted-circle}** No 2 | -| Advanced search (using the web UI) | **{dotted-circle}** No | -| Container registry | **{dotted-circle}** No 3| -| Dependency Proxy | **{dotted-circle}** No 4| - -1. Git reads are served from the local secondary while pushes get proxied to the primary. - Selective sync or cases where repositories don't exist locally on the Geo secondary throw a "not found" error. -1. Pages can use the same URL (without access control), but must be configured separately and are not proxied. -1. The container registry is only recommended for Disaster Recovery scenarios. If the secondary site's container registry is not up to date, the read request is served with old data as the request is not forwarded to the primary site. -1. Read requests to a Geo secondary site's Dependency Proxy are always proxied to the primary site. +| Feature / component | Accelerated reads? | Notes | +|:----------------------------------------------------|:------------------------------------| ------------| +| Project, wiki, design repository (using the web UI) | **{dotted-circle}** No | | +| Project, wiki repository (using Git) | **{check-circle}** Yes | Git reads are served from the local secondary while pushes get proxied to the primary. Selective sync or cases where repositories don't exist locally on the Geo secondary throw a "not found" error.| +| Project, Personal Snippet (using the web UI) | **{dotted-circle}** No | | +| Project, Personal Snippet (using Git) | **{check-circle}** Yes | Git reads are served from the local secondary while pushes get proxied to the primary. Selective sync or cases where repositories don't exist locally on the Geo secondary throw a "not found" error. | +| Group wiki repository (using the web UI) | **{dotted-circle}** No | | +| Group wiki repository (using Git) | **{check-circle}** Yes | Git reads are served from the local secondary while pushes get proxied to the primary. Selective sync or cases where repositories don't exist locally on the Geo secondary throw a "not found" error. | +| User uploads | **{dotted-circle}** No | | +| LFS objects (using the web UI) | **{dotted-circle}** No | | +| LFS objects (using Git) | **{check-circle}** Yes | | +| Pages | **{dotted-circle}** No | Pages can use the same URL (without access control), but must be configured separately and are not proxied.| +| Advanced search (using the web UI) | **{dotted-circle}** No | | +| Container registry | **{dotted-circle}** No | The container registry is only recommended for Disaster Recovery scenarios. If the secondary site's container registry is not up to date, the read request is served with old data as the request is not forwarded to the primary site. Accelerating the container registry is planned, please upvote or comment in the [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/365864) to indicate your interest or ask your GitLab representative to do so on your behalf. | +| Dependency Proxy | **{dotted-circle}** No | Read requests to a Geo secondary site's Dependency Proxy are always proxied to the primary site. | ## Disable Geo proxying diff --git a/doc/administration/geo/secondary_proxy/location_aware_external_url.md b/doc/administration/geo/secondary_proxy/location_aware_external_url.md index 4ff349d8741..2f55aa27dff 100644 --- a/doc/administration/geo/secondary_proxy/location_aware_external_url.md +++ b/doc/administration/geo/secondary_proxy/location_aware_external_url.md @@ -47,8 +47,8 @@ In a Route53 Hosted Zone, traffic policies can be used to set up a variety of routing configurations. To create a traffic policy: 1. Go to the -[Route53 dashboard](https://console.aws.amazon.com/route53/home) and select -**Traffic policies**. + [Route53 dashboard](https://console.aws.amazon.com/route53/home) and select + **Traffic policies**. 1. Select **Create traffic policy**. 1. Fill in the **Policy Name** field with `Single Git Host` and select **Next**. diff --git a/doc/administration/geo/setup/database.md b/doc/administration/geo/setup/database.md index 13615825a14..b9c2a69eaf7 100644 --- a/doc/administration/geo/setup/database.md +++ b/doc/administration/geo/setup/database.md @@ -622,7 +622,7 @@ If you still haven't [migrated from repmgr to Patroni](#migrating-from-repmgr-to 1. Before migrating, you should ensure there is no replication lag between the **primary** and **secondary** sites and that replication is paused. In GitLab 13.2 and later, you can pause and resume replication with `gitlab-ctl geo-replication-pause` and `gitlab-ctl geo-replication-resume` on a Geo secondary database node. 1. Follow the [instructions to migrate repmgr to Patroni](../../postgresql/replication_and_failover.md#switching-from-repmgr-to-patroni). When configuring Patroni on each **primary** site database node, add `patroni['replication_slots'] = { '' => 'physical' }` -to `gitlab.rb` where `` is the name of the replication slot for your **secondary** site. This ensures that Patroni recognizes the replication slot as permanent and doesn't drop it upon restarting. + to `gitlab.rb` where `` is the name of the replication slot for your **secondary** site. This ensures that Patroni recognizes the replication slot as permanent and doesn't drop it upon restarting. 1. If database replication to the **secondary** site was paused before migration, resume replication after Patroni is confirmed as working on the **primary** site. ### Migrating a single PostgreSQL node to Patroni diff --git a/doc/administration/gitaly/configure_gitaly.md b/doc/administration/gitaly/configure_gitaly.md index 2cdb4ea35fc..eb620ff7413 100644 --- a/doc/administration/gitaly/configure_gitaly.md +++ b/doc/administration/gitaly/configure_gitaly.md @@ -1019,9 +1019,9 @@ meaning that unique requests do not get written into the cache. If you: - Increase this number, your cache hit rate goes down and the -cache uses less disk space. + cache uses less disk space. - Decrease this number, your cache hit -rate goes up and the cache uses more disk space. + rate goes up and the cache uses more disk space. You should set `min_occurrences` to `1`. On GitLab.com, going from 0 to 1 saved us 50% cache disk space while barely affecting diff --git a/doc/administration/gitaly/praefect.md b/doc/administration/gitaly/praefect.md index 66e220dacc2..112c441164d 100644 --- a/doc/administration/gitaly/praefect.md +++ b/doc/administration/gitaly/praefect.md @@ -949,8 +949,8 @@ You can also appoint an authoritative name server by setting it in this format: 1. Save the file and [reconfigure](../restart_gitlab.md#reconfigure-a-linux-package-installation). 1. On the Praefect clients (except Gitaly servers), edit `git_data_dirs` in -`/etc/gitlab/gitlab.rb` as follows. Replace `PRAEFECT_SERVICE_DISCOVERY_ADDRESS` -with Praefect service discovery address, such as `praefect.service.consul`. + `/etc/gitlab/gitlab.rb` as follows. Replace `PRAEFECT_SERVICE_DISCOVERY_ADDRESS` + with Praefect service discovery address, such as `praefect.service.consul`. ```ruby git_data_dirs({ diff --git a/doc/administration/logs/index.md b/doc/administration/logs/index.md index 01c7c906bfc..08f31439b26 100644 --- a/doc/administration/logs/index.md +++ b/doc/administration/logs/index.md @@ -15,8 +15,8 @@ This guide talks about how to read and use these system log files. Read more about the log system and using the logs: - [Customize logging on Linux package installations](https://docs.gitlab.com/omnibus/settings/logs.html) -including adjusting log retention, log forwarding, -switching logs from JSON to plain text logging, and more. + including adjusting log retention, log forwarding, + switching logs from JSON to plain text logging, and more. - [How to parse and analyze JSON logs](../logs/log_parsing.md). ## Log Levels diff --git a/doc/administration/logs/tracing_correlation_id.md b/doc/administration/logs/tracing_correlation_id.md index f6b341ff114..a5f6b103d1f 100644 --- a/doc/administration/logs/tracing_correlation_id.md +++ b/doc/administration/logs/tracing_correlation_id.md @@ -36,7 +36,7 @@ To locate a relevant request and view its correlation ID: 1. To help isolate the requests you are looking for, you can filter for `document` requests. 1. Select the request of interest to view further detail. 1. Go to the **Headers** section and look for **Response Headers**. There you should find an `x-request-id` header with a -value that was randomly generated by GitLab for the request. + value that was randomly generated by GitLab for the request. See the following example: diff --git a/doc/administration/monitoring/prometheus/index.md b/doc/administration/monitoring/prometheus/index.md index bd3f2a20006..1fe05ed7538 100644 --- a/doc/administration/monitoring/prometheus/index.md +++ b/doc/administration/monitoring/prometheus/index.md @@ -246,14 +246,14 @@ To use an external Prometheus server: ``` 1. To allow the Prometheus server to fetch from the [GitLab metrics](#gitlab-metrics) endpoint, add the Prometheus -server IP address to the [monitoring IP allowlist](../ip_allowlist.md): + server IP address to the [monitoring IP allowlist](../ip_allowlist.md): ```ruby gitlab_rails['monitoring_whitelist'] = ['127.0.0.0/8', '192.168.0.1'] ``` 1. As we are setting each bundled service's [exporter](#bundled-software-metrics) to listen on a network address, -update the firewall on the instance to only allow traffic from your Prometheus IP for the exporters enabled. A full reference list of exporter services and their respective ports can be found [here](../../package_information/defaults.md#ports). + update the firewall on the instance to only allow traffic from your Prometheus IP for the exporters enabled. A full reference list of exporter services and their respective ports can be found [here](../../package_information/defaults.md#ports). 1. [Reconfigure GitLab](../../restart_gitlab.md#reconfigure-a-linux-package-installation) to apply the changes. 1. Edit the Prometheus server's configuration file. 1. Add each node's exporters to the Prometheus server's diff --git a/doc/administration/object_storage.md b/doc/administration/object_storage.md index f80ea29dc13..0862921f0d7 100644 --- a/doc/administration/object_storage.md +++ b/doc/administration/object_storage.md @@ -345,7 +345,7 @@ gitlab_rails['object_store']['connection'] = { If you use ADC, be sure that: - The service account that you use has the -[`iam.serviceAccounts.signBlob` permission](https://cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/signBlob). + [`iam.serviceAccounts.signBlob` permission](https://cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/signBlob). Typically this is done by granting the `Service Account Token Creator` role to the service account. - Your virtual machines have the [correct access scopes to access Google Cloud APIs](https://cloud.google.com/compute/docs/access/create-enable-service-accounts-for-instances#changeserviceaccountandscopes). If the machines do not have the right scope, the error logs may show: @@ -897,28 +897,28 @@ When not proxying files, GitLab returns an This can result in some of the following problems: - If GitLab is using non-secure HTTP to access the object storage, clients may generate -`https->http` downgrade errors and refuse to process the redirect. The solution to this -is for GitLab to use HTTPS. LFS, for example, generates this error: + `https->http` downgrade errors and refuse to process the redirect. The solution to this + is for GitLab to use HTTPS. LFS, for example, generates this error: - ```plaintext - LFS: lfsapi/client: refusing insecure redirect, https->http - ``` + ```plaintext + LFS: lfsapi/client: refusing insecure redirect, https->http + ``` - Clients need to trust the certificate authority that issued the object storage -certificate, or may return common TLS errors such as: + certificate, or may return common TLS errors such as: - ```plaintext - x509: certificate signed by unknown authority - ``` + ```plaintext + x509: certificate signed by unknown authority + ``` - Clients need network access to the object storage. -Network firewalls could block access. -Errors that might result -if this access is not in place include: + Network firewalls could block access. + Errors that might result + if this access is not in place include: - ```plaintext - Received status code 403 from server: Forbidden - ``` + ```plaintext + Received status code 403 from server: Forbidden + ``` - Object storage buckets need to allow Cross-Origin Resource Sharing (CORS) access from the URL of the GitLab instance. Attempting to load diff --git a/doc/administration/operations/gitlab_sshd.md b/doc/administration/operations/gitlab_sshd.md index 86c6d9d7fba..a14f556af84 100644 --- a/doc/administration/operations/gitlab_sshd.md +++ b/doc/administration/operations/gitlab_sshd.md @@ -48,7 +48,7 @@ The following instructions enable `gitlab-sshd` on a different port than OpenSSH ``` 1. Optional. By default, Linux package installations generate SSH host keys for `gitlab-sshd` if -they do not exist in `/var/opt/gitlab/gitlab-sshd`. If you wish to disable this automatic generation, add this line: + they do not exist in `/var/opt/gitlab/gitlab-sshd`. If you wish to disable this automatic generation, add this line: ```ruby gitlab_sshd['generate_host_keys'] = false diff --git a/doc/administration/package_information/supported_os.md b/doc/administration/package_information/supported_os.md index 89b2f78f6d9..b85d6b8dd07 100644 --- a/doc/administration/package_information/supported_os.md +++ b/doc/administration/package_information/supported_os.md @@ -28,7 +28,6 @@ architecture. | Debian 10 | GitLab CE / GitLab EE 12.2.0 | amd64, arm64 | [Debian Install Documentation](https://about.gitlab.com/install/#debian) | 2024 | | | Debian 11 | GitLab CE / GitLab EE 14.6.0 | amd64, arm64 | [Debian Install Documentation](https://about.gitlab.com/install/#debian) | 2026 | | | Debian 12 | GitLab CE / GitLab EE 16.1.0 | amd64, arm64 | [Debian Install Documentation](https://about.gitlab.com/install/#debian) | TBD | | -| OpenSUSE 15.4 | GitLab CE / GitLab EE 15.7.0 | x86_64, aarch64 | [OpenSUSE Install Documentation](https://about.gitlab.com/install/#opensuse-leap) | Nov 2023 | | | OpenSUSE 15.5 | GitLab CE / GitLab EE 16.4.0 | x86_64, aarch64 | [OpenSUSE Install Documentation](https://about.gitlab.com/install/#opensuse-leap) | Dec 2024 | | | RHEL 8 | GitLab CE / GitLab EE 12.8.1 | x86_64, arm64 | [Use CentOS Install Documentation](https://about.gitlab.com/install/#centos-7) | May 2029 | [RHEL Details](https://access.redhat.com/support/policy/updates/errata/#Life_Cycle_Dates) | | RHEL 9 | GitLab CE / GitLab EE 16.0.0 | x86_64, arm64 | [Use CentOS Install Documentation](https://about.gitlab.com/install/#centos-7) | May 2032 | [RHEL Details](https://access.redhat.com/support/policy/updates/errata/#Life_Cycle_Dates) | @@ -106,12 +105,13 @@ release for them can be found below: | Raspbian Stretch | [June 2020](https://downloads.raspberrypi.org/raspbian/images/raspbian-2019-04-09/) | [GitLab CE](https://packages.gitlab.com/app/gitlab/raspberry-pi2/search?q=gitlab-ce_13.3&dist=raspbian%2Fstretch) 13.3 | | Debian Jessie | [June 2020](https://www.debian.org/News/2020/20200709) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce_13.2&dist=debian%2Fjessie) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee_13.2&dist=debian%2Fjessie) 13.3 | | CentOS 6 | [November 2020](https://wiki.centos.org/About/Product) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=13.6&filter=all&filter=all&dist=el%2F6) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=13.6&filter=all&filter=all&dist=el%2F6) 13.6 | -| CentOS 8 | [December 2021](https://wiki.centos.org/About/Product) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=14.6&filter=all&filter=all&dist=el%2F8) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=14.6&filter=all&filter=all&dist=el%2F8) 14.6 | +| CentOS 8 | [December 2021](https://wiki.centos.org/About/Product) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=14.6&filter=all&filter=all&dist=el%2F8) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=14.6&filter=all&filter=all&dist=el%2F8) 14.6 | | OpenSUSE 15.1 | [November 2020](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-13.12&dist=opensuse%2F15.1) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-13.12&dist=opensuse%2F15.1) 13.12 | | Ubuntu 16.04 | [April 2021](https://ubuntu.com/info/release-end-of-life) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce_13.12&dist=ubuntu%2Fxenial) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee_13.12&dist=ubuntu%2Fxenial) 13.12 | | OpenSUSE 15.2 | [December 2021](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-14.7&dist=opensuse%2F15.2) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-14.7&dist=opensuse%2F15.2) 14.7 | | Debian 9 "Stretch" | [June 2022](https://lists.debian.org/debian-lts-announce/2022/07/msg00002.html) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce_15.2&dist=debian%2Fstretch) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee_15.2&dist=debian%2Fstretch) 15.2 | -| OpenSUSE 15.3 | [December 2022](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-15.10&dist=opensuse%2F15.3) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-15.10&dist=opensuse%2F15.3) 15.10 | +| OpenSUSE 15.3 | [December 2022](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-15.10&dist=opensuse%2F15.3) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-15.10&dist=opensuse%2F15.3) 15.10 | +| OpenSUSE 15.4 | [December 2023](https://en.opensuse.org/Lifetime#Discontinued_distributions) | [GitLab CE](https://packages.gitlab.com/app/gitlab/gitlab-ce/search?q=gitlab-ce-16.7&dist=opensuse%2F15.4) / [GitLab EE](https://packages.gitlab.com/app/gitlab/gitlab-ee/search?q=gitlab-ee-16.7&dist=opensuse%2F15.4) 16.7 | NOTE: An exception to this deprecation policy is when we are unable to provide diff --git a/doc/administration/pages/index.md b/doc/administration/pages/index.md index ad3718b90b2..150e0115eb7 100644 --- a/doc/administration/pages/index.md +++ b/doc/administration/pages/index.md @@ -249,7 +249,7 @@ outside world. ``` 1. If you haven't named your certificate and key `example.io.crt` and `example.io.key`, -you must also add the full paths as shown below: + you must also add the full paths as shown below: ```ruby pages_nginx['ssl_certificate'] = "/etc/gitlab/ssl/pages-nginx.crt" @@ -258,8 +258,8 @@ you must also add the full paths as shown below: 1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation). 1. If you're using [Pages Access Control](#access-control), update the redirect URI in the GitLab Pages -[System OAuth application](../../integration/oauth_provider.md#create-an-instance-wide-application) -to use the HTTPS protocol. + [System OAuth application](../../integration/oauth_provider.md#create-an-instance-wide-application) + to use the HTTPS protocol. WARNING: Multiple wildcards for one instance is not supported. Only one wildcard per instance can be assigned. @@ -517,7 +517,7 @@ world. Custom domains and TLS are supported. If you don't have IPv6, you can omit the IPv6 address. 1. If you haven't named your certificate `example.io.crt` and your key `example.io.key`, -then you need to also add the full paths as shown below: + then you need to also add the full paths as shown below: ```ruby gitlab_pages['cert'] = "/etc/gitlab/ssl/example.io.crt" @@ -526,8 +526,8 @@ then you need to also add the full paths as shown below: 1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation). 1. If you're using [Pages Access Control](#access-control), update the redirect URI in the GitLab Pages -[System OAuth application](../../integration/oauth_provider.md#create-an-instance-wide-application) -to use the HTTPS protocol. + [System OAuth application](../../integration/oauth_provider.md#create-an-instance-wide-application) + to use the HTTPS protocol. ### Custom domain verification @@ -1011,25 +1011,20 @@ Valid time units are `ns`, `us` (or `µs`), `ms`, `s`, `m`, `h`. Examples: - Increasing `gitlab_cache_expiry` allows items to exist in the cache longer. -This setting might be useful if the communication between GitLab Pages and GitLab Rails -is not stable. - + This setting might be useful if the communication between GitLab Pages and GitLab Rails + is not stable. - Increasing `gitlab_cache_refresh` reduces the frequency at which GitLab Pages -requests a domain's configuration from GitLab Rails. This setting might be useful -GitLab Pages generates too many requests to GitLab API and content does not change frequently. - + requests a domain's configuration from GitLab Rails. This setting might be useful + GitLab Pages generates too many requests to GitLab API and content does not change frequently. - Decreasing `gitlab_cache_cleanup` removes expired items from the cache more frequently, -reducing the memory usage of your Pages node. - + reducing the memory usage of your Pages node. - Decreasing `gitlab_retrieval_timeout` allows you to stop the request to GitLab Rails -more quickly. Increasing it allows more time to receive a response from the API, -useful in slow networking environments. - + more quickly. Increasing it allows more time to receive a response from the API, + useful in slow networking environments. - Decreasing `gitlab_retrieval_interval` makes requests to the API more frequently, -only when there is an error response from the API, for example a connection timeout. - + only when there is an error response from the API, for example a connection timeout. - Decreasing `gitlab_retrieval_retries` reduces the number of times a domain's -configuration is tried to be resolved automatically before reporting an error. + configuration is tried to be resolved automatically before reporting an error. ## Object storage settings diff --git a/doc/administration/raketasks/maintenance.md b/doc/administration/raketasks/maintenance.md index c9082ea826c..21a7ba258c1 100644 --- a/doc/administration/raketasks/maintenance.md +++ b/doc/administration/raketasks/maintenance.md @@ -400,15 +400,13 @@ To manually rebuild a database index: ### Notes - Rebuilding database indexes is a disk-intensive task, so you should perform the -task during off-peak hours. Running the task during peak hours can lead to -_increased_ bloat, and can also cause certain queries to perform slowly. - + task during off-peak hours. Running the task during peak hours can lead to + _increased_ bloat, and can also cause certain queries to perform slowly. - The task requires free disk space for the index being restored. The created -indexes are appended with `_ccnew`. If the reindexing task fails, re-running the -task cleans up the temporary indexes. - + indexes are appended with `_ccnew`. If the reindexing task fails, re-running the + task cleans up the temporary indexes. - The time it takes for database index rebuilding to complete depends on the size -of the target database. It can take between several hours and several days. + of the target database. It can take between several hours and several days. ## Dump the database schema diff --git a/doc/administration/reference_architectures/10k_users.md b/doc/administration/reference_architectures/10k_users.md index 14ee3f69a6b..f4492488a23 100644 --- a/doc/administration/reference_architectures/10k_users.md +++ b/doc/administration/reference_architectures/10k_users.md @@ -2270,7 +2270,7 @@ the overall makeup as desired as long as the minimum CPU and Memory requirements | Supporting services | 2 | 4 vCPU, 15 GB memory | `n1-standard-4` | `m5.xlarge` | 7.75 vCPU, 25 GB memory | - For this setup, we **recommend** and regularly [test](index.md#validation-and-test-results) -[Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) and [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/). Other Kubernetes services may also work, but your mileage may vary. + [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) and [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/). Other Kubernetes services may also work, but your mileage may vary. - Nodes configuration is shown as it is forced to ensure pod vCPU / memory ratios and avoid scaling during **performance testing**. - In production deployments, there is no need to assign pods to specific nodes. A minimum of three nodes per node group in three different availability zones is strongly recommended to align with resilient cloud architecture practices. diff --git a/doc/administration/reference_architectures/25k_users.md b/doc/administration/reference_architectures/25k_users.md index d05be844604..21a21370c8f 100644 --- a/doc/administration/reference_architectures/25k_users.md +++ b/doc/administration/reference_architectures/25k_users.md @@ -1505,7 +1505,7 @@ Updates to example must be made at: ``` 1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace -the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step. + the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step. 1. Praefect requires to run some database migrations, much like the main GitLab application. For this you should select **one Praefect node only to run the migrations**, AKA the _Deploy Node_. This node @@ -2280,7 +2280,7 @@ the overall makeup as desired as long as the minimum CPU and Memory requirements | Supporting services | 2 | 4 vCPU, 15 GB memory | `n1-standard-4` | `m5.xlarge` | 7.75 vCPU, 25 GB memory | - For this setup, we **recommend** and regularly [test](index.md#validation-and-test-results) -[Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) and [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/). Other Kubernetes services may also work, but your mileage may vary. + [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) and [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/). Other Kubernetes services may also work, but your mileage may vary. - Nodes configuration is shown as it is forced to ensure pod vCPU / memory ratios and avoid scaling during **performance testing**. - In production deployments, there is no need to assign pods to specific nodes. A minimum of three nodes per node group in three different availability zones is strongly recommended to align with resilient cloud architecture practices. diff --git a/doc/administration/reference_architectures/2k_users.md b/doc/administration/reference_architectures/2k_users.md index b51631adb3c..e856a6a48a8 100644 --- a/doc/administration/reference_architectures/2k_users.md +++ b/doc/administration/reference_architectures/2k_users.md @@ -1101,7 +1101,7 @@ the overall makeup as desired as long as the minimum CPU and Memory requirements | Supporting services | 2 | 2 vCPU, 7.5 GB memory | `n1-standard-2` | `m5.large` | 1.9 vCPU, 5.5 GB memory | - For this setup, we **recommend** and regularly [test](index.md#validation-and-test-results) -[Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) and [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/). Other Kubernetes services may also work, but your mileage may vary. + [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) and [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/). Other Kubernetes services may also work, but your mileage may vary. - Nodes configuration is shown as it is forced to ensure pod vCPU / memory ratios and avoid scaling during **performance testing**. - In production deployments, there is no need to assign pods to specific nodes. A minimum of three nodes per node group in three different availability zones is strongly recommended to align with resilient cloud architecture practices. diff --git a/doc/administration/reference_architectures/3k_users.md b/doc/administration/reference_architectures/3k_users.md index 75a79f0c644..9cfe0f2e3f6 100644 --- a/doc/administration/reference_architectures/3k_users.md +++ b/doc/administration/reference_architectures/3k_users.md @@ -1423,7 +1423,7 @@ Updates to example must be made at: ``` 1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace -the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step. + the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step. 1. Praefect requires to run some database migrations, much like the main GitLab application. For this you should select **one Praefect node only to run the migrations**, AKA the _Deploy Node_. This node @@ -2257,7 +2257,7 @@ the overall makeup as desired as long as the minimum CPU and Memory requirements | Supporting services | 2 | 2 vCPU, 7.5 GB memory | `n1-standard-2` | `m5.large` | 3.9 vCPU, 11.8 GB memory | - For this setup, we **recommend** and regularly [test](index.md#validation-and-test-results) -[Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) and [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/). Other Kubernetes services may also work, but your mileage may vary. + [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) and [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/). Other Kubernetes services may also work, but your mileage may vary. - Nodes configuration is shown as it is forced to ensure pod vCPU / memory ratios and avoid scaling during **performance testing**. - In production deployments, there is no need to assign pods to specific nodes. A minimum of three nodes per node group in three different availability zones is strongly recommended to align with resilient cloud architecture practices. diff --git a/doc/administration/reference_architectures/50k_users.md b/doc/administration/reference_architectures/50k_users.md index 5e47904c008..76428598d96 100644 --- a/doc/administration/reference_architectures/50k_users.md +++ b/doc/administration/reference_architectures/50k_users.md @@ -1511,7 +1511,7 @@ Updates to example must be made at: ``` 1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace -the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step. + the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step. 1. Praefect requires to run some database migrations, much like the main GitLab application. For this you should select **one Praefect node only to run the migrations**, AKA the _Deploy Node_. This node @@ -2290,7 +2290,7 @@ the overall makeup as desired as long as the minimum CPU and Memory requirements | Supporting services | 2 | 4 vCPU, 15 GB memory | `n1-standard-4` | `m5.xlarge` | 7.75 vCPU, 25 GB memory | - For this setup, we **recommend** and regularly [test](index.md#validation-and-test-results) -[Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) and [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/). Other Kubernetes services may also work, but your mileage may vary. + [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) and [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/). Other Kubernetes services may also work, but your mileage may vary. - Nodes configuration is shown as it is forced to ensure pod vCPU / memory ratios and avoid scaling during **performance testing**. - In production deployments, there is no need to assign pods to specific nodes. A minimum of three nodes per node group in three different availability zones is strongly recommended to align with resilient cloud architecture practices. diff --git a/doc/administration/reference_architectures/5k_users.md b/doc/administration/reference_architectures/5k_users.md index d479bcf3bec..2b3d928d8f6 100644 --- a/doc/administration/reference_architectures/5k_users.md +++ b/doc/administration/reference_architectures/5k_users.md @@ -1423,7 +1423,7 @@ Updates to example must be made at: ``` 1. Copy the `/etc/gitlab/gitlab-secrets.json` file from the first Linux package node you configured and add or replace -the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step. + the file of the same name on this server. If this is the first Linux package node you are configuring then you can skip this step. 1. Praefect requires to run some database migrations, much like the main GitLab application. For this you should select **one Praefect node only to run the migrations**, AKA the _Deploy Node_. This node @@ -2232,7 +2232,7 @@ the overall makeup as desired as long as the minimum CPU and Memory requirements | Supporting services | 2 | 2 vCPU, 7.5 GB memory | `n1-standard-2` | `m5.large` | 3.9 vCPU, 11.8 GB memory | - For this setup, we **recommend** and regularly [test](index.md#validation-and-test-results) -[Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) and [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/). Other Kubernetes services may also work, but your mileage may vary. + [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) and [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/). Other Kubernetes services may also work, but your mileage may vary. - Nodes configuration is shown as it is forced to ensure pod vCPU / memory ratios and avoid scaling during **performance testing**. - In production deployments, there is no need to assign pods to nodes. A minimum of three nodes in three different availability zones is strongly recommended to align with resilient cloud architecture practices. diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index f17d9794568..bdfa8137c70 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -15589,8 +15589,6 @@ four standard [pagination arguments](#connection-pagination-arguments): | `path` **{warning-solid}** | [`String`](#string) | **Introduced** in 16.8. This feature is an Experiment. It can be changed or removed at any time. Relative web path to the version. | | `readmeHtml` **{warning-solid}** | [`String`](#string) | **Introduced** in 16.8. This feature is an Experiment. It can be changed or removed at any time. GitLab Flavored Markdown rendering of README.md. This field can only be resolved for one version in any single request. | | `releasedAt` **{warning-solid}** | [`Time`](#time) | **Introduced** in 16.7. This feature is an Experiment. It can be changed or removed at any time. Timestamp of when the version was released. | -| `tagName` **{warning-solid}** | [`String`](#string) | **Introduced** in 16.7. This feature is an Experiment. It can be changed or removed at any time. Deprecated in 16.8. Use name. | -| `tagPath` **{warning-solid}** | [`String`](#string) | **Introduced** in 16.7. This feature is an Experiment. It can be changed or removed at any time. Deprecated in 16.8. Use path. | ### `CiConfig` diff --git a/doc/ci/runners/configure_runners.md b/doc/ci/runners/configure_runners.md index 3b21d865d8b..6212c07ce47 100644 --- a/doc/ci/runners/configure_runners.md +++ b/doc/ci/runners/configure_runners.md @@ -903,18 +903,41 @@ variables: | `CACHE_COMPRESSION_LEVEL` | To adjust compression ratio, set to `fastest`, `fast`, `default`, `slow`, or `slowest`. This setting works with the Fastzip archiver only, so the GitLab Runner feature flag [`FF_USE_FASTZIP`](https://docs.gitlab.com/runner/configuration/feature-flags.html#available-feature-flags) must also be enabled. | | `CACHE_REQUEST_TIMEOUT` | Configure the maximum duration of cache upload and download operations for a single job in minutes. Default is `10` minutes. | -## Artifact attestation +## Artifact provenance metadata > [Introduced](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/28940) in GitLab Runner 15.1. NOTE: Zip archives are the only supported artifact type. Follow [the issue for details](https://gitlab.com/gitlab-org/gitlab/-/issues/367203). -GitLab Runner can generate and produce attestation metadata for all build artifacts. To enable this feature, you must set the `RUNNER_GENERATE_ARTIFACTS_METADATA` environment variable to `true`. This variable can either be set globally or it can be set for individual jobs. The metadata is in rendered in a plain text `.json` file that's stored with the artifact. The file name is as follows: `{ARTIFACT_NAME}-metadata.json` where `ARTIFACT_NAME` is what was defined as the [name for the artifact](../jobs/job_artifacts.md#with-a-dynamically-defined-name) in the CI file. The file name, however, defaults to `artifacts-metadata.json` if no name was given to the build artifacts. +Runners can generate and produce provenance metadata for all build artifacts. -### Attestation format +To enable artifact provenance data, set the `RUNNER_GENERATE_ARTIFACTS_METADATA` environment +variable to `true`. You can set the variable as global or for individual jobs: -The attestation metadata is generated in the [in-toto attestation format](https://github.com/in-toto/attestation) for spec version [v0.1](https://github.com/in-toto/attestation/tree/v0.1.0/spec). The following fields are populated by default: +```yaml +variables: + RUNNER_GENERATE_ARTIFACTS_METADATA: "true" + +job1: + variables: + RUNNER_GENERATE_ARTIFACTS_METADATA: "true" +``` + +The metadata renders in a plain text `.json` file stored with the artifact. The +file name is `{ARTIFACT_NAME}-metadata.json`. `ARTIFACT_NAME` is the +[name for the artifact](../jobs/job_artifacts.md#with-a-dynamically-defined-name) +defined in the `.gitlab-ci.yml` file. If the name is not defined, the default file name is +`artifacts-metadata.json`. + +### Provenance metadata format + +The provenance metadata is generated in the [in-toto attestation format](https://github.com/in-toto/attestation) for spec version [0.1](https://github.com/in-toto/attestation/tree/v0.1.0/spec). +The runner also produces a statement that adheres to SLSA v0.2 by default. + +To opt-in to an SLSA v1.0 statement, set the `SLSA_PROVENANCE_SCHEMA_VERSION=v1` variable in the `.gitlab-ci.yml` file. The v0.2 statement is deprecated and is planned to be removed in the GitLab 17.0 and the v1.0 statement is planned to become the new default format. + +The following fields are populated by default: | Field | Value | | ------ | ------ | @@ -938,7 +961,7 @@ The attestation metadata is generated in the [in-toto attestation format](https: | `metadata.completeness.environment` | Whether the builder's environment is reported. Always `true`. | | `metadata.completeness.materials` | Whether the build materials are reported. Always `false`. | -An example of an attestation that the GitLab Runner might generate is as follows: +An example of provenance metadata that the GitLab Runner might generate is as follows: ```yaml { diff --git a/doc/development/contributing/index.md b/doc/development/contributing/index.md index 2c8b5b2af20..d4541558d23 100644 --- a/doc/development/contributing/index.md +++ b/doc/development/contributing/index.md @@ -134,6 +134,14 @@ Lastly, keep the following in mind when submitting merge requests: be merged, as well as some guidance. The maintainers will be open to discussion about how to change the code so it can be approved and merged in the future. +## Tips + +- [Small MRs are the main key to a great review](https://about.gitlab.com/blog/2021/03/18/iteration-and-code-review/). +- Make sure to read our [merge request guidelines for contributors before you start for the first time](merge_request_workflow.md#merge-request-guidelines-for-contributors). +- Automated testing is required. Take your time to understand the different [testing levels](../testing_guide/testing_levels.md#how-to-test-at-the-correct-level) and apply them accordingly. +- Make sure to have a great description that includes steps to reproduce your implementation. +- [Make sure to follow our commit message guidelines](merge_request_workflow.md#commit-messages-guidelines). + ## Closing policy for issues and merge requests - For the criteria for closing issues, see [the Issue Triage handbook page](https://about.gitlab.com/handbook/engineering/quality/issue-triage/#outdated-issues). diff --git a/doc/install/aws/index.md b/doc/install/aws/index.md index 6ed3368fb45..25b52c9003c 100644 --- a/doc/install/aws/index.md +++ b/doc/install/aws/index.md @@ -725,13 +725,13 @@ From the EC2 dashboard: 1. We leave our **Health Check Grace Period** as the default `300` seconds. Select **Configure scaling policies**. 1. Check **Use scaling policies to adjust the capacity of this group**. 1. For this group we scale between 2 and 4 instances where one instance is added if CPU -utilization is greater than 60% and one instance is removed if it falls -to less than 45%. + utilization is greater than 60% and one instance is removed if it falls + to less than 45%. ![Auto scaling group policies](img/policies.png) 1. Finally, configure notifications and tags as you see fit, review your changes, and create the -auto scaling group. + auto scaling group. As the auto scaling group is created, you see your new instances spinning up in your EC2 dashboard. You also see the new instances added to your load balancer. After the instances pass the heath check, they are ready to start receiving traffic from the load balancer. diff --git a/doc/install/docker.md b/doc/install/docker.md index 51b3aa28396..76e5b9bd7b3 100644 --- a/doc/install/docker.md +++ b/doc/install/docker.md @@ -531,7 +531,7 @@ To upgrade GitLab that was [installed using Docker Engine](#install-gitlab-using ``` 1. Create the container once again with the -[previously specified](#install-gitlab-using-docker-engine) options: + [previously specified](#install-gitlab-using-docker-engine) options: ```shell sudo docker run --detach \ diff --git a/doc/install/requirements.md b/doc/install/requirements.md index e3905dd4882..bad3a2b09e7 100644 --- a/doc/install/requirements.md +++ b/doc/install/requirements.md @@ -232,8 +232,8 @@ The recommended number of threads is dependent on several factors, including tot - If the operating system has a maximum 2 GB of memory, the recommended number of threads is `1`. A higher value results in excess swapping, and decrease performance. - In all other cases, the recommended number of threads is `4`. We don't recommend setting this -higher, due to how [Ruby MRI multi-threading](https://en.wikipedia.org/wiki/Global_interpreter_lock) -works. + higher, due to how [Ruby MRI multi-threading](https://en.wikipedia.org/wiki/Global_interpreter_lock) + works. ### Puma per worker maximum memory diff --git a/doc/security/two_factor_authentication.md b/doc/security/two_factor_authentication.md index c7d6796a212..80b6988b1b1 100644 --- a/doc/security/two_factor_authentication.md +++ b/doc/security/two_factor_authentication.md @@ -49,6 +49,21 @@ Use the [application settings API](../api/settings.md) to modify the following s For more information, see the [list of settings that can be accessed through API calls](../api/settings.md#list-of-settings-that-can-be-accessed-via-api-calls). +## Enforce 2FA for Administrator users **(FREE SELF)** + +Administrators can enforce 2FA for administrator users in a self-managed instance. + +1. On the left sidebar, at the bottom, select **Admin Area**. +1. On the left sidebar, select **Settings > General**. +1. Expand the **Sign-in restrictions** section: + - Select **Require administrators to enable 2FA**. + - In **Two-factor grace period**, enter a number of hours. If you want to + enforce 2FA on the next sign-in attempt, enter `0`. +1. Select **Save changes**. + +NOTE: +If you are using an external provider to sign in into GitLab, this setting will **not** enforce 2FA for users. 2FA should be enabled on that external provider. + ## Enforce 2FA for all users in a group **(FREE ALL)** > [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/24965) in GitLab 12.0, 2FA settings for a group are also applied to subgroups. diff --git a/doc/subscriptions/customers_portal.md b/doc/subscriptions/customers_portal.md index 9b669460e80..865dcf99515 100644 --- a/doc/subscriptions/customers_portal.md +++ b/doc/subscriptions/customers_portal.md @@ -16,7 +16,7 @@ If you made your purchase through an authorized reseller, you must contact them ## Sign in to Customers Portal -You can sign in to Customers Portal either with your GitLab.com account or your email and password (if you have not yet [linked your Customers Portal account to your GitLab.com account](#link-a-gitlabcom-account)). +You can sign in to Customers Portal either with your GitLab.com account or a one-time sign-in link sent to your email (if you have not yet [linked your Customers Portal account to your GitLab.com account](#link-a-gitlabcom-account)). NOTE: If you registered for Customers Portal with your GitLab.com account, sign in with this account. @@ -157,11 +157,12 @@ method as the default: ## Link a GitLab.com account -Follow this guideline if you have a legacy Customers Portal profile and use an email and password to log in. +Follow this guideline if you have a legacy Customers Portal profile to log in. To link a GitLab.com account to your Customers Portal profile: -1. Sign in to the [Customers Portal](https://customers.gitlab.com/customers/sign_in?legacy=true) using email and password. +1. Trigger a one-time sign-in link to your email from the [Customers Portal](https://customers.gitlab.com/customers/sign_in?legacy=true). +1. Locate the email and click on the one-time sign-in link to log into your Customers Portal account. 1. Select **My profile > Profile settings**. 1. Under **Your GitLab.com account**, select **Link account**. 1. Sign in to the [GitLab.com](https://gitlab.com/users/sign_in) account you want to link to the Customers Portal profile. @@ -170,7 +171,7 @@ To link a GitLab.com account to your Customers Portal profile: Customers are required to use their GitLab.com account to register for a new Customers Portal profile. -If you have a legacy Customers Portal profile that is not linked to a GitLab.com account, you may still [sign in](https://customers.gitlab.com/customers/sign_in?legacy=true) using an email and password. However, you should [create](https://gitlab.com/users/sign_up) and [link a GitLab.com account](#change-the-linked-account) to ensure continued access to the Customers Portal. +If you have a legacy Customers Portal profile that is not linked to a GitLab.com account, you may still [sign in](https://customers.gitlab.com/customers/sign_in?legacy=true) using a one-time sign-in link sent to your email. However, you should [create](https://gitlab.com/users/sign_up) and [link a GitLab.com account](#change-the-linked-account) to ensure continued access to the Customers Portal. To change the GitLab.com account linked to your Customers Portal profile: diff --git a/doc/update/background_migrations.md b/doc/update/background_migrations.md index 8f7e4cc7b1d..0cd622f68ee 100644 --- a/doc/update/background_migrations.md +++ b/doc/update/background_migrations.md @@ -445,17 +445,17 @@ If you have, you can [manually finish the batched background migration](#finish- If you haven't, choose one of the following methods: 1. [Rollback and upgrade](#roll-back-and-follow-the-required-upgrade-path) through one of the required -versions before updating to 14.2+. + versions before updating to 14.2+. 1. [Roll forward](#roll-forward-and-finish-the-migrations-on-the-upgraded-version), staying on the current -version and manually ensuring that the batched migrations complete successfully. + version and manually ensuring that the batched migrations complete successfully. #### Roll back and follow the required upgrade path 1. [Rollback and restore the previously installed version](../administration/backup_restore/index.md) 1. Update to either 14.0.5 or 14.1 **before** updating to 14.2+ 1. [Check the status](#check-the-status-of-batched-background-migrations) of the batched background migrations and -make sure they are all marked as finished before attempting to upgrade again. If any remain marked as active, -you can [manually finish them](#finish-a-failed-migration-manually). + make sure they are all marked as finished before attempting to upgrade again. If any remain marked as active, + you can [manually finish them](#finish-a-failed-migration-manually). #### Roll forward and finish the migrations on the upgraded version @@ -465,8 +465,8 @@ To run all the batched background migrations, it can take a significant amount o depending on the size of your GitLab installation. 1. [Check the status](#check-the-status-of-batched-background-migrations) of the batched background migrations in the -database, and [manually run them](#finish-a-failed-migration-manually) with the appropriate -arguments until the status query returns no rows. + database, and [manually run them](#finish-a-failed-migration-manually) with the appropriate + arguments until the status query returns no rows. 1. When the status of all of all them is marked as complete, re-run migrations for your installation. 1. [Complete the database migrations](../administration/raketasks/maintenance.md#run-incomplete-database-migrations) from your GitLab upgrade: @@ -488,8 +488,8 @@ As the failing migrations are post-deployment migrations, you can remain on a ru version and wait for the batched background migrations to finish. 1. [Check the status](#check-the-status-of-batched-background-migrations) of the batched background migration from -the error message, and make sure it is listed as finished. If it is still active, either wait until it is done, -or [manually finish it](#finish-a-failed-migration-manually). + the error message, and make sure it is listed as finished. If it is still active, either wait until it is done, + or [manually finish it](#finish-a-failed-migration-manually). 1. Re-run migrations for your installation, so the remaining post-deployment migrations finish. ### The `BackfillNamespaceIdForNamespaceRoute` batched migration job fails diff --git a/doc/update/deprecations.md b/doc/update/deprecations.md index 80cebf268e2..f1a319b863f 100644 --- a/doc/update/deprecations.md +++ b/doc/update/deprecations.md @@ -124,6 +124,24 @@ Before upgrading to GitLab 18.0, please ensure you have [migrated](https://docs.
+### Slack notifications integration + +
+- Announced in GitLab 15.9 +- Removal in GitLab 18.0 ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change)) +- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/435909). +
+ +As we're consolidating all Slack capabilities into the +GitLab for Slack app, we've deprecated the Slack notifications +integration. +Use the GitLab for Slack app to manage notifications +to your Slack workspace. + +
+ +
+ ### Support for REST API endpoints that reset runner registration tokens
@@ -595,6 +613,20 @@ are deprecated and will be removed from the GraphQL API. For installation instru
+### GitLab Runner provenance metadata SLSA v0.2 statement + +
+- Announced in GitLab 16.8 +- Removal in GitLab 17.0 ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change)) +- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/36869). +
+ +Runners generate provenance metadata and currently defaults to generating statements that adhere to SLSA v0.2. Because SLSA v1.0 has been released and is now supported by GitLab, the v0.2 statement is now deprecated and removal is planned in GitLab 17.0. The SLSA v1.0 statement is planned to become the new default statement format in GitLab 17.0. + +
+ +
+ ### GraphQL deprecation of `dependencyProxyTotalSizeInBytes` field
@@ -1115,25 +1147,6 @@ automatically from GitLab 16.0 onwards.
-### Slack notifications integration - -
-- Announced in GitLab 15.9 -- Removal in GitLab 17.0 ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change)) -- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/372411). -
- -As we're consolidating all Slack capabilities into the -GitLab for Slack app, we're [deprecating the Slack notifications -integration](https://gitlab.com/gitlab-org/gitlab/-/issues/372411). -GitLab.com users can now use the GitLab for Slack app to manage notifications -to their Slack workspace. For self-managed users of the Slack notifications integration, -we'll be introducing support in [this epic](https://gitlab.com/groups/gitlab-org/-/epics/1211). - -
- -
- ### The GitHub importer Rake task
diff --git a/doc/update/versions/gitlab_14_changes.md b/doc/update/versions/gitlab_14_changes.md index fd58d24790a..4d82ce86fed 100644 --- a/doc/update/versions/gitlab_14_changes.md +++ b/doc/update/versions/gitlab_14_changes.md @@ -144,9 +144,10 @@ For more information about upgrading GitLab Helm Chart, see [the release notes f 1. Add `gitlab_kas['enable'] = false` to `gitlab.rb`. 1. If the server is already upgraded to 14.8, run `gitlab-ctl reconfigure`. + - GitLab 14.8.0 includes a -[background migration `PopulateTopicsNonPrivateProjectsCount`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79140) -that may remain stuck permanently in a **pending** state. + [background migration `PopulateTopicsNonPrivateProjectsCount`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79140) + that may remain stuck permanently in a **pending** state. To clean up this stuck job, run the following in the [GitLab Rails Console](../../administration/operations/rails_console.md): @@ -305,8 +306,8 @@ that may remain stuck permanently in a **pending** state. ### Self-compiled installations - When `make` is run, Gitaly builds are now created in `_build/bin` and no longer in the root directory of the source directory. If you -are using a self-compiled installation, update paths to these binaries in your [systemd unit files](../upgrading_from_source.md#configure-systemd-units) -or [init scripts](../upgrading_from_source.md#configure-sysv-init-script) by [following the documentation](../upgrading_from_source.md). + are using a self-compiled installation, update paths to these binaries in your [systemd unit files](../upgrading_from_source.md#configure-systemd-units) + or [init scripts](../upgrading_from_source.md#configure-sysv-init-script) by [following the documentation](../upgrading_from_source.md). ### Geo installations **(PREMIUM SELF)** @@ -363,8 +364,8 @@ or [init scripts](../upgrading_from_source.md#configure-sysv-init-script) by [fo We recommend moving your databases from Aurora to RDS for PostgreSQL before upgrading. Refer to [Moving GitLab databases to a different PostgreSQL instance](../../administration/postgresql/moving.md). - GitLab 14.4.0 includes a -[background migration `PopulateTopicsTotalProjectsCountCache`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71033) -that may remain stuck permanently in a **pending** state when the instance lacks records that match the migration's target. + [background migration `PopulateTopicsTotalProjectsCountCache`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71033) + that may remain stuck permanently in a **pending** state when the instance lacks records that match the migration's target. To clean up this stuck job, run the following in the [GitLab Rails Console](../../administration/operations/rails_console.md): diff --git a/doc/update/versions/gitlab_15_changes.md b/doc/update/versions/gitlab_15_changes.md index 7440c701509..203d13a20e6 100644 --- a/doc/update/versions/gitlab_15_changes.md +++ b/doc/update/versions/gitlab_15_changes.md @@ -597,7 +597,7 @@ A [license caching issue](https://gitlab.com/gitlab-org/gitlab/-/issues/376706) ## 15.3.3 - In GitLab 15.3.3, [SAML Group Links](../../api/groups.md#saml-group-links) API `access_level` attribute type changed to `integer`. See -[the API documentation](../../api/members.md). + [the API documentation](../../api/members.md). - A [license caching issue](https://gitlab.com/gitlab-org/gitlab/-/issues/376706) prevents some premium features of GitLab from working correctly if you add a new license. Workarounds for this issue: - Restart all Rails, Sidekiq and Gitaly nodes after applying a new license. This clears the relevant license caches and allows all premium features to operate correctly. diff --git a/doc/update/versions/gitlab_16_changes.md b/doc/update/versions/gitlab_16_changes.md index 8efa056e70d..4948db7bd29 100644 --- a/doc/update/versions/gitlab_16_changes.md +++ b/doc/update/versions/gitlab_16_changes.md @@ -85,10 +85,34 @@ Specific information applies to Linux package installations: - All sites are running PostgreSQL 13: Install the new Geo secondary site with [pinned PostgreSQL version 13](https://docs.gitlab.com/omnibus/settings/database.html#pin-the-packaged-postgresql-version-fresh-installs-only). - All sites are running PostgreSQL 14: No special action is required. +- You might experience verification failures on a subset of projects due to checksum mismatch between the primary site and the secondary site. The details are tracked in this [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/427493). There is no risk of data loss as the data is being correctly replicated to the secondary sites. Users cloning impacted projects from a Geo secondary site will always be redirected to the primary site. There are no known workarounds at this time. We are actively working on a fix. + + **Affected releases**: + + | Affected minor releases | Affected patch releases | Fixed in | + | ----------------------- | ----------------------- | -------- | + | 16.4 | All | None | + | 16.5 | All | None | + | 16.6 | All | None | + | 16.7 | All | None | + ## 16.6.0 - Old [CI Environment destroy jobs may be spawned](https://gitlab.com/gitlab-org/gitlab/-/issues/433264#) after upgrading to GitLab 16.6. +### Geo installations + +- You might experience verification failures on a subset of projects due to checksum mismatch between the primary site and the secondary site. The details are tracked in this [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/427493). There is no risk of data loss as the data is being correctly replicated to the secondary sites. Users cloning impacted projects from a Geo secondary site will always be redirected to the primary site. There are no known workarounds at this time. We are actively working on a fix. + + **Affected releases**: + + | Affected minor releases | Affected patch releases | Fixed in | + | ----------------------- | ----------------------- | -------- | + | 16.4 | All | None | + | 16.5 | All | None | + | 16.6 | All | None | + | 16.7 | All | None | + ## 16.5.0 - Git 2.42.0 and later is required by Gitaly. For self-compiled installations, you should use the [Git version provided by Gitaly](../../install/installation.md#git). @@ -176,6 +200,17 @@ Specific information applies to installations using Geo: | 16.4 | All | None | | 16.5 | 16.5.0 - 16.5.1 | 16.5.2 | +- You might experience verification failures on a subset of projects due to checksum mismatch between the primary site and the secondary site. The details are tracked in this [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/427493). There is no risk of data loss as the data is being correctly replicated to the secondary sites. Users cloning impacted projects from a Geo secondary site will always be redirected to the primary site. There are no known workarounds at this time. We are actively working on a fix. + + **Affected releases**: + + | Affected minor releases | Affected patch releases | Fixed in | + | ----------------------- | ----------------------- | -------- | + | 16.4 | All | None | + | 16.5 | All | None | + | 16.6 | All | None | + | 16.7 | All | None | + ## 16.4.0 - Updating a group path [received a bug fix](https://gitlab.com/gitlab-org/gitlab/-/issues/419289) that uses a database index introduced in 16.3. @@ -315,6 +350,17 @@ Specific information applies to installations using Geo: | 16.4 | All | None | | 16.5 | 16.5.0 - 16.5.1 | 16.5.2 | +- You might experience verification failures on a subset of projects due to checksum mismatch between the primary site and the secondary site. The details are tracked in this [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/427493). There is no risk of data loss as the data is being correctly replicated to the secondary sites. Users cloning impacted projects from a Geo secondary site will always be redirected to the primary site. There are no known workarounds at this time. We are actively working on a fix. + + **Affected releases**: + + | Affected minor releases | Affected patch releases | Fixed in | + | ----------------------- | ----------------------- | -------- | + | 16.4 | All | None | + | 16.5 | All | None | + | 16.6 | All | None | + | 16.7 | All | None | + ## 16.3.0 - **Update to GitLab 16.3.5 or later**. This avoids [issue 425971](https://gitlab.com/gitlab-org/gitlab/-/issues/425971) that causes an excessive use of database disk space for GitLab 16.3.3 and 16.3.4. diff --git a/doc/update/zero_downtime.md b/doc/update/zero_downtime.md index 6ecd23a0dc8..c40c7a0524e 100644 --- a/doc/update/zero_downtime.md +++ b/doc/update/zero_downtime.md @@ -343,7 +343,7 @@ version), and then upgrade the original primary. For this, we must know the address of the current Redis primary. - If your application node is running GitLab 12.7.0 or later, you can use the -following command to get address of current Redis primary + following command to get address of current Redis primary ```shell sudo gitlab-ctl get-redis-master @@ -514,27 +514,27 @@ the update on the **primary** node: - Run post-deployment database migrations - ```shell - sudo gitlab-rake db:migrate - ``` + ```shell + sudo gitlab-rake db:migrate + ``` - After the update is finalized on the primary node, hot reload `puma` and -restart `sidekiq` and `geo-logcursor` services on **all primary and secondary** -nodes: + restart `sidekiq` and `geo-logcursor` services on **all primary and secondary** + nodes: - ```shell - sudo gitlab-ctl hup puma - sudo gitlab-ctl restart sidekiq - sudo gitlab-ctl restart geo-logcursor - ``` + ```shell + sudo gitlab-ctl hup puma + sudo gitlab-ctl restart sidekiq + sudo gitlab-ctl restart geo-logcursor + ``` After updating all nodes (both **primary** and all **secondaries**), check their status: - Verify Geo configuration and dependencies - ```shell - sudo gitlab-rake gitlab:geo:check - ``` + ```shell + sudo gitlab-rake gitlab:geo:check + ``` If you do not want to run zero downtime upgrades in the future, make sure you remove `/etc/gitlab/skip-auto-reconfigure` and revert diff --git a/doc/user/analytics/issue_analytics.md b/doc/user/analytics/issue_analytics.md index b8aa23a0af2..089a5636a52 100644 --- a/doc/user/analytics/issue_analytics.md +++ b/doc/user/analytics/issue_analytics.md @@ -1,63 +1,11 @@ --- -stage: Plan -group: Optimize -info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments +redirect_to: '../group/issues_analytics/index.md' +remove_date: '2024-04-05' --- -# Issue analytics for projects **(PREMIUM ALL)** +This document was moved to [another location](../group/issues_analytics/index.md). -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196561) in GitLab 12.9. - -Issue analytics is a bar graph which illustrates the number of issues created each month. -The default time span is 13 months, which includes the current month, and the 12 months -prior. - -To access the chart: - -1. On the left sidebar, select **Search or go to** and find your project. -1. Select **Analyze > Issue analytics**. - -You can also access the chart from the [Value Streams Dashboard](value_streams_dashboard.md#dashboard-metrics-and-drill-down-reports) through the **New issues** drill-down report. - -Hover over each bar to see the total number of issues. - -To narrow the scope of issues included in the graph, enter your criteria in the -**Search or filter results...** field. Criteria from the following list can be typed in or selected from a menu: - -- Author -- Assignee -- Milestone -- Label -- My reaction -- Weight - -You can change the total number of months displayed by setting a URL parameter. -For example, `https://gitlab.com/groups/gitlab-org/-/issues_analytics?months_back=15` -shows a total of 15 months for the chart in the GitLab.org group. - -![Issues created per month](img/issues_created_per_month_v14_8.png) - -## Enhanced issue analytics **(ULTIMATE ALL)** - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/233905/) in GitLab 16.4 [with a flag](../../administration/feature_flags.md) named `issues_completed_analytics_feature_flag`. Disabled by default. - -FLAG: -On self-managed GitLab, by default this feature is not available. To make it available, an administrator can -[enable the feature flag](../../administration/feature_flags.md) named `issues_completed_analytics_feature_flag`. On GitLab.com, this feature is not -available. This feature is not ready for production use. - -Enhanced issue analytics display the additional metric "Issues closed", which represents the total number of resolved issues in your project over a selected period. -You can use this metric to improve the overall turn-around time and value delivered to your customers. - -![Issues opened and closed per month](img/enhanced_issue_analytics_v16_7.png) - -## Drill into the information - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196547) in GitLab 13.1. - -You can examine details of individual issues by browsing the table -located below the chart. - -The chart displays the top 100 issues based on the global page filters. - -![Issues table](img/issues_table_v13_1.png) + + + + diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md index 61a0544d6ba..fd0a50b493c 100644 --- a/doc/user/application_security/dependency_scanning/index.md +++ b/doc/user/application_security/dependency_scanning/index.md @@ -678,10 +678,6 @@ Support for additional languages, dependency managers, and dependency files are | ------------------- | --------- | --------------- | ---------- | ----- | | [Poetry](https://python-poetry.org/) | Python | `pyproject.toml` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium) | [GitLab#32774](https://gitlab.com/gitlab-org/gitlab/-/issues/32774) | -## Contribute your scanner - -The [Security Scanner Integration](../../../development/integrations/secure.md) documentation explains how to integrate other security scanners into GitLab. - ## Configuration Enable the dependency scanning analyzer to ensure it scans your application's dependencies for known @@ -807,10 +803,10 @@ The following variables allow configuration of global dependency scanning settin | CI/CD variables | Description | | ----------------------------|------------ | -| `ADDITIONAL_CA_CERT_BUNDLE` | Bundle of CA certs to trust. The bundle of certificates provided here is also used by other tools during the scanning process, such as `git`, `yarn`, or `npm`. See [Using a custom SSL CA certificate authority](#using-a-custom-ssl-ca-certificate-authority) for more details. | -| `DS_EXCLUDED_ANALYZERS` | Specify the analyzers (by name) to exclude from Dependency Scanning. For more information, see [Dependency Scanning Analyzers](#dependency-analyzers). | +| `ADDITIONAL_CA_CERT_BUNDLE` | Bundle of CA certs to trust. The bundle of certificates provided here is also used by other tools during the scanning process, such as `git`, `yarn`, or `npm`. For more details, see [Using a custom SSL CA certificate authority](#using-a-custom-ssl-ca-certificate-authority). | +| `DS_EXCLUDED_ANALYZERS` | Specify the analyzers (by name) to exclude from Dependency Scanning. For more information, see [Dependency Scanning analyzers](#dependency-analyzers). | | `DS_EXCLUDED_PATHS` | Exclude files and directories from the scan based on the paths. A comma-separated list of patterns. Patterns can be globs (see [`doublestar.Match`](https://pkg.go.dev/github.com/bmatcuk/doublestar/v4@v4.0.2#Match) for supported patterns), or file or folder paths (for example, `doc,spec`). Parent directories also match patterns. Default: `"spec, test, tests, tmp"`. | -| `DS_IMAGE_SUFFIX` | Suffix added to the image name. (Introduced in GitLab 14.10. GitLab team members can view more information in this confidential issue: `https://gitlab.com/gitlab-org/gitlab/-/issues/354796`). Automatically set to `"-fips"` when FIPS mode is enabled. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/357922) in GitLab 15.0.) | +| `DS_IMAGE_SUFFIX` | Suffix added to the image name. (GitLab team members can view more information in this confidential issue: `https://gitlab.com/gitlab-org/gitlab/-/issues/354796`). Automatically set to `"-fips"` when FIPS mode is enabled. | | `DS_MAX_DEPTH` | Defines how many directory levels deep that the analyzer should search for supported files to scan. A value of `-1` scans all directories regardless of depth. Default: `2`. | | `SECURE_ANALYZERS_PREFIX` | Override the name of the Docker registry providing the official default images (proxy). | diff --git a/doc/user/application_security/index.md b/doc/user/application_security/index.md index e31877d195a..da1439ed13e 100644 --- a/doc/user/application_security/index.md +++ b/doc/user/application_security/index.md @@ -247,10 +247,8 @@ Security scan information appears in multiple locations and formats: ### Merge request **(FREE ALL)** -> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/4393) in GitLab Free 13.5. -> - Made [available in all tiers](https://gitlab.com/gitlab-org/gitlab/-/issues/273205) in 13.6. -> - Report download dropdown list [added](https://gitlab.com/gitlab-org/gitlab/-/issues/273418) in 13.7. -> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/249550) in GitLab 13.9. +Output of all enabled application security tools is shown in a merge request widget. You can use +this information to manage the risk of any issues identified in the source branch. #### All tiers diff --git a/doc/user/group/issues_analytics/index.md b/doc/user/group/issues_analytics/index.md index 28f4026b3e3..35b398e1ce0 100644 --- a/doc/user/group/issues_analytics/index.md +++ b/doc/user/group/issues_analytics/index.md @@ -4,17 +4,18 @@ group: Optimize info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments --- -# Issue analytics for groups **(PREMIUM ALL)** +# Issue analytics **(PREMIUM ALL)** -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7478) in GitLab 11.5. +> - Issue analytics for groups [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7478) in GitLab 11.5. +> - Issue analytics for projects [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196561) in GitLab 12.9. Issue analytics is a bar graph which illustrates the number of issues created each month. -The default time span is 13 months, which includes the current month, and the 12 months -prior. +The default time span is 13 months, which includes the current month, and the 12 months prior. +Issue analytics is available for projects and groups. To access the chart: -1. On the left sidebar, select **Search or go to** and find your group. +1. On the left sidebar, select **Search or go to** and find your project or group. 1. Select **Analyze > Issue analytics**. You can also access the chart from the [Value Streams Dashboard](../../analytics/value_streams_dashboard.md) through the **New issues** drill-down report. diff --git a/doc/user/project/integrations/slack.md b/doc/user/project/integrations/slack.md index 9b92fa35e24..fee6de2af6d 100644 --- a/doc/user/project/integrations/slack.md +++ b/doc/user/project/integrations/slack.md @@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w WARNING: This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/372411) in GitLab 15.9 -and is planned for removal in 17.0. Use the [GitLab for Slack app](gitlab_slack_application.md) instead. +and is planned for removal in 18.0. Use the [GitLab for Slack app](gitlab_slack_application.md) instead. This change is a breaking change. The Slack notifications integration enables your GitLab project to send events diff --git a/doc/user/project/merge_requests/widgets.md b/doc/user/project/merge_requests/widgets.md index d60bd660b53..a6680e5e4f4 100644 --- a/doc/user/project/merge_requests/widgets.md +++ b/doc/user/project/merge_requests/widgets.md @@ -73,3 +73,9 @@ If you have configured [License Compliance](../../compliance/license_scanning_of If you have configured [external status checks](status_checks.md) you can see the status of these checks in merge requests [in a specific widget](status_checks.md#status-checks-widget). + +## Application security scanning + +If you have enabled any application security scanning tools, the results are shown in the security +scanning widget. For more information, see +[security scanning output in merge request widget](../../application_security/index.md#merge-request). diff --git a/lib/gitlab/auth/two_factor_auth_verifier.rb b/lib/gitlab/auth/two_factor_auth_verifier.rb index 4b66aaf0e6a..971f8bb25ce 100644 --- a/lib/gitlab/auth/two_factor_auth_verifier.rb +++ b/lib/gitlab/auth/two_factor_auth_verifier.rb @@ -14,13 +14,28 @@ module Gitlab two_factor_authentication_required? && two_factor_grace_period_expired? end + # rubocop:disable Cop/UserAdmin -- Admin mode does not matter in the context of verifying for two factor statuses def two_factor_authentication_required? return false if allow_2fa_bypass_for_provider Gitlab::CurrentSettings.require_two_factor_authentication? || - current_user&.require_two_factor_authentication_from_group? + current_user&.require_two_factor_authentication_from_group? || + (Gitlab::CurrentSettings.require_admin_two_factor_authentication && current_user&.admin?) # rubocop:disable Cop/UserAdmin -- It should be applied to any administrator user regardless of admin mode end + def two_factor_authentication_reason + if Gitlab::CurrentSettings.require_two_factor_authentication? + :global + elsif Gitlab::CurrentSettings.require_admin_two_factor_authentication && current_user&.admin? + :admin_2fa + elsif current_user&.require_two_factor_authentication_from_group? + :group + else + false + end + end + # rubocop:enable Cop/UserAdmin + def current_user_needs_to_setup_two_factor? current_user && !current_user.temp_oauth_email? && !current_user.two_factor_enabled? end diff --git a/lib/gitlab/gon_helper.rb b/lib/gitlab/gon_helper.rb index caf7cfb3f76..c4c0e48be3f 100644 --- a/lib/gitlab/gon_helper.rb +++ b/lib/gitlab/gon_helper.rb @@ -123,7 +123,7 @@ module Gitlab end def add_browsersdk_tracking - return unless Gitlab.com? && Feature.enabled?(:browsersdk_tracking) && Feature.enabled?(:gl_analytics_tracking, + return unless Gitlab.com? && Feature.enabled?(:gl_analytics_tracking, Feature.current_request) return if ENV['GITLAB_ANALYTICS_URL'].blank? || ENV['GITLAB_ANALYTICS_ID'].blank? diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 28cfe4f90a6..6d586672764 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -4296,6 +4296,9 @@ msgstr "" msgid "AdminUsers|user cap" msgstr "" +msgid "Administrator users are required to enable Two-Factor Authentication for their account." +msgstr "" + msgid "Administrators" msgstr "" @@ -18876,6 +18879,9 @@ msgstr "" msgid "Ends: %{endsAt}" msgstr "" +msgid "Enforce Two-Factor authentication for administrator users" +msgstr "" + msgid "Enforce two-factor authentication" msgstr "" @@ -41169,6 +41175,9 @@ msgstr "" msgid "Require additional authentication for administrative tasks." msgstr "" +msgid "Require administrators to enable 2FA" +msgstr "" + msgid "Require expiration date" msgstr "" diff --git a/scripts/review_apps/base-config.yaml b/scripts/review_apps/base-config.yaml index 70941b264c5..ef73d7bfd49 100644 --- a/scripts/review_apps/base-config.yaml +++ b/scripts/review_apps/base-config.yaml @@ -94,7 +94,7 @@ gitlab: memory: 1500Mi limits: cpu: 700m - memory: 2000Mi + memory: 2200Mi hpa: cpu: targetAverageValue: 650m diff --git a/spec/features/profiles/two_factor_auths_spec.rb b/spec/features/profiles/two_factor_auths_spec.rb index cea3172898f..bc6f88474a9 100644 --- a/spec/features/profiles/two_factor_auths_spec.rb +++ b/spec/features/profiles/two_factor_auths_spec.rb @@ -63,6 +63,35 @@ RSpec.describe 'Two factor auths', feature_category: :system_access do end end + context 'when two factor is enforced for administrator users' do + let_it_be(:admin) { create(:admin) } + + before do + stub_application_setting(require_admin_two_factor_authentication: require_admin_two_factor_authentication) + sign_in(admin) + end + + context 'when visiting root dashboard path' do + let(:require_admin_two_factor_authentication) { true } + + it 'renders alert for administrator users' do + visit profile_two_factor_auth_path + expect(page).to have_content('Administrator users are required to enable Two-Factor Authentication for their account. You need to do this before ') + end + end + end + + context 'when two factor is disabled for administrator users' do + context 'when visiting root dashboard path' do + let(:require_admin_two_factor_authentication) { false } + + it 'does not render an alert for administrator users' do + visit profile_two_factor_auth_path + expect(page).not_to have_content('Administrator users are required to enable Two-Factor Authentication for their account. You need to do this before ') + end + end + end + context 'when two factor is enforced in global settings' do before do stub_application_setting(require_two_factor_authentication: true) diff --git a/spec/frontend/error_tracking/components/error_details_info_spec.js b/spec/frontend/error_tracking/components/error_details_info_spec.js index a3f4b0e0dd8..f563fee0ec0 100644 --- a/spec/frontend/error_tracking/components/error_details_info_spec.js +++ b/spec/frontend/error_tracking/components/error_details_info_spec.js @@ -47,6 +47,13 @@ describe('ErrorDetails', () => { expect(wrapper.findByTestId('user-count-card').text()).toMatchInterpolatedText('Users 2'); }); + it('should not render a card with user counts if integrated error tracking', () => { + mountComponent({ + integrated: true, + }); + expect(wrapper.findByTestId('user-count-card').exists()).toBe(false); + }); + describe('first seen card', () => { it('if firstSeen is missing, does not render a card', () => { mountComponent({ diff --git a/spec/frontend/error_tracking/components/error_tracking_list_spec.js b/spec/frontend/error_tracking/components/error_tracking_list_spec.js index 823f7132fdd..91518002f0e 100644 --- a/spec/frontend/error_tracking/components/error_tracking_list_spec.js +++ b/spec/frontend/error_tracking/components/error_tracking_list_spec.js @@ -146,6 +146,28 @@ describe('ErrorTrackingList', () => { expect(findErrorListRows().length).toEqual(store.state.list.errors.length); }); + describe('user count', () => { + it('shows user count', () => { + mountComponent({ + integratedErrorTrackingEnabled: false, + stubs: { + GlTable: false, + }, + }); + expect(findErrorListTable().find('thead').text()).toContain('Users'); + }); + + it('does not show user count', () => { + mountComponent({ + integratedErrorTrackingEnabled: true, + stubs: { + GlTable: false, + }, + }); + expect(findErrorListTable().find('thead').text()).not.toContain('Users'); + }); + }); + describe.each([ ['/test-project/-/error_tracking'], ['/test-project/-/error_tracking/'], // handles leading '/' https://gitlab.com/gitlab-org/gitlab/-/issues/430211 diff --git a/spec/graphql/types/ci/catalog/resources/version_type_spec.rb b/spec/graphql/types/ci/catalog/resources/version_type_spec.rb index 10eea90e949..bc1b9a97e88 100644 --- a/spec/graphql/types/ci/catalog/resources/version_type_spec.rb +++ b/spec/graphql/types/ci/catalog/resources/version_type_spec.rb @@ -10,9 +10,7 @@ RSpec.describe Types::Ci::Catalog::Resources::VersionType, feature_category: :pi id created_at released_at - tag_name name - tag_path path author commit diff --git a/spec/lib/gitlab/auth/two_factor_auth_verifier_spec.rb b/spec/lib/gitlab/auth/two_factor_auth_verifier_spec.rb index e0ef45d5621..bccddaa50a0 100644 --- a/spec/lib/gitlab/auth/two_factor_auth_verifier_spec.rb +++ b/spec/lib/gitlab/auth/two_factor_auth_verifier_spec.rb @@ -169,4 +169,33 @@ RSpec.describe Gitlab::Auth::TwoFactorAuthVerifier do end end end + + describe '#two_factor_authentication_reason?' do + it 'returns false if two factor authentication is not required' do + allow(user).to receive(:require_two_factor_authentication?).and_return(false) + + expect(subject.two_factor_authentication_reason).to be_falsey + end + + it 'returns :global if two factor authentication is enabled globally' do + stub_application_setting require_two_factor_authentication: true + + expect(subject.two_factor_authentication_reason).to eq(:global) + end + + it 'returns :admin_2fa if the current user is an admin and two factor is enabled' do + stub_application_setting require_admin_two_factor_authentication: true + + allow(user).to receive(:admin?).and_return(true) + + expect(subject.two_factor_authentication_reason).to eq(:admin_2fa) + end + + it 'returns :group if two factor authentication is enforced through a group setting' do + stub_application_setting require_two_factor_authentication: false + allow(user).to receive(:require_two_factor_authentication_from_group?).and_return(true) + + expect(subject.two_factor_authentication_reason).to eq(:group) + end + end end diff --git a/spec/lib/gitlab/gon_helper_spec.rb b/spec/lib/gitlab/gon_helper_spec.rb index e4684597ddf..d9dcae3cdc7 100644 --- a/spec/lib/gitlab/gon_helper_spec.rb +++ b/spec/lib/gitlab/gon_helper_spec.rb @@ -205,7 +205,6 @@ RSpec.describe Gitlab::GonHelper do context 'when feature flag is false' do before do - stub_feature_flags(browsersdk_tracking: false) stub_feature_flags(gl_analytics_tracking: false) end diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb index 39d7e6a84d4..949421c205f 100644 --- a/spec/services/projects/fork_service_spec.rb +++ b/spec/services/projects/fork_service_spec.rb @@ -3,165 +3,159 @@ require 'spec_helper' RSpec.describe Projects::ForkService, feature_category: :source_code_management do - include ProjectForksHelper + subject(:service) { described_class.new(project, user, params) } + + let_it_be_with_reload(:project) { create(:project, :repository, star_count: 100, description: 'project') } + let_it_be_with_reload(:user) { create(:user) } + + let(:params) { { namespace: namespace } } + let(:namespace) { user.namespace } shared_examples 'forks count cache refresh' do it 'flushes the forks count cache of the source project', :clean_gitlab_redis_cache do expect(from_project.forks_count).to be_zero - fork_project(from_project, to_user, using_service: true) + described_class.new(from_project, to_user, params).execute + BatchLoader::Executor.clear_current - expect(from_project.forks_count).to eq(1) + expect(from_project.reload.forks_count).to eq(1) end end - context 'when forking a new project' do - describe 'fork by user' do + describe '#execute' do + subject(:fork_of_project) { service.execute } + + before do + # NOTE: Avatar file is dropped after project reload. Explicitly re-add it for each test. + project.avatar = fixture_file_upload("spec/fixtures/dk.png", "image/png") + end + + context 'when forker is a guest' do before do - @from_user = create(:user) - @from_namespace = @from_user.namespace - avatar = fixture_file_upload("spec/fixtures/dk.png", "image/png") - @from_project = create( - :project, - :repository, - creator_id: @from_user.id, - namespace: @from_namespace, - star_count: 107, - avatar: avatar, - description: 'wow such project', - external_authorization_classification_label: 'classification-label' - ) - @to_user = create(:user) - @to_namespace = @to_user.namespace - @from_project.add_member(@to_user, :developer) + project.add_member(user, :guest) end - context 'fork project' do - context 'when forker is a guest' do - before do - @guest = create(:user) - @from_project.add_member(@guest, :guest) - end - subject { fork_project(@from_project, @guest, using_service: true) } + it 'does not create a fork' do + is_expected.not_to be_persisted + expect(subject.errors[:forked_from_project_id]).to eq(['is forbidden']) + end - it { is_expected.not_to be_persisted } - it { expect(subject.errors[:forked_from_project_id]).to eq(['is forbidden']) } + it 'does not create a fork network' do + expect { subject }.not_to change { project.reload.fork_network } + end + end - it 'does not create a fork network' do - expect { subject }.not_to change { @from_project.reload.fork_network } + context 'when forker is a developer' do + before do + project.add_member(user, :developer) + end + + it 'creates a fork of the project' do + expect(fork_of_project).to be_persisted + expect(fork_of_project.errors).to be_empty + expect(fork_of_project.first_owner).to eq(user) + expect(fork_of_project.namespace).to eq(user.namespace) + expect(fork_of_project.star_count).to be_zero + expect(fork_of_project.description).to eq(project.description) + expect(fork_of_project.avatar.file).to be_exists + expect(fork_of_project.ci_config_path).to eq(project.ci_config_path) + expect(fork_of_project.external_authorization_classification_label).to eq(project.external_authorization_classification_label) + expect(fork_of_project.suggestion_commit_message).to eq(project.suggestion_commit_message) + expect(fork_of_project.merge_commit_template).to eq(project.merge_commit_template) + expect(fork_of_project.squash_commit_template).to eq(project.squash_commit_template) + end + + # This test is here because we had a bug where the from-project lost its + # avatar after being forked. + # https://gitlab.com/gitlab-org/gitlab-foss/issues/26158 + it 'after forking the original project still has its avatar' do + # If we do not fork the project first we cannot detect the bug. + expect(fork_of_project).to be_persisted + + expect(project.avatar.file).to be_exists + end + + it_behaves_like 'forks count cache refresh' do + let(:from_project) { project } + let(:to_user) { user } + end + + it 'creates a fork network with the new project and the root project set' do + subject + + fork_network = project.reload.fork_network + + expect(fork_network).not_to be_nil + expect(fork_network.root_project).to eq(project) + expect(fork_network.projects).to contain_exactly(project, fork_of_project) + end + + it 'imports the repository of the forked project', :sidekiq_might_not_need_inline do + expect(fork_of_project).to be_persisted + + # The call to project.repository.after_import in RepositoryForkWorker does + # not reset the @exists variable of this fork_of_project.repository + # so we have to explicitly call this method to clear the @exists variable. + # of the instance we're returning here. + fork_of_project.repository.expire_content_cache + + expect(fork_of_project.empty_repo?).to be_falsey + end + + context 'when creating fork of the fork' do + let_it_be(:other_namespace) { create(:group).tap { |group| group.add_owner(user) } } + + it 'creates a new project' do + fork_of_project = described_class.new(project, user, params).execute + expect(fork_of_project).to be_persisted + + fork_of_fork = described_class.new(fork_of_project, user, { namespace: other_namespace }).execute + expect(fork_of_fork).to be_persisted + + expect(fork_of_fork).to be_valid + expect(fork_of_fork.fork_network.root_project).to eq(project) + expect(fork_of_fork.fork_network_member.forked_from_project).to eq(fork_of_project) + end + + context 'when the forked project has higher visibility than the root project' do + let_it_be(:root_project) { create(:project, :public) } + + it 'successfully creates a fork of the fork with correct visibility' do + fork_of_project = described_class.new(root_project, user, params).execute + expect(fork_of_project).to be_persisted + + root_project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL) + + # Forked project visibility is not affected by root project visibility change + expect(fork_of_project).to have_attributes(visibility_level: Gitlab::VisibilityLevel::PUBLIC) + + fork_of_fork = described_class.new(fork_of_project, user, { namespace: other_namespace }).execute + expect(fork_of_fork).to be_persisted + + expect(fork_of_fork).to be_valid + expect(fork_of_fork).to have_attributes(visibility_level: Gitlab::VisibilityLevel::PUBLIC) end end it_behaves_like 'forks count cache refresh' do - let(:from_project) { @from_project } - let(:to_user) { @to_user } - end - - describe "successfully creates project in the user namespace" do - let(:to_project) { fork_project(@from_project, @to_user, namespace: @to_user.namespace, using_service: true) } - - it { expect(to_project).to be_persisted } - it { expect(to_project.errors).to be_empty } - it { expect(to_project.first_owner).to eq(@to_user) } - it { expect(to_project.namespace).to eq(@to_user.namespace) } - it { expect(to_project.star_count).to be_zero } - it { expect(to_project.description).to eq(@from_project.description) } - it { expect(to_project.avatar.file).to be_exists } - it { expect(to_project.ci_config_path).to eq(@from_project.ci_config_path) } - it { expect(to_project.external_authorization_classification_label).to eq(@from_project.external_authorization_classification_label) } - it { expect(to_project.suggestion_commit_message).to eq(@from_project.suggestion_commit_message) } - it { expect(to_project.merge_commit_template).to eq(@from_project.merge_commit_template) } - it { expect(to_project.squash_commit_template).to eq(@from_project.squash_commit_template) } - - # This test is here because we had a bug where the from-project lost its - # avatar after being forked. - # https://gitlab.com/gitlab-org/gitlab-foss/issues/26158 - it "after forking the from-project still has its avatar" do - # If we do not fork the project first we cannot detect the bug. - expect(to_project).to be_persisted - - expect(@from_project.avatar.file).to be_exists - end - - it_behaves_like 'forks count cache refresh' do - let(:from_project) { @from_project } - let(:to_user) { @to_user } - end - - it 'creates a fork network with the new project and the root project set' do - to_project - fork_network = @from_project.reload.fork_network - - expect(fork_network).not_to be_nil - expect(fork_network.root_project).to eq(@from_project) - expect(fork_network.projects).to contain_exactly(@from_project, to_project) - end - - it 'imports the repository of the forked project', :sidekiq_might_not_need_inline do - to_project = fork_project(@from_project, @to_user, repository: true, using_service: true) - - expect(to_project.empty_repo?).to be_falsy - end - end - - context 'creating a fork of a fork' do - let(:from_forked_project) { fork_project(@from_project, @to_user, using_service: true) } - let(:other_namespace) do - group = create(:group) - group.add_owner(@to_user) - group - end - - let(:to_project) { fork_project(from_forked_project, @to_user, namespace: other_namespace, using_service: true) } - - it 'sets the root of the network to the root project' do - expect(to_project.fork_network.root_project).to eq(@from_project) - end - - it 'sets the forked_from_project on the membership' do - expect(to_project.fork_network_member.forked_from_project).to eq(from_forked_project) - end - - context 'when the forked project has higher visibility than the root project' do - let(:root_project) { create(:project, :public) } - - it 'successfully creates a fork of the fork with correct visibility' do - forked_project = fork_project(root_project, @to_user, using_service: true) - - root_project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL) - - # Forked project visibility is not affected by root project visibility change - expect(forked_project).to have_attributes(visibility_level: Gitlab::VisibilityLevel::PUBLIC) - - fork_of_the_fork = fork_project(forked_project, @to_user, namespace: other_namespace, using_service: true) - - expect(fork_of_the_fork).to be_valid - expect(fork_of_the_fork).to have_attributes(visibility_level: Gitlab::VisibilityLevel::PUBLIC) - end - end - - it_behaves_like 'forks count cache refresh' do - let(:from_project) { from_forked_project } - let(:to_user) { @to_user } - end + let(:from_project) { described_class.new(project, user, { namespace: other_namespace }).execute } + let(:to_user) { user } end end - context 'project already exists' do - it "fails due to validation, not transaction failure" do - @existing_project = create(:project, :repository, creator_id: @to_user.id, path: @from_project.path, namespace: @to_namespace) - @to_project = fork_project(@from_project, @to_user, namespace: @to_namespace, using_service: true) - expect(@existing_project).to be_persisted + context 'when project already exists' do + it 'fails due to validation, not transaction failure' do + existing_project = create(:project, namespace: namespace, path: project.path) + expect(existing_project).to be_persisted - expect(@to_project).not_to be_persisted - expect(@to_project.errors[:path]).to eq(['has already been taken']) + expect(fork_of_project).not_to be_persisted + expect(fork_of_project.errors[:path]).to eq(['has already been taken']) end end - context 'repository in legacy storage already exists' do - let(:raw_fake_repo) { Gitlab::Git::Repository.new('default', File.join(@to_user.namespace.full_path, "#{@from_project.path}.git"), nil, nil) } - let(:params) { { namespace: @to_user.namespace, using_service: true } } + context 'when repository in legacy storage already exists' do + let(:raw_fake_repo) { Gitlab::Git::Repository.new('default', File.join(user.namespace.full_path, "#{project.path}.git"), nil, nil) } before do stub_application_setting(hashed_storage_enabled: false) @@ -172,60 +166,54 @@ RSpec.describe Projects::ForkService, feature_category: :source_code_management raw_fake_repo.remove end - subject { fork_project(@from_project, @to_user, params) } - it 'does not allow creation' do - expect(subject).not_to be_persisted - expect(subject.errors.messages).to have_key(:base) - expect(subject.errors.messages[:base].first).to match('There is already a repository with that name on disk') + fork_of_project + + expect(fork_of_project).not_to be_persisted + expect(fork_of_project.errors.messages).to have_key(:base) + expect(fork_of_project.errors.messages[:base].first).to match('There is already a repository with that name on disk') end context 'when repository disk validation is explicitly skipped' do let(:params) { super().merge(skip_disk_validation: true) } it 'allows fork project creation' do - expect(subject).to be_persisted - expect(subject.errors.messages).to be_empty + expect(fork_of_project).to be_persisted + expect(fork_of_project.errors.messages).to be_empty end end end - context "CI/CD settings" do - let(:to_project) { fork_project(@from_project, @to_user, using_service: true) } + context 'CI/CD settings' do + context 'when origin has git depth specified' do + it 'inherits default_git_depth from the origin project' do + project.update!(ci_default_git_depth: 42) - context "when origin has git depth specified" do - before do - @from_project.update!(ci_default_git_depth: 42) - end - - it "inherits default_git_depth from the origin project" do - expect(to_project.ci_default_git_depth).to eq(42) + expect(fork_of_project).to be_persisted + expect(fork_of_project.ci_default_git_depth).to eq(42) end end - context "when origin does not define git depth" do - before do - @from_project.update!(ci_default_git_depth: nil) - end + context 'when origin does not define git depth' do + it 'the fork has git depth set to 0' do + project.update!(ci_default_git_depth: nil) - it "the fork has git depth set to 0" do - expect(to_project.ci_default_git_depth).to eq(0) + expect(fork_of_project).to be_persisted + expect(fork_of_project.ci_default_git_depth).to eq(0) end end end - context "when project has restricted visibility level" do - context "and only one visibility level is restricted" do + context 'when project has restricted visibility level' do + context 'and only one visibility level is restricted' do before do - @from_project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL) + project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL) stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::INTERNAL]) end - it "creates fork with lowest level" do - forked_project = fork_project(@from_project, @to_user, using_service: true) - - expect(forked_project).to be_persisted - expect(forked_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) + it 'creates fork with lowest level' do + expect(fork_of_project).to be_persisted + expect(fork_of_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) end end @@ -235,289 +223,283 @@ RSpec.describe Projects::ForkService, feature_category: :source_code_management end it "doesn't create a fork" do - forked_project = fork_project(@from_project, @to_user, using_service: true) - - expect(forked_project).not_to be_persisted - expect(forked_project.errors[:visibility_level]).to eq ['private has been restricted by your GitLab administrator'] + expect(fork_of_project).not_to be_persisted + expect(fork_of_project.errors[:visibility_level]).to eq ['private has been restricted by your GitLab administrator'] end end end context 'when forking is disabled' do before do - @from_project.project_feature.update_attribute( - :forking_access_level, ProjectFeature::DISABLED) + project.project_feature.update_attribute(:forking_access_level, ProjectFeature::DISABLED) end - it 'fails' do - to_project = fork_project(@from_project, @to_user, namespace: @to_user.namespace, using_service: true) - - expect(to_project.errors[:forked_from_project_id]).to eq(['is forbidden']) - end - end - end - - describe 'fork to namespace' do - before do - @group_owner = create(:user) - @developer = create(:user) - @project = create( - :project, :repository, - creator_id: @group_owner.id, - star_count: 777, - description: 'Wow, such a cool project!', - ci_config_path: 'debian/salsa-ci.yml' - ) - @group = create(:group) - @group.add_member(@group_owner, GroupMember::OWNER) - @group.add_member(@developer, GroupMember::DEVELOPER) - @project.add_member(@developer, :developer) - @project.add_member(@group_owner, :developer) - @opts = { namespace: @group, using_service: true } - end - - context 'fork project for group' do - it 'group owner successfully forks project into the group' do - to_project = fork_project(@project, @group_owner, @opts) - - expect(to_project).to be_persisted - expect(to_project.errors).to be_empty - expect(to_project.first_owner).to eq(@group_owner) - expect(to_project.namespace).to eq(@group) - expect(to_project.name).to eq(@project.name) - expect(to_project.path).to eq(@project.path) - expect(to_project.description).to eq(@project.description) - expect(to_project.ci_config_path).to eq(@project.ci_config_path) - expect(to_project.star_count).to be_zero + it 'does not create a fork' do + expect(fork_of_project).not_to be_persisted + expect(fork_of_project.errors[:forked_from_project_id]).to eq(['is forbidden']) end end - context 'fork project for group when user not owner' do - it 'group developer fails to fork project into the group' do - to_project = fork_project(@project, @developer, @opts) + context 'when forking to the group namespace' do + context 'when user owns a target group' do + let_it_be_with_reload(:namespace) { create(:group).tap { |group| group.add_owner(user) } } - expect(to_project.errors[:namespace]).to eq(['is not valid']) + it 'creates a fork in the group' do + expect(fork_of_project).to be_persisted + expect(fork_of_project.first_owner).to eq(user) + expect(fork_of_project.namespace).to eq(namespace) + end + + context 'when project already exists in group' do + it 'fails due to validation, not transaction failure' do + existing_project = create(:project, :repository, path: project.path, namespace: namespace) + expect(existing_project).to be_persisted + + expect(fork_of_project).not_to be_persisted + expect(fork_of_project.errors[:path]).to eq(['has already been taken']) + end + end + + context 'when the namespace has a lower visibility level than the project' do + let_it_be(:namespace) { create(:group, :private).tap { |group| group.add_owner(user) } } + let_it_be(:project) { create(:project, :public) } + + it 'creates the project with the lower visibility level' do + expect(fork_of_project).to be_persisted + expect(fork_of_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) + end + end + end + + context 'when user is not a group owner' do + let_it_be(:namespace) { create(:group).tap { |group| group.add_developer(user) } } + + it 'does not create a fork' do + expect(fork_of_project).not_to be_persisted + expect(fork_of_project.errors[:namespace]).to eq(['is not valid']) + end end end - context 'project already exists in group' do - it 'fails due to validation, not transaction failure' do - existing_project = create(:project, :repository, path: @project.path, namespace: @group) - to_project = fork_project(@project, @group_owner, @opts) - expect(existing_project.persisted?).to be_truthy - expect(to_project.errors[:path]).to eq(['has already been taken']) + context 'with optional attributes' do + let(:params) { super().merge(path: 'forked', name: 'My Fork', description: 'Description', visibility: 'private') } + + it 'sets optional attributes to specified values' do + expect(fork_of_project).to be_persisted + + expect(fork_of_project.path).to eq('forked') + expect(fork_of_project.name).to eq('My Fork') + expect(fork_of_project.description).to eq('Description') + expect(fork_of_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) + end + + context 'when an unknown visibility is requested' do + let_it_be(:project) { create(:project, :public) } + + let(:params) { super().merge(visibility: 'unknown') } + + it 'sets visibility level to private' do + expect(fork_of_project).to be_persisted + + expect(fork_of_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) + end + end + + context 'when requested visibility level is greater than allowed' do + let_it_be(:project) { create(:project, :internal) } + + let(:params) { super().merge(visibility: 'public') } + + it 'sets visibility level to project visibility' do + expect(fork_of_project).to be_persisted + + expect(fork_of_project.visibility_level).to eq(Gitlab::VisibilityLevel::INTERNAL) + end + end + + context 'when target namespace has lower visibility than a project' do + let_it_be(:project) { create(:project, :public) } + let_it_be(:namespace) { create(:group, :private).tap { |group| group.add_owner(user) } } + + it 'sets visibility level to target namespace visibility level' do + expect(fork_of_project).to be_persisted + + expect(fork_of_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) + end + end + + context 'when project has custom visibility settings' do + let_it_be(:project) { create(:project, :public) } + + let(:attrs) do + ProjectFeature::FEATURES.to_h do |f| + ["#{f}_access_level", ProjectFeature::PRIVATE] + end + end + + before do + project.project_feature.update!(attrs) + end + + it 'copies project features visibility settings to the fork' do + expect(fork_of_project).to be_persisted + + expect(fork_of_project.project_feature.slice(attrs.keys)).to eq(attrs) + end end end - context 'when the namespace has a lower visibility level than the project' do - it 'creates the project with the lower visibility level' do - public_project = create(:project, :public) - private_group = create(:group, :private) - group_owner = create(:user) - private_group.add_owner(group_owner) + context 'when a project is already forked' do + let_it_be(:project) { create(:project, :public, :repository) } + let_it_be(:group) { create(:group).tap { |group| group.add_owner(user) } } - forked_project = fork_project(public_project, group_owner, namespace: private_group, using_service: true) - - expect(forked_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) - end - end - end - - describe 'fork with optional attributes' do - let(:public_project) { create(:project, :public) } - - it 'sets optional attributes to specified values' do - forked_project = fork_project( - public_project, - nil, - namespace: public_project.namespace, - path: 'forked', - name: 'My Fork', - description: 'Description', - visibility: 'internal', - using_service: true - ) - - expect(forked_project.path).to eq('forked') - expect(forked_project.name).to eq('My Fork') - expect(forked_project.description).to eq('Description') - expect(forked_project.visibility_level).to eq(Gitlab::VisibilityLevel::INTERNAL) - end - - it 'sets visibility level to private if an unknown visibility is requested' do - forked_project = fork_project(public_project, nil, using_service: true, visibility: 'unknown') - - expect(forked_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) - end - - it 'sets visibility level to project visibility level if requested visibility is greater' do - private_project = create(:project, :private) - - forked_project = fork_project(private_project, nil, using_service: true, visibility: 'public') - - expect(forked_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) - end - - it 'sets visibility level to target namespace visibility level if requested visibility is greater' do - private_group = create(:group, :private) - - forked_project = fork_project(public_project, nil, namespace: private_group, using_service: true, visibility: 'public') - - expect(forked_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) - end - - it 'copies project features visibility settings to the fork', :aggregate_failures do - attrs = ProjectFeature::FEATURES.to_h do |f| - ["#{f}_access_level", ProjectFeature::PRIVATE] + before do + # Stub everything required to move a project to a Gitaly shard that does not exist + allow(Gitlab::GitalyClient).to receive(:filesystem_id).with('default').and_call_original + allow(Gitlab::GitalyClient).to receive(:filesystem_id).with('test_second_storage').and_return(SecureRandom.uuid) + stub_storage_settings('test_second_storage' => {}) + allow_any_instance_of(Gitlab::Git::Repository).to receive(:create_repository) + .and_return(true) + allow_any_instance_of(Gitlab::Git::Repository).to receive(:replicate) + allow_any_instance_of(Gitlab::Git::Repository).to receive(:checksum) + .and_return(::Gitlab::Git::SHA1_BLANK_SHA) + allow_next_instance_of(Gitlab::Git::ObjectPool) do |object_pool| + allow(object_pool).to receive(:link) + end end - public_project.project_feature.update!(attrs) + it 'creates a new pool repository after the project is moved to a new shard' do + fork_before_move = subject - user = create(:user, developer_projects: [public_project]) - forked_project = described_class.new(public_project, user).execute + storage_move = create( + :project_repository_storage_move, + :scheduled, + container: project, + destination_storage_name: 'test_second_storage' + ) + Projects::UpdateRepositoryStorageService.new(storage_move).execute - expect(forked_project.project_feature.slice(attrs.keys)).to eq(attrs) - end - end - end + fork_after_move = described_class.new(project.reload, user, namespace: group).execute - context 'when a project is already forked' do - it 'creates a new pool repository after the project is moved to a new shard' do - project = create(:project, :public, :repository) - fork_before_move = fork_project(project, nil, using_service: true) + pool_repository_before_move = PoolRepository.joins(:shard) + .find_by(source_project: project, shards: { name: 'default' }) + pool_repository_after_move = PoolRepository.joins(:shard) + .find_by(source_project: project, shards: { name: 'test_second_storage' }) - # Stub everything required to move a project to a Gitaly shard that does not exist - allow(Gitlab::GitalyClient).to receive(:filesystem_id).with('default').and_call_original - allow(Gitlab::GitalyClient).to receive(:filesystem_id).with('test_second_storage').and_return(SecureRandom.uuid) - stub_storage_settings('test_second_storage' => {}) - allow_any_instance_of(Gitlab::Git::Repository).to receive(:create_repository) - .and_return(true) - allow_any_instance_of(Gitlab::Git::Repository).to receive(:replicate) - allow_any_instance_of(Gitlab::Git::Repository).to receive(:checksum) - .and_return(::Gitlab::Git::SHA1_BLANK_SHA) - allow_next_instance_of(Gitlab::Git::ObjectPool) do |object_pool| - allow(object_pool).to receive(:link) + expect(fork_before_move.pool_repository).to eq(pool_repository_before_move) + expect(fork_after_move.pool_repository).to eq(pool_repository_after_move) + end end - storage_move = create( - :project_repository_storage_move, - :scheduled, - container: project, - destination_storage_name: 'test_second_storage' - ) - Projects::UpdateRepositoryStorageService.new(storage_move).execute - fork_after_move = fork_project(project.reload, nil, using_service: true) - pool_repository_before_move = PoolRepository.joins(:shard) - .find_by(source_project: project, shards: { name: 'default' }) - pool_repository_after_move = PoolRepository.joins(:shard) - .find_by(source_project: project, shards: { name: 'test_second_storage' }) + context 'when forking with object pools' do + let_it_be(:project) { create(:project, :public, :repository) } - expect(fork_before_move.pool_repository).to eq(pool_repository_before_move) - expect(fork_after_move.pool_repository).to eq(pool_repository_after_move) - end - end + context 'when no pool exists' do + it 'creates a new object pool' do + expect { fork_of_project }.to change { PoolRepository.count }.by(1) - context 'when forking with object pools' do - let(:fork_from_project) { create(:project, :repository, :public) } - let(:forker) { create(:user) } + expect(fork_of_project.pool_repository).to eq(project.pool_repository) + end - context 'when no pool exists' do - it 'creates a new object pool' do - forked_project = fork_project(fork_from_project, forker, using_service: true) + context 'when project is private' do + let_it_be(:project) { create(:project, :private, :repository) } - expect(forked_project.pool_repository).to eq(fork_from_project.pool_repository) - end - end + it 'does not create an object pool' do + expect { fork_of_project }.not_to change { PoolRepository.count } - context 'when a pool already exists' do - let!(:pool_repository) { create(:pool_repository, source_project: fork_from_project) } + expect(fork_of_project.pool_repository).to be_nil + end + end + end - it 'joins the object pool' do - forked_project = fork_project(fork_from_project, forker, using_service: true) + context 'when a pool already exists' do + let!(:pool_repository) { create(:pool_repository, source_project: project) } - expect(forked_project.pool_repository).to eq(fork_from_project.pool_repository) - end - end - end + it 'joins the object pool' do + expect { fork_of_project }.not_to change { PoolRepository.count } - context 'when linking fork to an existing project' do - let(:fork_from_project) { create(:project, :public) } - let(:fork_to_project) { create(:project, :public) } - let(:user) do - create(:user).tap { |u| fork_to_project.add_maintainer(u) } - end - - subject { described_class.new(fork_from_project, user) } - - def forked_from_project(project) - project.fork_network_member&.forked_from_project - end - - context 'if project is already forked' do - it 'does not create fork relation' do - allow(fork_to_project).to receive(:forked?).and_return(true) - expect(forked_from_project(fork_to_project)).to be_nil - expect(subject.execute(fork_to_project)).to be_nil - expect(forked_from_project(fork_to_project)).to be_nil - end - end - - context 'if project is not forked' do - it 'creates fork relation' do - expect(fork_to_project.forked?).to be_falsy - expect(forked_from_project(fork_to_project)).to be_nil - - subject.execute(fork_to_project) - - fork_to_project.reload - - expect(fork_to_project.forked?).to be true - expect(forked_from_project(fork_to_project)).to eq fork_from_project - expect(fork_to_project.forked_from_project).to eq fork_from_project + expect(fork_of_project.pool_repository).to eq(pool_repository) + end + end end - it 'flushes the forks count cache of the source project' do - expect(fork_from_project.forks_count).to be_zero + context 'when linking fork to an existing project' do + let_it_be_with_reload(:unlinked_fork) { create(:project, :public) } - subject.execute(fork_to_project) - BatchLoader::Executor.clear_current + before_all do + unlinked_fork.add_developer(user) + end - expect(fork_from_project.forks_count).to eq(1) - end + def forked_from_project(project) + project.fork_network_member&.forked_from_project + end - context 'if the fork is not allowed' do - let(:fork_from_project) { create(:project, :private) } + context 'if project is already forked' do + it 'does not create fork relation' do + allow(unlinked_fork).to receive(:forked?).and_return(true) - it 'does not delete the LFS objects' do - create(:lfs_objects_project, project: fork_to_project) + expect(forked_from_project(unlinked_fork)).to be_nil - expect { subject.execute(fork_to_project) } - .not_to change { fork_to_project.lfs_objects_projects.size } + expect(service.execute(unlinked_fork)).to be_nil + + expect(forked_from_project(unlinked_fork)).to be_nil + end + end + + context 'if project is not forked' do + it 'creates fork relation' do + expect(unlinked_fork.forked?).to be_falsy + expect(forked_from_project(unlinked_fork)).to be_nil + + service.execute(unlinked_fork) + + unlinked_fork.reload + + expect(unlinked_fork.forked?).to be true + expect(forked_from_project(unlinked_fork)).to eq project + expect(unlinked_fork.forked_from_project).to eq project + end + + it 'flushes the forks count cache of the source project' do + expect(project.forks_count).to be_zero + + service.execute(unlinked_fork) + BatchLoader::Executor.clear_current + + expect(project.forks_count).to eq(1) + end + + context 'if the fork is not allowed' do + let_it_be(:project) { create(:project, :private) } + + it 'does not delete the LFS objects' do + create(:lfs_objects_project, project: unlinked_fork) + + expect { service.execute(unlinked_fork) } + .not_to change { unlinked_fork.lfs_objects_projects.size } + end + end end end end end describe '#valid_fork_targets' do + subject { service.valid_fork_targets } + let(:finder_mock) { instance_double('ForkTargetsFinder', execute: ['finder_return_value']) } - let(:current_user) { instance_double('User') } - let(:project) { instance_double('Project') } before do - allow(ForkTargetsFinder).to receive(:new).with(project, current_user).and_return(finder_mock) + allow(ForkTargetsFinder).to receive(:new).with(project, user).and_return(finder_mock) end it 'returns whatever finder returns' do - expect(described_class.new(project, current_user).valid_fork_targets).to eq ['finder_return_value'] + is_expected.to eq ['finder_return_value'] end end describe '#valid_fork_branch?' do - let_it_be(:user) { create(:user) } - let_it_be(:project) { create(:project, :small_repo, creator_id: user.id) } - let_it_be(:branch) { nil } - - subject { described_class.new(project, user).valid_fork_branch?(branch) } + subject { service.valid_fork_branch?(branch) } context 'when branch exists' do let(:branch) { project.default_branch_or_main } @@ -533,12 +515,11 @@ RSpec.describe Projects::ForkService, feature_category: :source_code_management end describe '#valid_fork_target?' do - let(:project) { Project.new } + subject { service.valid_fork_target? } + let(:params) { {} } context 'when target is not passed' do - subject { described_class.new(project, user, params).valid_fork_target? } - context 'when current user is an admin' do let(:user) { build(:user, :admin) } @@ -549,7 +530,6 @@ RSpec.describe Projects::ForkService, feature_category: :source_code_management let(:user) { create(:user) } let(:finder_mock) { instance_double('ForkTargetsFinder', execute: [user.namespace]) } - let(:project) { create(:project) } before do allow(ForkTargetsFinder).to receive(:new).with(project, user).and_return(finder_mock) @@ -570,9 +550,9 @@ RSpec.describe Projects::ForkService, feature_category: :source_code_management end context 'when target is passed' do - let(:target) { create(:group) } + subject { service.valid_fork_target?(target) } - subject { described_class.new(project, user, params).valid_fork_target?(target) } + let(:target) { create(:group) } context 'when current user is an admin' do let(:user) { build(:user, :admin) }