Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
d59bc6c73d
commit
a0a2334dfd
|
|
@ -1,6 +1,6 @@
|
|||
include:
|
||||
- project: gitlab-org/quality/pipeline-common
|
||||
ref: 8.3.2
|
||||
ref: 8.4.0
|
||||
file:
|
||||
- /ci/danger-review.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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -74,7 +74,9 @@ export default {
|
|||
</template>
|
||||
</gl-card>
|
||||
|
||||
<!-- user count is currently not supported for integrated error tracking https://gitlab.com/gitlab-org/opstrace/opstrace/-/issues/2345 -->
|
||||
<gl-card
|
||||
v-if="!error.integrated"
|
||||
:class="$options.CARD_CLASS"
|
||||
:body-class="$options.BODY_CLASS"
|
||||
:header-class="$options.HEADER_CLASS"
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ export default {
|
|||
{
|
||||
key: 'status',
|
||||
label: '',
|
||||
tdClass: `${tableDataClass}`,
|
||||
tdClass: `${tableDataClass} gl-text-center`,
|
||||
},
|
||||
],
|
||||
statusFilters: {
|
||||
|
|
@ -182,6 +182,13 @@ export default {
|
|||
showIntegratedDisabledAlert() {
|
||||
return !this.isAlertDismissed && this.showIntegratedTrackingDisabledAlert;
|
||||
},
|
||||
fields() {
|
||||
if (this.integratedErrorTrackingEnabled) {
|
||||
// user count is currently not supported for integrated error tracking https://gitlab.com/gitlab-org/opstrace/opstrace/-/issues/2345
|
||||
return this.$options.fields.filter((field) => field.key !== 'users');
|
||||
}
|
||||
return this.$options.fields;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
pagination() {
|
||||
|
|
@ -417,7 +424,7 @@ export default {
|
|||
<gl-table
|
||||
class="error-list-table gl-mt-5"
|
||||
:items="errors"
|
||||
:fields="$options.fields"
|
||||
:fields="fields"
|
||||
:show-empty="true"
|
||||
fixed
|
||||
stacked="md"
|
||||
|
|
|
|||
|
|
@ -46,15 +46,11 @@ module EnforcesTwoFactorAuthentication
|
|||
end
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def two_factor_authentication_reason(global: -> {}, 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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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' }
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
bb86e8dd465b6bfa394c16e27a7ebc16b63545f9b7675e57399ac159d4b53711
|
||||
|
|
@ -0,0 +1 @@
|
|||
e3fce3184c7e9c3e84e73caeaee94ab14dafc46c046e8477d5762b3d41a11a02
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -49,18 +49,18 @@ feature is available.
|
|||
|
||||
DevOps Adoption shows feature adoption for development, security, and operations.
|
||||
|
||||
| Category | Feature |
|
||||
| --- | --- |
|
||||
| Development | Approvals<br>Code owners<br>Issues<br>Merge requests |
|
||||
| Security | DAST<br>Dependency Scanning<br>Fuzz Testing<br>SAST |
|
||||
| Operations | Deployments<br>Pipelines<br>Runners |
|
||||
| Category | Feature |
|
||||
|-------------|---------|
|
||||
| Development | Approvals<br>Code owners<br>Issues<br>Merge requests |
|
||||
| Security | DAST<br>Dependency Scanning<br>Fuzz Testing<br>SAST |
|
||||
| Operations | Deployments<br>Pipelines<br>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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 `<instance_url>/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:
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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**.
|
||||
|
||||

|
||||
|
||||
|
|
|
|||
|
|
@ -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 <sup>1</sup> |
|
||||
| Project, Personal Snippet (using the web UI) | **{dotted-circle}** No |
|
||||
| Project, Personal Snippet (using Git) | **{check-circle}** Yes <sup>1</sup> |
|
||||
| Group wiki repository (using the web UI) | **{dotted-circle}** No |
|
||||
| Group wiki repository (using Git) | **{check-circle}** Yes <sup>1</sup> |
|
||||
| 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 <sup>2</sup> |
|
||||
| Advanced search (using the web UI) | **{dotted-circle}** No |
|
||||
| Container registry | **{dotted-circle}** No <sup>3</sup>|
|
||||
| Dependency Proxy | **{dotted-circle}** No <sup>4</sup>|
|
||||
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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**.
|
||||
|
|
|
|||
|
|
@ -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'] = { '<slot_name>' => 'physical' }`
|
||||
to `gitlab.rb` where `<slot_name>` 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 `<slot_name>` 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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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({
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 | <https://wiki.debian.org/LTS> |
|
||||
| Debian 11 | GitLab CE / GitLab EE 14.6.0 | amd64, arm64 | [Debian Install Documentation](https://about.gitlab.com/install/#debian) | 2026 | <https://wiki.debian.org/LTS> |
|
||||
| Debian 12 | GitLab CE / GitLab EE 16.1.0 | amd64, arm64 | [Debian Install Documentation](https://about.gitlab.com/install/#debian) | TBD | <https://wiki.debian.org/LTS> |
|
||||
| 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 | <https://en.opensuse.org/Lifetime> |
|
||||
| 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 | <https://en.opensuse.org/Lifetime> |
|
||||
| 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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -15589,8 +15589,6 @@ four standard [pagination arguments](#connection-pagination-arguments):
|
|||
| <a id="cicatalogresourceversionpath"></a>`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. |
|
||||
| <a id="cicatalogresourceversionreadmehtml"></a>`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. |
|
||||
| <a id="cicatalogresourceversionreleasedat"></a>`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. |
|
||||
| <a id="cicatalogresourceversiontagname"></a>`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. |
|
||||
| <a id="cicatalogresourceversiontagpath"></a>`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`
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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%.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -124,6 +124,24 @@ Before upgrading to GitLab 18.0, please ensure you have [migrated](https://docs.
|
|||
|
||||
<div class="deprecation breaking-change" data-milestone="18.0">
|
||||
|
||||
### Slack notifications integration
|
||||
|
||||
<div class="deprecation-notes">
|
||||
- Announced in GitLab <span class="milestone">15.9</span>
|
||||
- Removal in GitLab <span class="milestone">18.0</span> ([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).
|
||||
</div>
|
||||
|
||||
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.
|
||||
|
||||
</div>
|
||||
|
||||
<div class="deprecation breaking-change" data-milestone="18.0">
|
||||
|
||||
### Support for REST API endpoints that reset runner registration tokens
|
||||
|
||||
<div class="deprecation-notes">
|
||||
|
|
@ -595,6 +613,20 @@ are deprecated and will be removed from the GraphQL API. For installation instru
|
|||
|
||||
<div class="deprecation breaking-change" data-milestone="17.0">
|
||||
|
||||
### GitLab Runner provenance metadata SLSA v0.2 statement
|
||||
|
||||
<div class="deprecation-notes">
|
||||
- Announced in GitLab <span class="milestone">16.8</span>
|
||||
- Removal in GitLab <span class="milestone">17.0</span> ([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).
|
||||
</div>
|
||||
|
||||
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.
|
||||
|
||||
</div>
|
||||
|
||||
<div class="deprecation breaking-change" data-milestone="17.0">
|
||||
|
||||
### GraphQL deprecation of `dependencyProxyTotalSizeInBytes` field
|
||||
|
||||
<div class="deprecation-notes">
|
||||
|
|
@ -1115,25 +1147,6 @@ automatically from GitLab 16.0 onwards.
|
|||
|
||||
<div class="deprecation breaking-change" data-milestone="17.0">
|
||||
|
||||
### Slack notifications integration
|
||||
|
||||
<div class="deprecation-notes">
|
||||
- Announced in GitLab <span class="milestone">15.9</span>
|
||||
- Removal in GitLab <span class="milestone">17.0</span> ([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).
|
||||
</div>
|
||||
|
||||
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).
|
||||
|
||||
</div>
|
||||
|
||||
<div class="deprecation breaking-change" data-milestone="17.0">
|
||||
|
||||
### The GitHub importer Rake task
|
||||
|
||||
<div class="deprecation-notes">
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||

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

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

|
||||
<!-- This redirect file can be deleted after <2024-04-05>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
|
|||
|
|
@ -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). |
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
|
|
|||
|
|
@ -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 ""
|
||||
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ gitlab:
|
|||
memory: 1500Mi
|
||||
limits:
|
||||
cpu: 700m
|
||||
memory: 2000Mi
|
||||
memory: 2200Mi
|
||||
hpa:
|
||||
cpu:
|
||||
targetAverageValue: 650m
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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({
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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) }
|
||||
|
|
|
|||
Loading…
Reference in New Issue