Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-11-01 06:10:42 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-11-01 06:10:42 +0300
commit24ed1c84da7fb6df910f06552bc9e2e7fe5bcb59 (patch)
tree2e648cbac693d1fe3dd2720c9f608470998d6b03
parent533fed8bd825f93b4b43bd41d41caa38cfc6ae55 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.rubocop_todo/layout/argument_alignment.yml9
-rw-r--r--app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue50
-rw-r--r--app/assets/javascripts/pages/projects/forks/new/index.js2
-rw-r--r--app/assets/javascripts/work_items/components/work_item_title.vue7
-rw-r--r--app/assets/javascripts/work_items/constants.js7
-rw-r--r--app/models/project.rb6
-rw-r--r--app/services/projects/fork_service.rb13
-rw-r--r--app/views/admin/application_settings/_gitlab_shell_operation_limits.html.haml2
-rw-r--r--app/views/admin/application_settings/_import_export_limits.html.haml3
-rw-r--r--app/views/admin/application_settings/_performance.html.haml6
-rw-r--r--app/views/admin/application_settings/_projects_api_limits.html.haml2
-rw-r--r--app/views/projects/forks/new.html.haml1
-rw-r--r--app/workers/repository_fork_worker.rb22
-rw-r--r--db/docs/namespaces.yml4
-rw-r--r--db/post_migrate/20231024015915_drop_index_namespaces_on_created_at_for_gitlab_com.rb24
-rw-r--r--db/post_migrate/20231026103346_drop_project_settings_jitsu_key.rb21
-rw-r--r--db/schema_migrations/202310240159151
-rw-r--r--db/schema_migrations/202310261033461
-rw-r--r--db/structure.sql2
-rw-r--r--doc/api/lint.md4
-rw-r--r--doc/api/projects.md1
-rw-r--r--lib/api/projects.rb2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml2
-rw-r--r--lib/gitlab/database/gitlab_schema.rb1
-rw-r--r--lib/gitlab/database/tables_locker.rb2
-rw-r--r--lib/gitlab/database/tables_truncate.rb2
-rw-r--r--lib/gitlab/gitaly_client/repository_service.rb7
-rw-r--r--locale/gitlab.pot30
-rw-r--r--rubocop/cop/migration/with_lock_retries_disallowed_method.rb2
-rw-r--r--spec/db/docs_spec.rb5
-rw-r--r--spec/frontend/pages/projects/forks/new/components/fork_form_spec.js42
-rw-r--r--spec/frontend/work_items/components/work_item_title_spec.js20
-rw-r--r--spec/helpers/admin/components_helper_spec.rb1
-rw-r--r--spec/lib/gitlab/diff/file_collection/compare_spec.rb8
-rw-r--r--spec/lib/gitlab/diff/file_collection/merge_request_diff_batch_spec.rb25
-rw-r--r--spec/lib/gitlab/diff/file_collection/paginated_merge_request_diff_spec.rb16
-rw-r--r--spec/lib/gitlab/diff/file_spec.rb5
-rw-r--r--spec/lib/gitlab/diff/highlight_cache_spec.rb20
-rw-r--r--spec/lib/gitlab/diff/line_spec.rb14
-rw-r--r--spec/lib/gitlab/diff/suggestion_diff_spec.rb13
-rw-r--r--spec/lib/gitlab/diff/suggestion_spec.rb22
-rw-r--r--spec/lib/gitlab/diff/suggestions_parser_spec.rb67
-rw-r--r--spec/lib/gitlab/gitaly_client/repository_service_spec.rb38
-rw-r--r--spec/models/merge_request_spec.rb10
-rw-r--r--spec/services/projects/fork_service_spec.rb20
-rw-r--r--spec/support/shared_examples/database_health_status_indicators/prometheus_alert_based_shared_examples.rb4
-rw-r--r--spec/tasks/gitlab/background_migrations_rake_spec.rb1
-rw-r--r--spec/tasks/gitlab/db_rake_spec.rb4
-rw-r--r--spec/workers/repository_fork_worker_spec.rb30
50 files changed, 438 insertions, 165 deletions
diff --git a/.rubocop_todo/layout/argument_alignment.yml b/.rubocop_todo/layout/argument_alignment.yml
index 982304c0220..7b372bfd01a 100644
--- a/.rubocop_todo/layout/argument_alignment.yml
+++ b/.rubocop_todo/layout/argument_alignment.yml
@@ -1465,15 +1465,6 @@ Layout/ArgumentAlignment:
- 'spec/lib/gitlab/data_builder/push_spec.rb'
- 'spec/lib/gitlab/database/migration_helpers_spec.rb'
- 'spec/lib/gitlab/dependency_linker/parser/gemfile_spec.rb'
- - 'spec/lib/gitlab/diff/file_collection/compare_spec.rb'
- - 'spec/lib/gitlab/diff/file_collection/merge_request_diff_batch_spec.rb'
- - 'spec/lib/gitlab/diff/file_collection/paginated_merge_request_diff_spec.rb'
- - 'spec/lib/gitlab/diff/file_spec.rb'
- - 'spec/lib/gitlab/diff/highlight_cache_spec.rb'
- - 'spec/lib/gitlab/diff/line_spec.rb'
- - 'spec/lib/gitlab/diff/suggestion_diff_spec.rb'
- - 'spec/lib/gitlab/diff/suggestion_spec.rb'
- - 'spec/lib/gitlab/diff/suggestions_parser_spec.rb'
- 'spec/lib/gitlab/email/hook/delivery_metrics_observer_spec.rb'
- 'spec/lib/gitlab/email/hook/smime_signature_interceptor_spec.rb'
- 'spec/lib/gitlab/error_tracking/processor/context_payload_processor_spec.rb'
diff --git a/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue b/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue
index 9659c927fbf..e3d50e900ca 100644
--- a/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue
+++ b/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue
@@ -7,6 +7,7 @@ import {
GlFormGroup,
GlFormTextarea,
GlButton,
+ GlSprintf,
GlFormRadio,
GlFormRadioGroup,
} from '@gitlab/ui';
@@ -56,6 +57,7 @@ export default {
GlIcon,
GlLink,
GlButton,
+ GlSprintf,
GlFormInput,
GlFormTextarea,
GlFormGroup,
@@ -91,6 +93,9 @@ export default {
projectDescription: {
default: '',
},
+ projectDefaultBranch: {
+ default: '',
+ },
projectVisibility: {
default: '',
},
@@ -116,6 +121,7 @@ export default {
required: false,
skipValidation: true,
}),
+ branches: initFormField({ value: '', required: true, skipValidation: true }),
visibility: initFormField({ value: null }),
},
};
@@ -168,6 +174,18 @@ export default {
return allowedLevels;
},
+ branchesOptions() {
+ return [
+ {
+ text: s__('ForkProject|All branches'),
+ value: '',
+ },
+ {
+ text: s__(`ForkProject|Only the default branch %{defaultBranch}`),
+ value: this.projectDefaultBranch,
+ },
+ ];
+ },
visibilityLevels() {
return [
{
@@ -245,7 +263,7 @@ export default {
this.form.showValidation = false;
const { projectId } = this;
- const { name, slug, description, visibility, namespace } = this.form.fields;
+ const { name, slug, description, branches, visibility, namespace } = this.form.fields;
const postParams = {
id: projectId,
@@ -253,6 +271,7 @@ export default {
namespace_id: namespace.value.id,
path: slug.value,
description: description.value,
+ branches: branches.value,
visibility: visibility.value,
};
@@ -263,6 +282,7 @@ export default {
const { data } = await axios.post(url, postParams);
redirectTo(data.web_url); // eslint-disable-line import/no-deprecated
} catch (error) {
+ this.isSaving = false;
createAlert({
message: s__(
'ForkProject|An error occurred while forking the project. Please try again.',
@@ -348,6 +368,34 @@ export default {
/>
</gl-form-group>
+ <gl-form-group>
+ <label>
+ {{ s__('ForkProject|Branches to include') }}
+ </label>
+ <gl-form-radio-group
+ v-model="form.fields.branches.value"
+ data-testid="fork-branches-radio-group"
+ name="branches"
+ :aria-label="__('branches')"
+ required
+ >
+ <gl-form-radio
+ v-for="{ text, value } in branchesOptions"
+ :key="value"
+ :value="value"
+ :data-testid="`radio-${value}`"
+ >
+ <div>
+ <gl-sprintf :message="text">
+ <template #defaultBranch>
+ <code class="gl-ml-2">{{ projectDefaultBranch }}</code>
+ </template>
+ </gl-sprintf>
+ </div>
+ </gl-form-radio>
+ </gl-form-radio-group>
+ </gl-form-group>
+
<gl-form-group
v-validation:[form.showValidation]
:invalid-feedback="s__('ForkProject|Please select a visibility level')"
diff --git a/app/assets/javascripts/pages/projects/forks/new/index.js b/app/assets/javascripts/pages/projects/forks/new/index.js
index a31b8b1a1f4..694914e9154 100644
--- a/app/assets/javascripts/pages/projects/forks/new/index.js
+++ b/app/assets/javascripts/pages/projects/forks/new/index.js
@@ -15,6 +15,7 @@ const {
projectId,
projectName,
projectPath,
+ projectDefaultBranch,
projectDescription,
projectVisibility,
restrictedVisibilityLevels,
@@ -38,6 +39,7 @@ new Vue({
projectName,
projectPath,
projectDescription,
+ projectDefaultBranch,
projectVisibility,
restrictedVisibilityLevels: JSON.parse(restrictedVisibilityLevels),
},
diff --git a/app/assets/javascripts/work_items/components/work_item_title.vue b/app/assets/javascripts/work_items/components/work_item_title.vue
index 966a72631c6..9b5803421dd 100644
--- a/app/assets/javascripts/work_items/components/work_item_title.vue
+++ b/app/assets/javascripts/work_items/components/work_item_title.vue
@@ -5,6 +5,8 @@ import {
sprintfWorkItem,
I18N_WORK_ITEM_ERROR_UPDATING,
TRACKING_CATEGORY_SHOW,
+ WORK_ITEM_TITLE_MAX_LENGTH,
+ I18N_MAX_CHARS_IN_WORK_ITEM_TITLE_MESSAGE,
} from '../constants';
import { getUpdateWorkItemMutation } from './update_work_item';
import ItemTitle from './item_title.vue';
@@ -56,6 +58,11 @@ export default {
return;
}
+ if (updatedTitle.length > WORK_ITEM_TITLE_MAX_LENGTH) {
+ this.$emit('error', sprintfWorkItem(I18N_MAX_CHARS_IN_WORK_ITEM_TITLE_MESSAGE));
+ return;
+ }
+
const input = {
id: this.workItemId,
title: updatedTitle,
diff --git a/app/assets/javascripts/work_items/constants.js b/app/assets/javascripts/work_items/constants.js
index e4fa277485a..9632165b8cb 100644
--- a/app/assets/javascripts/work_items/constants.js
+++ b/app/assets/javascripts/work_items/constants.js
@@ -45,6 +45,8 @@ export const WORK_ITEM_TYPE_VALUE_REQUIREMENTS = 'Requirements';
export const WORK_ITEM_TYPE_VALUE_KEY_RESULT = 'Key Result';
export const WORK_ITEM_TYPE_VALUE_OBJECTIVE = 'Objective';
+export const WORK_ITEM_TITLE_MAX_LENGTH = 255;
+
export const i18n = {
fetchErrorTitle: s__('WorkItem|Work item not found'),
fetchError: s__(
@@ -108,6 +110,11 @@ export const I18N_WORK_ITEM_ERROR_COPY_EMAIL = s__(
'WorkItem|Something went wrong while copying the %{workItemType} email address. Please try again.',
);
+export const I18N_MAX_CHARS_IN_WORK_ITEM_TITLE_MESSAGE = sprintf(
+ s__('WorkItem|Title cannot have more than %{WORK_ITEM_TITLE_MAX_LENGTH} characters.'),
+ { WORK_ITEM_TITLE_MAX_LENGTH },
+);
+
export const I18N_WORK_ITEM_COPY_CREATE_NOTE_EMAIL = s__(
'WorkItem|Copy %{workItemType} email address',
);
diff --git a/app/models/project.rb b/app/models/project.rb
index b8f02297ad7..bc6d2600d83 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1444,12 +1444,10 @@ class Project < ApplicationRecord
end
def build_or_assign_import_data(data: nil, credentials: nil)
- return if data.nil? && credentials.nil?
-
project_import_data = import_data || build_import_data
- project_import_data.merge_data(data.to_h)
- project_import_data.merge_credentials(credentials.to_h)
+ project_import_data.merge_data(data.to_h) if data
+ project_import_data.merge_credentials(credentials.to_h) if credentials
project_import_data
end
diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb
index aace8846afc..168420b17bf 100644
--- a/app/services/projects/fork_service.rb
+++ b/app/services/projects/fork_service.rb
@@ -17,6 +17,10 @@ module Projects
@valid_fork_targets ||= ForkTargetsFinder.new(@project, current_user).execute(options)
end
+ def valid_fork_branch?(branch)
+ @project.repository.branch_exists?(branch)
+ end
+
def valid_fork_target?(namespace = target_namespace)
return true if current_user.admin?
@@ -68,7 +72,8 @@ module Projects
external_authorization_classification_label: @project.external_authorization_classification_label,
suggestion_commit_message: @project.suggestion_commit_message,
merge_commit_template: @project.merge_commit_template,
- squash_commit_template: @project.squash_commit_template
+ squash_commit_template: @project.squash_commit_template,
+ import_data: { data: { fork_branch: branch } }
}
if @project.avatar.present? && @project.avatar.image?
@@ -145,6 +150,12 @@ module Projects
def stream_audit_event(forked_project)
# Defined in EE
end
+
+ def branch
+ # We extract branch name from @params[:branches] because the front end
+ # insists on sending it as 'branches'.
+ @params[:branches]
+ end
end
end
diff --git a/app/views/admin/application_settings/_gitlab_shell_operation_limits.html.haml b/app/views/admin/application_settings/_gitlab_shell_operation_limits.html.haml
index 8529accff8e..22372146ea1 100644
--- a/app/views/admin/application_settings/_gitlab_shell_operation_limits.html.haml
+++ b/app/views/admin/application_settings/_gitlab_shell_operation_limits.html.haml
@@ -15,5 +15,5 @@
.form-group
= f.label :gitlab_shell_operation_limit, s_('ShellOperations|Maximum number of Git operations per minute'), class: 'gl-font-bold'
= f.number_field :gitlab_shell_operation_limit, class: 'form-control gl-form-input'
-
+ %span.form-text.text-muted= _('Set to 0 to disable the limit.')
= f.submit _('Save changes'), pajamas_button: true
diff --git a/app/views/admin/application_settings/_import_export_limits.html.haml b/app/views/admin/application_settings/_import_export_limits.html.haml
index 8cb7915f847..269a1497324 100644
--- a/app/views/admin/application_settings/_import_export_limits.html.haml
+++ b/app/views/admin/application_settings/_import_export_limits.html.haml
@@ -2,8 +2,7 @@
= form_errors(@application_setting)
%fieldset
- = html_escape(_("Set any rate limit to %{code_open}0%{code_close} to disable the limit.")) % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
-
+ = html_escape(_("Set to 0 to disable the limits."))
%fieldset
.form-group
diff --git a/app/views/admin/application_settings/_performance.html.haml b/app/views/admin/application_settings/_performance.html.haml
index bfa548b70e5..14c785509bd 100644
--- a/app/views/admin/application_settings/_performance.html.haml
+++ b/app/views/admin/application_settings/_performance.html.haml
@@ -11,16 +11,16 @@
= f.label :raw_blob_request_limit, _('Raw blob request rate limit per minute'), class: 'label-bold'
= f.number_field :raw_blob_request_limit, class: 'form-control gl-form-input'
.form-text.text-muted
- = _('Maximum number of requests per minute for each raw path (default is `300`). Set to `0` to disable throttling.')
+ = _('Maximum number of requests per minute for each raw path (default is 300). Set to 0 to disable throttling.')
.form-group
= f.label :push_event_hooks_limit, class: 'label-bold'
= f.number_field :push_event_hooks_limit, class: 'form-control gl-form-input'
.form-text.text-muted
- = _('Maximum number of changes (branches or tags) in a single push above which webhooks and integrations are not triggered (default is `3`). Setting to `0` does not disable throttling.')
+ = _('Maximum number of changes (branches or tags) in a single push above which webhooks and integrations are not triggered (default is 3). Setting to 0 does not disable throttling.')
.form-group
= f.label :push_event_activities_limit, class: 'label-bold'
= f.number_field :push_event_activities_limit, class: 'form-control gl-form-input'
.form-text.text-muted
- = _('Maximum number of changes (branches or tags) in a single push above which a bulk push event is created (default is `3`). Setting to `0` does not disable throttling.')
+ = _('Maximum number of changes (branches or tags) in a single push above which a bulk push event is created (default is 3). Setting to 0 does not disable throttling.')
= f.submit _('Save changes'), pajamas_button: true
diff --git a/app/views/admin/application_settings/_projects_api_limits.html.haml b/app/views/admin/application_settings/_projects_api_limits.html.haml
index d84df972c6d..c9eff76916a 100644
--- a/app/views/admin/application_settings/_projects_api_limits.html.haml
+++ b/app/views/admin/application_settings/_projects_api_limits.html.haml
@@ -16,6 +16,6 @@
= f.label :projects_api_rate_limit_unauthenticated, _('Maximum requests per 10 minutes per IP address'), class: 'label-bold'
= f.number_field :projects_api_rate_limit_unauthenticated, class: 'form-control gl-form-input'
.form-text.gl-text-gray-600
- = _("Set this number to 0 to disable the limit.")
+ = _("Set to 0 to disable the limit.")
= f.submit _('Save changes'), data: { qa_selector: 'save_changes_button' }, pajamas_button: true
diff --git a/app/views/projects/forks/new.html.haml b/app/views/projects/forks/new.html.haml
index e9c6b3fcd22..1194a361753 100644
--- a/app/views/projects/forks/new.html.haml
+++ b/app/views/projects/forks/new.html.haml
@@ -9,6 +9,7 @@
project_id: @project.id,
project_name: @project.name,
project_path: @project.path,
+ project_default_branch: @project.default_branch,
project_description: @project.description,
project_visibility: @project.visibility,
restricted_visibility_levels: Gitlab::CurrentSettings.restricted_visibility_levels.to_json } }
diff --git a/app/workers/repository_fork_worker.rb b/app/workers/repository_fork_worker.rb
index 5ec9ceaf004..f4a507246ac 100644
--- a/app/workers/repository_fork_worker.rb
+++ b/app/workers/repository_fork_worker.rb
@@ -2,6 +2,7 @@
class RepositoryForkWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
+ include Gitlab::Utils::StrongMemoize
data_consistency :always
@@ -12,10 +13,8 @@ class RepositoryForkWorker # rubocop:disable Scalability/IdempotentWorker
feature_category :source_code_management
def perform(*args)
- target_project_id = args.shift
- target_project = Project.find(target_project_id)
+ @target_project_id = args.shift
- source_project = target_project.forked_from_project
unless source_project
return target_project.import_state.mark_as_failed(_('Source project cannot be found.'))
end
@@ -25,6 +24,21 @@ class RepositoryForkWorker # rubocop:disable Scalability/IdempotentWorker
private
+ def target_project
+ Project.find(@target_project_id)
+ end
+ strong_memoize_attr :target_project
+
+ def source_project
+ @source_project ||= target_project.forked_from_project
+ end
+
+ def branch
+ return unless target_project.import_data&.data
+
+ target_project.import_data.data['fork_branch']
+ end
+
def fork_repository(target_project, source_project)
return unless start_fork(target_project)
@@ -46,7 +60,7 @@ class RepositoryForkWorker # rubocop:disable Scalability/IdempotentWorker
source_repo = source_project.repository.raw
target_repo = target_project.repository.raw
- ::Gitlab::GitalyClient::RepositoryService.new(target_repo).fork_repository(source_repo)
+ ::Gitlab::GitalyClient::RepositoryService.new(target_repo).fork_repository(source_repo, branch)
rescue GRPC::BadStatus => e
Gitlab::ErrorTracking.track_exception(e, source_project_id: source_project.id, target_project_id: target_project.id)
diff --git a/db/docs/namespaces.yml b/db/docs/namespaces.yml
index ba3d345d8c7..4010858ce5a 100644
--- a/db/docs/namespaces.yml
+++ b/db/docs/namespaces.yml
@@ -11,3 +11,7 @@ description: Storing namespaces records for groups, users and projects
introduced_by_url: https://github.com/gitlabhq/gitlabhq/pull/2051
milestone: "<6.0"
gitlab_schema: gitlab_main_cell
+schema_inconsistencies:
+- type: missing_indexes
+ object_name: index_namespaces_on_created_at
+ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/134948
diff --git a/db/post_migrate/20231024015915_drop_index_namespaces_on_created_at_for_gitlab_com.rb b/db/post_migrate/20231024015915_drop_index_namespaces_on_created_at_for_gitlab_com.rb
new file mode 100644
index 00000000000..8f2f8a4064c
--- /dev/null
+++ b/db/post_migrate/20231024015915_drop_index_namespaces_on_created_at_for_gitlab_com.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class DropIndexNamespacesOnCreatedAtForGitlabCom < Gitlab::Database::Migration[2.1]
+ disable_ddl_transaction!
+
+ TABLE_NAME = :namespaces
+ INDEX_NAME = :index_namespaces_on_created_at
+
+ def up
+ return unless should_run?
+
+ remove_concurrent_index_by_name TABLE_NAME, INDEX_NAME
+ end
+
+ def down
+ return unless should_run?
+
+ add_concurrent_index TABLE_NAME, :created_at, name: INDEX_NAME
+ end
+
+ def should_run?
+ Gitlab.com_except_jh?
+ end
+end
diff --git a/db/post_migrate/20231026103346_drop_project_settings_jitsu_key.rb b/db/post_migrate/20231026103346_drop_project_settings_jitsu_key.rb
new file mode 100644
index 00000000000..606648ca7fa
--- /dev/null
+++ b/db/post_migrate/20231026103346_drop_project_settings_jitsu_key.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+class DropProjectSettingsJitsuKey < Gitlab::Database::Migration[2.2]
+ milestone '16.6'
+
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ remove_column :project_settings, :jitsu_key, if_exists: true
+ end
+ end
+
+ def down
+ with_lock_retries do
+ add_column :project_settings, :jitsu_key, :text, if_not_exists: true
+ end
+
+ add_text_limit :project_settings, :jitsu_key, 100
+ end
+end
diff --git a/db/schema_migrations/20231024015915 b/db/schema_migrations/20231024015915
new file mode 100644
index 00000000000..7f6eac81c71
--- /dev/null
+++ b/db/schema_migrations/20231024015915
@@ -0,0 +1 @@
+8ad5065584f72084ee929e479725593330d0d13542dc4939476d62f831c6f2e8 \ No newline at end of file
diff --git a/db/schema_migrations/20231026103346 b/db/schema_migrations/20231026103346
new file mode 100644
index 00000000000..53f5520bcc4
--- /dev/null
+++ b/db/schema_migrations/20231026103346
@@ -0,0 +1 @@
+dc0065c2caffdf5bbf79c1e94f8bdb6d415a836cc575109d25df8217423be0e1 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 925db79d44c..a9e416c4c57 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -21829,7 +21829,6 @@ CREATE TABLE project_settings (
selective_code_owner_removals boolean DEFAULT false NOT NULL,
issue_branch_template text,
show_diff_preview_in_email boolean DEFAULT true NOT NULL,
- jitsu_key text,
suggested_reviewers_enabled boolean DEFAULT false NOT NULL,
only_allow_merge_if_all_status_checks_passed boolean DEFAULT false NOT NULL,
mirror_branch_regex text,
@@ -21847,7 +21846,6 @@ CREATE TABLE project_settings (
encrypted_product_analytics_configurator_connection_string_iv bytea,
pages_multiple_versions_enabled boolean DEFAULT false NOT NULL,
CONSTRAINT check_1a30456322 CHECK ((char_length(pages_unique_domain) <= 63)),
- CONSTRAINT check_2981f15877 CHECK ((char_length(jitsu_key) <= 100)),
CONSTRAINT check_3a03e7557a CHECK ((char_length(previous_default_branch) <= 4096)),
CONSTRAINT check_3ca5cbffe6 CHECK ((char_length(issue_branch_template) <= 255)),
CONSTRAINT check_4b142e71f3 CHECK ((char_length(product_analytics_data_collector_host) <= 255)),
diff --git a/doc/api/lint.md b/doc/api/lint.md
index 7b288c34343..45ae739ef86 100644
--- a/doc/api/lint.md
+++ b/doc/api/lint.md
@@ -20,7 +20,7 @@ POST /projects/:id/ci/lint
| `content` | string | Yes | The CI/CD configuration content. |
| `dry_run` | boolean | No | Run [pipeline creation simulation](../ci/lint.md#simulate-a-pipeline), or only do static check. Default: `false`. |
| `include_jobs` | boolean | No | If the list of jobs that would exist in a static check or pipeline simulation should be included in the response. Default: `false`. |
-| `ref` | string | No | When `dry_run` is `true`, sets the branch or tag to use. Defaults to the project's default branch when not set. |
+| `ref` | string | No | When `dry_run` is `true`, sets the branch or tag context to use to validate the CI/CD YAML configuration. Defaults to the project's default branch when not set. |
Example request:
@@ -71,7 +71,7 @@ GET /projects/:id/ci/lint
|----------------|---------|----------|-------------|
| `dry_run` | boolean | No | Run pipeline creation simulation, or only do static check. |
| `include_jobs` | boolean | No | If the list of jobs that would exist in a static check or pipeline simulation should be included in the response. Default: `false`. |
-| `ref` | string | No | When `dry_run` is `true`, sets the branch or tag to use. Defaults to the project's default branch when not set. |
+| `ref` | string | No | When `dry_run` is `true`, sets the branch or tag context to use to validate the CI/CD YAML configuration. Defaults to the project's default branch when not set. |
| `sha` | string | No | The commit SHA of a branch or tag. Defaults to the SHA of the head of the project's default branch when not set. |
Example request:
diff --git a/doc/api/projects.md b/doc/api/projects.md
index f909f376fce..516418a387b 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -1794,6 +1794,7 @@ POST /projects/:id/fork
| `namespace` | integer or string | No | _(Deprecated)_ The ID or path of the namespace that the project is forked to. |
| `path` | string | No | The path assigned to the resultant project after forking. |
| `visibility` | string | No | The [visibility level](#project-visibility-level) assigned to the resultant project after forking. |
+| `branches` | string | No | Branches to fork (empty for all branches). |
## List forks of a project
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 1f0b608b67c..d2e297f4213 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -470,6 +470,7 @@ module API
optional :description, type: String, desc: 'The description that will be assigned to the fork', documentation: { example: 'Description' }
optional :visibility, type: String, values: Gitlab::VisibilityLevel.string_values, desc: 'The visibility of the fork'
optional :mr_default_target_self, type: Boolean, desc: 'Merge requests of this forked project targets itself by default'
+ optional :branches, type: String, desc: 'Branches to fork'
end
post ':id/fork', feature_category: :source_code_management do
Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/20759')
@@ -489,6 +490,7 @@ module API
service = ::Projects::ForkService.new(user_project, current_user, fork_params)
+ not_found!('Source Branch') if fork_params[:branches].present? && !service.valid_fork_branch?(fork_params[:branches])
not_found!('Target Namespace') unless service.valid_fork_target?
forked_project = service.execute
diff --git a/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
index 2d04c97b32e..9620a214792 100644
--- a/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
@@ -1,5 +1,5 @@
variables:
- AUTO_BUILD_IMAGE_VERSION: 'v1.44.0'
+ AUTO_BUILD_IMAGE_VERSION: 'v1.46.0'
build:
stage: build
diff --git a/lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml
index 2d04c97b32e..9620a214792 100644
--- a/lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml
@@ -1,5 +1,5 @@
variables:
- AUTO_BUILD_IMAGE_VERSION: 'v1.44.0'
+ AUTO_BUILD_IMAGE_VERSION: 'v1.46.0'
build:
stage: build
diff --git a/lib/gitlab/database/gitlab_schema.rb b/lib/gitlab/database/gitlab_schema.rb
index 31ceb898eee..e885df52dfd 100644
--- a/lib/gitlab/database/gitlab_schema.rb
+++ b/lib/gitlab/database/gitlab_schema.rb
@@ -31,6 +31,7 @@ module Gitlab
'_test_gitlab_main_cell_' => :gitlab_main_cell,
'_test_gitlab_main_' => :gitlab_main,
'_test_gitlab_ci_' => :gitlab_ci,
+ '_test_gitlab_jh_' => :gitlab_jh,
'_test_gitlab_embedding_' => :gitlab_embedding,
'_test_gitlab_geo_' => :gitlab_geo,
'_test_gitlab_pm_' => :gitlab_pm,
diff --git a/lib/gitlab/database/tables_locker.rb b/lib/gitlab/database/tables_locker.rb
index aa880b709fe..608dea9e3c5 100644
--- a/lib/gitlab/database/tables_locker.rb
+++ b/lib/gitlab/database/tables_locker.rb
@@ -3,7 +3,7 @@
module Gitlab
module Database
class TablesLocker
- GITLAB_SCHEMAS_TO_IGNORE = %i[gitlab_embedding gitlab_geo].freeze
+ GITLAB_SCHEMAS_TO_IGNORE = %i[gitlab_embedding gitlab_geo gitlab_jh].freeze
def initialize(logger: nil, dry_run: false, include_partitions: true)
@logger = logger
diff --git a/lib/gitlab/database/tables_truncate.rb b/lib/gitlab/database/tables_truncate.rb
index f91146fff3d..5394dee6fec 100644
--- a/lib/gitlab/database/tables_truncate.rb
+++ b/lib/gitlab/database/tables_truncate.rb
@@ -3,7 +3,7 @@
module Gitlab
module Database
class TablesTruncate
- GITLAB_SCHEMAS_TO_IGNORE = %i[gitlab_geo gitlab_embedding].freeze
+ GITLAB_SCHEMAS_TO_IGNORE = %i[gitlab_geo gitlab_embedding gitlab_jh].freeze
def initialize(database_name:, min_batch_size: 5, logger: nil, until_table: nil, dry_run: false)
@database_name = database_name
diff --git a/lib/gitlab/gitaly_client/repository_service.rb b/lib/gitlab/gitaly_client/repository_service.rb
index d92bf5263f1..457380615f7 100644
--- a/lib/gitlab/gitaly_client/repository_service.rb
+++ b/lib/gitlab/gitaly_client/repository_service.rb
@@ -136,10 +136,13 @@ module Gitlab
response.base.presence
end
- def fork_repository(source_repository)
+ def fork_repository(source_repository, branch = nil)
+ revision = branch.present? ? "refs/heads/#{branch}" : ""
+
request = Gitaly::CreateForkRequest.new(
repository: @gitaly_repo,
- source_repository: source_repository.gitaly_repository
+ source_repository: source_repository.gitaly_repository,
+ revision: revision
)
gitaly_client_call(
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 0f2242baee3..3f68ca49f3c 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -20861,9 +20861,15 @@ msgstr ""
msgid "ForkProject|A fork is a copy of a project."
msgstr ""
+msgid "ForkProject|All branches"
+msgstr ""
+
msgid "ForkProject|An error occurred while forking the project. Please try again."
msgstr ""
+msgid "ForkProject|Branches to include"
+msgstr ""
+
msgid "ForkProject|Cancel"
msgstr ""
@@ -20879,6 +20885,9 @@ msgstr ""
msgid "ForkProject|Internal"
msgstr ""
+msgid "ForkProject|Only the default branch %{defaultBranch}"
+msgstr ""
+
msgid "ForkProject|Please select a namespace"
msgstr ""
@@ -29147,10 +29156,10 @@ msgstr ""
msgid "Maximum number of %{name} (%{count}) exceeded"
msgstr ""
-msgid "Maximum number of changes (branches or tags) in a single push above which a bulk push event is created (default is `3`). Setting to `0` does not disable throttling."
+msgid "Maximum number of changes (branches or tags) in a single push above which a bulk push event is created (default is 3). Setting to 0 does not disable throttling."
msgstr ""
-msgid "Maximum number of changes (branches or tags) in a single push above which webhooks and integrations are not triggered (default is `3`). Setting to `0` does not disable throttling."
+msgid "Maximum number of changes (branches or tags) in a single push above which webhooks and integrations are not triggered (default is 3). Setting to 0 does not disable throttling."
msgstr ""
msgid "Maximum number of comments exceeded"
@@ -29171,7 +29180,7 @@ msgstr ""
msgid "Maximum number of requests per minute for an unauthenticated IP address"
msgstr ""
-msgid "Maximum number of requests per minute for each raw path (default is `300`). Set to `0` to disable throttling."
+msgid "Maximum number of requests per minute for each raw path (default is 300). Set to 0 to disable throttling."
msgstr ""
msgid "Maximum number of stages per value stream exceeded"
@@ -44247,9 +44256,6 @@ msgstr ""
msgid "Set a password on your account to pull or push via %{protocol}."
msgstr ""
-msgid "Set any rate limit to %{code_open}0%{code_close} to disable the limit."
-msgstr ""
-
msgid "Set due date"
msgstr ""
@@ -44355,6 +44361,12 @@ msgstr ""
msgid "Set to 0 for no size limit."
msgstr ""
+msgid "Set to 0 to disable the limit."
+msgstr ""
+
+msgid "Set to 0 to disable the limits."
+msgstr ""
+
msgid "Set to 0 to disable timeout."
msgstr ""
@@ -54394,6 +54406,9 @@ msgstr ""
msgid "WorkItem|This work item is not available. It either doesn't exist or you don't have permission to view it."
msgstr ""
+msgid "WorkItem|Title cannot have more than %{WORK_ITEM_TITLE_MAX_LENGTH} characters."
+msgstr ""
+
msgid "WorkItem|Turn off confidentiality"
msgstr ""
@@ -55922,6 +55937,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "branches"
+msgstr ""
+
msgid "builds"
msgstr ""
diff --git a/rubocop/cop/migration/with_lock_retries_disallowed_method.rb b/rubocop/cop/migration/with_lock_retries_disallowed_method.rb
index 471d98f5416..e019e5bd0cf 100644
--- a/rubocop/cop/migration/with_lock_retries_disallowed_method.rb
+++ b/rubocop/cop/migration/with_lock_retries_disallowed_method.rb
@@ -35,6 +35,8 @@ module RuboCop
swap_foreign_keys
swap_indexes
reset_trigger_function
+ cleanup_conversion_of_integer_to_bigint
+ revert_initialize_conversion_of_integer_to_bigint
].sort.freeze
MSG = "The method is not allowed to be called within the `with_lock_retries` block, the only allowed methods are: #{ALLOWED_MIGRATION_METHODS.join(', ')}".freeze
diff --git a/spec/db/docs_spec.rb b/spec/db/docs_spec.rb
index 8d4cb3ac5ef..500d6881a2d 100644
--- a/spec/db/docs_spec.rb
+++ b/spec/db/docs_spec.rb
@@ -14,6 +14,7 @@ RSpec.shared_examples 'validate dictionary' do |objects, directory_path, require
introduced_by_url
milestone
gitlab_schema
+ schema_inconsistencies
]
end
@@ -169,7 +170,7 @@ RSpec.shared_examples 'validate dictionary' do |objects, directory_path, require
end
RSpec.describe 'Views documentation', feature_category: :database do
- database_base_models = Gitlab::Database.database_base_models.select { |k, _| k != 'geo' }
+ database_base_models = Gitlab::Database.database_base_models.select { |k, _| %w[geo jh].exclude?(k) }
views = database_base_models.flat_map { |_, m| m.connection.views }.sort.uniq
directory_path = File.join('db', 'docs', 'views')
required_fields = %i[feature_categories view_name gitlab_schema]
@@ -178,7 +179,7 @@ RSpec.describe 'Views documentation', feature_category: :database do
end
RSpec.describe 'Tables documentation', feature_category: :database do
- database_base_models = Gitlab::Database.database_base_models.select { |k, _| k != 'geo' }
+ database_base_models = Gitlab::Database.database_base_models.select { |k, _| %w[geo jh].exclude?(k) }
tables = database_base_models.flat_map { |_, m| m.connection.tables }.sort.uniq
directory_path = File.join('db', 'docs')
required_fields = %i[feature_categories table_name gitlab_schema]
diff --git a/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js b/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js
index 7bc4cd4d541..b0bfa4620c6 100644
--- a/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js
+++ b/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js
@@ -1,4 +1,11 @@
-import { GlFormInputGroup, GlFormInput, GlForm, GlFormRadioGroup, GlFormRadio } from '@gitlab/ui';
+import {
+ GlFormInputGroup,
+ GlFormInput,
+ GlForm,
+ GlFormRadioGroup,
+ GlFormRadio,
+ GlSprintf,
+} from '@gitlab/ui';
import { getByRole } from '@testing-library/dom';
import { mount, shallowMount } from '@vue/test-utils';
import axios from 'axios';
@@ -41,6 +48,7 @@ describe('ForkForm component', () => {
projectPath: 'project-name',
projectDescription: 'some project description',
projectVisibility: 'private',
+ projectDefaultBranch: 'main',
restrictedVisibilityLevels: [],
};
@@ -96,6 +104,7 @@ describe('ForkForm component', () => {
GlFormInput,
GlFormRadioGroup,
GlFormRadio,
+ GlSprintf,
},
});
};
@@ -118,13 +127,13 @@ describe('ForkForm component', () => {
const findInternalRadio = () => wrapper.find('[data-testid="radio-internal"]');
const findPublicRadio = () => wrapper.find('[data-testid="radio-public"]');
const findForkNameInput = () => wrapper.find('[data-testid="fork-name-input"]');
- const findGlFormRadioGroup = () => wrapper.findComponent(GlFormRadioGroup);
const findForkUrlInput = () => wrapper.findComponent(ProjectNamespace);
const findForkSlugInput = () => wrapper.find('[data-testid="fork-slug-input"]');
const findForkDescriptionTextarea = () =>
wrapper.find('[data-testid="fork-description-textarea"]');
const findVisibilityRadioGroup = () =>
wrapper.find('[data-testid="fork-visibility-radio-group"]');
+ const findBranchesRadioGroup = () => wrapper.find('[data-testid="fork-branches-radio-group"]');
it('will go to cancelPath when click cancel button', () => {
createComponent();
@@ -203,11 +212,25 @@ describe('ForkForm component', () => {
});
});
+ describe('branches options', () => {
+ const formRadios = () => findBranchesRadioGroup().findAllComponents(GlFormRadio);
+ it('displays 2 branches options', () => {
+ createComponent();
+ expect(formRadios()).toHaveLength(2);
+ });
+
+ it('displays the correct description for each option', () => {
+ createComponent();
+ expect(formRadios().at(0).text()).toBe('All branches');
+ expect(formRadios().at(1).text()).toMatchInterpolatedText('Only the default branch main');
+ });
+ });
+
describe('visibility level', () => {
it('displays the correct description', () => {
createComponent();
- const formRadios = wrapper.findAllComponents(GlFormRadio);
+ const formRadios = findVisibilityRadioGroup().findAllComponents(GlFormRadio);
Object.keys(PROJECT_VISIBILITY_TYPE).forEach((visibilityType, index) => {
expect(formRadios.at(index).text()).toBe(PROJECT_VISIBILITY_TYPE[visibilityType]);
@@ -217,7 +240,7 @@ describe('ForkForm component', () => {
it('displays all 3 visibility levels', () => {
createComponent();
- expect(wrapper.findAllComponents(GlFormRadio)).toHaveLength(3);
+ expect(findVisibilityRadioGroup().findAllComponents(GlFormRadio)).toHaveLength(3);
});
describe('when the namespace is changed', () => {
@@ -236,7 +259,7 @@ describe('ForkForm component', () => {
it('resets the visibility to max allowed below current level', async () => {
createFullComponent({ projectVisibility: 'public' }, { namespaces });
- expect(findGlFormRadioGroup().vm.$attrs.checked).toBe('public');
+ expect(findVisibilityRadioGroup().vm.$attrs.checked).toBe('public');
fillForm({
name: 'one',
@@ -251,7 +274,7 @@ describe('ForkForm component', () => {
it('does not reset the visibility when current level is allowed', async () => {
createFullComponent({ projectVisibility: 'public' }, { namespaces });
- expect(findGlFormRadioGroup().vm.$attrs.checked).toBe('public');
+ expect(findVisibilityRadioGroup().vm.$attrs.checked).toBe('public');
fillForm({
name: 'two',
@@ -266,7 +289,7 @@ describe('ForkForm component', () => {
it('does not reset the visibility when visibility cap is increased', async () => {
createFullComponent({ projectVisibility: 'public' }, { namespaces });
- expect(findGlFormRadioGroup().vm.$attrs.checked).toBe('public');
+ expect(findVisibilityRadioGroup().vm.$attrs.checked).toBe('public');
fillForm({
name: 'three',
@@ -291,7 +314,7 @@ describe('ForkForm component', () => {
{ namespaces },
);
- await findGlFormRadioGroup().vm.$emit('input', 'internal');
+ await findVisibilityRadioGroup().vm.$emit('input', 'internal');
fillForm({
name: 'five',
id: 5,
@@ -469,7 +492,7 @@ describe('ForkForm component', () => {
jest.spyOn(axios, 'post');
setupComponent();
- await findGlFormRadioGroup().vm.$emit('input', null);
+ await findVisibilityRadioGroup().vm.$emit('input', null);
await nextTick();
@@ -533,6 +556,7 @@ describe('ForkForm component', () => {
const url = `/api/${GON_API_VERSION}/projects/${projectId}/fork`;
const project = {
+ branches: '',
description: projectDescription,
id: projectId,
name: projectName,
diff --git a/spec/frontend/work_items/components/work_item_title_spec.js b/spec/frontend/work_items/components/work_item_title_spec.js
index 34391b74cf7..0f466bcf691 100644
--- a/spec/frontend/work_items/components/work_item_title_spec.js
+++ b/spec/frontend/work_items/components/work_item_title_spec.js
@@ -131,5 +131,25 @@ describe('WorkItemTitle component', () => {
property: 'type_Task',
});
});
+
+ describe('when title has more than 255 characters', () => {
+ const title = new Array(257).join('a');
+
+ it('does not call a mutation', () => {
+ createComponent();
+
+ findItemTitle().vm.$emit('title-changed', title);
+
+ expect(mutationSuccessHandler).not.toHaveBeenCalled();
+ });
+
+ it('emits an error message', () => {
+ createComponent();
+
+ findItemTitle().vm.$emit('title-changed', title);
+
+ expect(wrapper.emitted('error')).toEqual([['Title cannot have more than 255 characters.']]);
+ });
+ });
});
});
diff --git a/spec/helpers/admin/components_helper_spec.rb b/spec/helpers/admin/components_helper_spec.rb
index bb590d003ad..b2107f99a34 100644
--- a/spec/helpers/admin/components_helper_spec.rb
+++ b/spec/helpers/admin/components_helper_spec.rb
@@ -11,6 +11,7 @@ RSpec.describe Admin::ComponentsHelper, feature_category: :database do
}
main[:ci] = { adapter_name: 'PostgreSQL', version: expected_version } if Gitlab::Database.has_config?(:ci)
main[:geo] = { adapter_name: 'PostgreSQL', version: expected_version } if Gitlab::Database.has_config?(:geo)
+ main[:jh] = { adapter_name: 'PostgreSQL', version: expected_version } if Gitlab::Database.has_config?(:jh)
main
end
diff --git a/spec/lib/gitlab/diff/file_collection/compare_spec.rb b/spec/lib/gitlab/diff/file_collection/compare_spec.rb
index c3f768db7f0..5469a43e46e 100644
--- a/spec/lib/gitlab/diff/file_collection/compare_spec.rb
+++ b/spec/lib/gitlab/diff/file_collection/compare_spec.rb
@@ -10,9 +10,11 @@ RSpec.describe Gitlab::Diff::FileCollection::Compare do
let(:start_commit) { sample_image_commit }
let(:head_commit) { sample_commit }
let(:raw_compare) do
- Gitlab::Git::Compare.new(project.repository.raw_repository,
- start_commit.id,
- head_commit.id)
+ Gitlab::Git::Compare.new(
+ project.repository.raw_repository,
+ start_commit.id,
+ head_commit.id
+ )
end
let(:diffable) { Compare.new(raw_compare, project) }
diff --git a/spec/lib/gitlab/diff/file_collection/merge_request_diff_batch_spec.rb b/spec/lib/gitlab/diff/file_collection/merge_request_diff_batch_spec.rb
index 8e14f48ae29..65e96f8e936 100644
--- a/spec/lib/gitlab/diff/file_collection/merge_request_diff_batch_spec.rb
+++ b/spec/lib/gitlab/diff/file_collection/merge_request_diff_batch_spec.rb
@@ -10,10 +10,7 @@ RSpec.describe Gitlab::Diff::FileCollection::MergeRequestDiffBatch, feature_cate
let(:diff_files_relation) { diffable.merge_request_diff_files }
subject do
- described_class.new(diffable,
- batch_page,
- batch_size,
- diff_options: nil)
+ described_class.new(diffable, batch_page, batch_size, diff_options: nil)
end
let(:diff_files) { subject.diff_files }
@@ -87,10 +84,7 @@ RSpec.describe Gitlab::Diff::FileCollection::MergeRequestDiffBatch, feature_cate
context 'last page' do
it 'returns correct diff files' do
last_page = diff_files_relation.count - batch_size
- collection = described_class.new(diffable,
- last_page,
- batch_size,
- diff_options: nil)
+ collection = described_class.new(diffable, last_page, batch_size, diff_options: nil)
expected_batch_files = diff_files_relation.offset(last_page).limit(batch_size).map(&:new_path)
@@ -101,10 +95,7 @@ RSpec.describe Gitlab::Diff::FileCollection::MergeRequestDiffBatch, feature_cate
it_behaves_like 'unfoldable diff' do
subject do
- described_class.new(merge_request.merge_request_diff,
- batch_page,
- batch_size,
- diff_options: nil)
+ described_class.new(merge_request.merge_request_diff, batch_page, batch_size, diff_options: nil)
end
end
@@ -118,10 +109,7 @@ RSpec.describe Gitlab::Diff::FileCollection::MergeRequestDiffBatch, feature_cate
let(:stub_path) { '.gitignore' }
subject do
- described_class.new(merge_request.merge_request_diff,
- batch_page,
- batch_size,
- **collection_default_args)
+ described_class.new(merge_request.merge_request_diff, batch_page, batch_size, **collection_default_args)
end
end
@@ -136,10 +124,7 @@ RSpec.describe Gitlab::Diff::FileCollection::MergeRequestDiffBatch, feature_cate
end
subject do
- described_class.new(merge_request.merge_request_diff,
- batch_page,
- batch_size,
- **collection_default_args)
+ described_class.new(merge_request.merge_request_diff, batch_page, batch_size, **collection_default_args)
end
end
end
diff --git a/spec/lib/gitlab/diff/file_collection/paginated_merge_request_diff_spec.rb b/spec/lib/gitlab/diff/file_collection/paginated_merge_request_diff_spec.rb
index ee956d04325..891336658ce 100644
--- a/spec/lib/gitlab/diff/file_collection/paginated_merge_request_diff_spec.rb
+++ b/spec/lib/gitlab/diff/file_collection/paginated_merge_request_diff_spec.rb
@@ -11,9 +11,7 @@ RSpec.describe Gitlab::Diff::FileCollection::PaginatedMergeRequestDiff, feature_
let(:diff_files) { subject.diff_files }
subject do
- described_class.new(diffable,
- page,
- per_page)
+ described_class.new(diffable, page, per_page)
end
describe '#diff_files' do
@@ -79,9 +77,7 @@ RSpec.describe Gitlab::Diff::FileCollection::PaginatedMergeRequestDiff, feature_
context 'when last page' do
it 'returns correct diff files' do
last_page = diff_files_relation.count - per_page
- collection = described_class.new(diffable,
- last_page,
- per_page)
+ collection = described_class.new(diffable, last_page, per_page)
expected_batch_files = diff_files_relation.page(last_page).per(per_page).map(&:new_path)
@@ -92,9 +88,7 @@ RSpec.describe Gitlab::Diff::FileCollection::PaginatedMergeRequestDiff, feature_
it_behaves_like 'unfoldable diff' do
subject do
- described_class.new(merge_request.merge_request_diff,
- page,
- per_page)
+ described_class.new(merge_request.merge_request_diff, page, per_page)
end
end
@@ -106,9 +100,7 @@ RSpec.describe Gitlab::Diff::FileCollection::PaginatedMergeRequestDiff, feature_
let(:diffable) { merge_request.merge_request_diff }
subject do
- described_class.new(merge_request.merge_request_diff,
- page,
- per_page)
+ described_class.new(merge_request.merge_request_diff, page, per_page)
end
end
end
diff --git a/spec/lib/gitlab/diff/file_spec.rb b/spec/lib/gitlab/diff/file_spec.rb
index ad2524e40c5..bc4fc49b1b7 100644
--- a/spec/lib/gitlab/diff/file_spec.rb
+++ b/spec/lib/gitlab/diff/file_spec.rb
@@ -407,10 +407,7 @@ RSpec.describe Gitlab::Diff::File do
context 'diff file stats' do
let(:diff_file) do
- described_class.new(diff,
- diff_refs: commit.diff_refs,
- repository: project.repository,
- stats: stats)
+ described_class.new(diff, diff_refs: commit.diff_refs, repository: project.repository, stats: stats)
end
let(:raw_diff) do
diff --git a/spec/lib/gitlab/diff/highlight_cache_spec.rb b/spec/lib/gitlab/diff/highlight_cache_spec.rb
index c51eaa4fa18..94a5d30283c 100644
--- a/spec/lib/gitlab/diff/highlight_cache_spec.rb
+++ b/spec/lib/gitlab/diff/highlight_cache_spec.rb
@@ -49,10 +49,12 @@ RSpec.describe Gitlab::Diff::HighlightCache, :clean_gitlab_redis_cache, feature_
let(:diff_file) do
diffs = merge_request.diffs
raw_diff = diffs.diffable.raw_diffs(diffs.diff_options.merge(paths: ['CHANGELOG'])).first
- Gitlab::Diff::File.new(raw_diff,
- repository: diffs.project.repository,
- diff_refs: diffs.diff_refs,
- fallback_diff_refs: diffs.fallback_diff_refs)
+ Gitlab::Diff::File.new(
+ raw_diff,
+ repository: diffs.project.repository,
+ diff_refs: diffs.diff_refs,
+ fallback_diff_refs: diffs.fallback_diff_refs
+ )
end
before do
@@ -227,10 +229,12 @@ RSpec.describe Gitlab::Diff::HighlightCache, :clean_gitlab_redis_cache, feature_
let(:diff_file) do
diffs = merge_request.diffs
raw_diff = diffs.diffable.raw_diffs(diffs.diff_options.merge(paths: ['CHANGELOG'])).first
- Gitlab::Diff::File.new(raw_diff,
- repository: diffs.project.repository,
- diff_refs: diffs.diff_refs,
- fallback_diff_refs: diffs.fallback_diff_refs)
+ Gitlab::Diff::File.new(
+ raw_diff,
+ repository: diffs.project.repository,
+ diff_refs: diffs.diff_refs,
+ fallback_diff_refs: diffs.fallback_diff_refs
+ )
end
it "uses ActiveSupport::Gzip when reading from the cache" do
diff --git a/spec/lib/gitlab/diff/line_spec.rb b/spec/lib/gitlab/diff/line_spec.rb
index 949def599ae..b23ba3a0f00 100644
--- a/spec/lib/gitlab/diff/line_spec.rb
+++ b/spec/lib/gitlab/diff/line_spec.rb
@@ -11,10 +11,16 @@ RSpec.describe Gitlab::Diff::Line do
end
let(:line) do
- described_class.new('<input>', 'match', 0, 0, 1,
- parent_file: double(:file),
- line_code: double(:line_code),
- rich_text: rich_text)
+ described_class.new(
+ '<input>',
+ 'match',
+ 0,
+ 0,
+ 1,
+ parent_file: double(:file),
+ line_code: double(:line_code),
+ rich_text: rich_text
+ )
end
let(:rich_text) { nil }
diff --git a/spec/lib/gitlab/diff/suggestion_diff_spec.rb b/spec/lib/gitlab/diff/suggestion_diff_spec.rb
index 9546c581112..f9d56662753 100644
--- a/spec/lib/gitlab/diff/suggestion_diff_spec.rb
+++ b/spec/lib/gitlab/diff/suggestion_diff_spec.rb
@@ -22,9 +22,7 @@ RSpec.describe Gitlab::Diff::SuggestionDiff do
end
let(:suggestion) do
- instance_double(Suggestion, from_line: 12,
- from_content: from_content,
- to_content: to_content)
+ instance_double(Suggestion, from_line: 12, from_content: from_content, to_content: to_content)
end
subject { described_class.new(suggestion).diff_lines }
@@ -56,9 +54,12 @@ RSpec.describe Gitlab::Diff::SuggestionDiff do
it 'returns a correct value if there is no newline at the end of the file' do
from_content = "One line test"
to_content = "Successful test!"
- suggestion = instance_double(Suggestion, from_line: 1,
- from_content: from_content,
- to_content: to_content)
+ suggestion = instance_double(
+ Suggestion,
+ from_line: 1,
+ from_content: from_content,
+ to_content: to_content
+ )
diff_lines = described_class.new(suggestion).diff_lines
diff --git a/spec/lib/gitlab/diff/suggestion_spec.rb b/spec/lib/gitlab/diff/suggestion_spec.rb
index 40779faf917..9f654c44852 100644
--- a/spec/lib/gitlab/diff/suggestion_spec.rb
+++ b/spec/lib/gitlab/diff/suggestion_spec.rb
@@ -5,10 +5,12 @@ require 'spec_helper'
RSpec.describe Gitlab::Diff::Suggestion do
shared_examples 'correct suggestion raw content' do
it 'returns correct raw data' do
- expect(suggestion.to_hash).to include(from_content: expected_lines.join,
- to_content: "#{text}\n",
- lines_above: above,
- lines_below: below)
+ expect(suggestion.to_hash).to include(
+ from_content: expected_lines.join,
+ to_content: "#{text}\n",
+ lines_above: above,
+ lines_below: below
+ )
end
it 'returns diff lines with correct line numbers' do
@@ -25,11 +27,13 @@ RSpec.describe Gitlab::Diff::Suggestion do
let(:merge_request) { create(:merge_request) }
let(:project) { merge_request.project }
let(:position) do
- Gitlab::Diff::Position.new(old_path: "files/ruby/popen.rb",
- new_path: "files/ruby/popen.rb",
- old_line: nil,
- new_line: 9,
- diff_refs: merge_request.diff_refs)
+ Gitlab::Diff::Position.new(
+ old_path: "files/ruby/popen.rb",
+ new_path: "files/ruby/popen.rb",
+ old_line: nil,
+ new_line: 9,
+ diff_refs: merge_request.diff_refs
+ )
end
let(:diff_file) do
diff --git a/spec/lib/gitlab/diff/suggestions_parser_spec.rb b/spec/lib/gitlab/diff/suggestions_parser_spec.rb
index a00c55d4fb2..ef845dbdc4c 100644
--- a/spec/lib/gitlab/diff/suggestions_parser_spec.rb
+++ b/spec/lib/gitlab/diff/suggestions_parser_spec.rb
@@ -7,11 +7,13 @@ RSpec.describe Gitlab::Diff::SuggestionsParser do
let(:merge_request) { create(:merge_request) }
let(:project) { merge_request.project }
let(:position) do
- Gitlab::Diff::Position.new(old_path: "files/ruby/popen.rb",
- new_path: "files/ruby/popen.rb",
- old_line: nil,
- new_line: 9,
- diff_refs: merge_request.diff_refs)
+ Gitlab::Diff::Position.new(
+ old_path: "files/ruby/popen.rb",
+ new_path: "files/ruby/popen.rb",
+ old_line: nil,
+ new_line: 9,
+ diff_refs: merge_request.diff_refs
+ )
end
let(:diff_file) do
@@ -19,8 +21,7 @@ RSpec.describe Gitlab::Diff::SuggestionsParser do
end
subject do
- described_class.parse(markdown, project: merge_request.project,
- position: position)
+ described_class.parse(markdown, project: merge_request.project, position: position)
end
def blob_lines_data(from_line, to_line)
@@ -59,15 +60,19 @@ RSpec.describe Gitlab::Diff::SuggestionsParser do
from_line = position.new_line
to_line = position.new_line
- expect(subject.first.to_hash).to include(from_content: blob_lines_data(from_line, to_line),
- to_content: " foo\n bar\n",
- lines_above: 0,
- lines_below: 0)
-
- expect(subject.second.to_hash).to include(from_content: blob_lines_data(from_line, to_line),
- to_content: " xpto\n baz\n",
- lines_above: 0,
- lines_below: 0)
+ expect(subject.first.to_hash).to include(
+ from_content: blob_lines_data(from_line, to_line),
+ to_content: " foo\n bar\n",
+ lines_above: 0,
+ lines_below: 0
+ )
+
+ expect(subject.second.to_hash).to include(
+ from_content: blob_lines_data(from_line, to_line),
+ to_content: " xpto\n baz\n",
+ lines_above: 0,
+ lines_below: 0
+ )
end
end
@@ -105,30 +110,36 @@ RSpec.describe Gitlab::Diff::SuggestionsParser do
from_line = position.new_line - 2
to_line = position.new_line + 1
- expect(subject.first.to_hash).to include(from_content: blob_lines_data(from_line, to_line),
- to_content: " # above and below\n",
- lines_above: 2,
- lines_below: 1)
+ expect(subject.first.to_hash).to include(
+ from_content: blob_lines_data(from_line, to_line),
+ to_content: " # above and below\n",
+ lines_above: 2,
+ lines_below: 1
+ )
end
it 'suggestion with above param has correct data' do
from_line = position.new_line - 3
to_line = position.new_line
- expect(subject.second.to_hash).to eq(from_content: blob_lines_data(from_line, to_line),
- to_content: " # only above\n",
- lines_above: 3,
- lines_below: 0)
+ expect(subject.second.to_hash).to eq(
+ from_content: blob_lines_data(from_line, to_line),
+ to_content: " # only above\n",
+ lines_above: 3,
+ lines_below: 0
+ )
end
it 'suggestion with below param has correct data' do
from_line = position.new_line
to_line = position.new_line + 3
- expect(subject.third.to_hash).to eq(from_content: blob_lines_data(from_line, to_line),
- to_content: " # only below\n",
- lines_above: 0,
- lines_below: 3)
+ expect(subject.third.to_hash).to eq(
+ from_content: blob_lines_data(from_line, to_line),
+ to_content: " # only below\n",
+ lines_above: 0,
+ lines_below: 3
+ )
end
end
end
diff --git a/spec/lib/gitlab/gitaly_client/repository_service_spec.rb b/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
index 283a9cb45dc..727bf494ee6 100644
--- a/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
@@ -140,6 +140,44 @@ RSpec.describe Gitlab::GitalyClient::RepositoryService, feature_category: :gital
end
end
+ describe '#fork_repository' do
+ let(:source_repository) { Gitlab::Git::Repository.new('default', 'repo/path', '', 'group/project') }
+
+ context 'when branch is not provided' do
+ it 'sends a create_fork message' do
+ expected_request = gitaly_request_with_params(
+ source_repository: source_repository.gitaly_repository,
+ revision: ""
+ )
+
+ expect_any_instance_of(Gitaly::RepositoryService::Stub)
+ .to receive(:create_fork)
+ .with(expected_request, kind_of(Hash))
+ .and_return(double(value: true))
+
+ client.fork_repository(source_repository)
+ end
+ end
+
+ context 'when branch is provided' do
+ it 'sends a create_fork message including revision' do
+ branch = 'wip'
+
+ expected_request = gitaly_request_with_params(
+ source_repository: source_repository.gitaly_repository,
+ revision: "refs/heads/#{branch}"
+ )
+
+ expect_any_instance_of(Gitaly::RepositoryService::Stub)
+ .to receive(:create_fork)
+ .with(expected_request, kind_of(Hash))
+ .and_return(double(value: true))
+
+ client.fork_repository(source_repository, branch)
+ end
+ end
+ end
+
describe '#import_repository' do
let(:source) { 'https://example.com/git/repo.git' }
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 6598cafeba0..04d0226ac22 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -6023,12 +6023,10 @@ RSpec.describe MergeRequest, factory_default: :keep, feature_category: :code_rev
allow(merge_request_diff).to receive(:patch_id_sha).and_return(nil)
allow(merge_request).to receive(:diff_refs).and_return(diff_refs)
- allow_next_instance_of(Repository) do |repo|
- allow(repo)
- .to receive(:get_patch_id)
- .with(diff_refs.base_sha, diff_refs.head_sha)
- .and_return(patch_id)
- end
+ allow(merge_request.project.repository)
+ .to receive(:get_patch_id)
+ .with(diff_refs.base_sha, diff_refs.head_sha)
+ .and_return(patch_id)
end
it { is_expected.to eq(patch_id) }
diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb
index 4d55f310974..ceb060445ad 100644
--- a/spec/services/projects/fork_service_spec.rb
+++ b/spec/services/projects/fork_service_spec.rb
@@ -510,6 +510,26 @@ RSpec.describe Projects::ForkService, feature_category: :source_code_management
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) }
+
+ context 'when branch exists' do
+ let(:branch) { project.default_branch_or_main }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when branch does not exist' do
+ let(:branch) { 'branch-that-does-not-exist' }
+
+ it { is_expected.to be_falsey }
+ end
+ end
+
describe '#valid_fork_target?' do
let(:project) { Project.new }
let(:params) { {} }
diff --git a/spec/support/shared_examples/database_health_status_indicators/prometheus_alert_based_shared_examples.rb b/spec/support/shared_examples/database_health_status_indicators/prometheus_alert_based_shared_examples.rb
index 109a349a652..ddc438cb652 100644
--- a/spec/support/shared_examples/database_health_status_indicators/prometheus_alert_based_shared_examples.rb
+++ b/spec/support/shared_examples/database_health_status_indicators/prometheus_alert_based_shared_examples.rb
@@ -2,7 +2,7 @@
RSpec.shared_examples 'Prometheus Alert based health indicator' do
let(:schema) { :main }
- let(:connection) { Gitlab::Database.database_base_models[schema].connection }
+ let(:connection) { Gitlab::Database.database_base_models_with_gitlab_shared[schema].connection }
around do |example|
Gitlab::Database::SharedModel.using_connection(connection) do
@@ -124,7 +124,7 @@ RSpec.shared_examples 'Prometheus Alert based health indicator' do
end
end
- Gitlab::Database.database_base_models.each do |database_base_model, connection|
+ Gitlab::Database.database_base_models_with_gitlab_shared.each do |database_base_model, connection|
next unless connection.present?
it_behaves_like 'Patroni Apdex Evaluator', database_base_model.to_sym
diff --git a/spec/tasks/gitlab/background_migrations_rake_spec.rb b/spec/tasks/gitlab/background_migrations_rake_spec.rb
index ba5618e2700..5c61f0eff38 100644
--- a/spec/tasks/gitlab/background_migrations_rake_spec.rb
+++ b/spec/tasks/gitlab/background_migrations_rake_spec.rb
@@ -149,6 +149,7 @@ RSpec.describe 'gitlab:background_migrations namespace rake tasks', :suppress_gi
context 'with two connections sharing the same database' do
before do
skip_if_database_exists(:ci)
+ skip_if_database_exists(:jh)
end
it 'skips the shared database' do
diff --git a/spec/tasks/gitlab/db_rake_spec.rb b/spec/tasks/gitlab/db_rake_spec.rb
index 7dd8adae04d..ba266168627 100644
--- a/spec/tasks/gitlab/db_rake_spec.rb
+++ b/spec/tasks/gitlab/db_rake_spec.rb
@@ -579,6 +579,10 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout, feature_categor
allow(File).to receive(:open).with(Rails.root.join('ee/db/geo/structure.sql').to_s, any_args).and_yield(output)
allow(File).to receive(:open).with(Rails.root.join('ee/db/embedding/structure.sql').to_s, any_args).and_yield(output)
end
+
+ if Gitlab.jh?
+ allow(File).to receive(:open).with(Rails.root.join('jh/db/structure.sql').to_s, any_args).and_yield(output)
+ end
end
after do
diff --git a/spec/workers/repository_fork_worker_spec.rb b/spec/workers/repository_fork_worker_spec.rb
index 3a5528b6a04..bd452c21d9a 100644
--- a/spec/workers/repository_fork_worker_spec.rb
+++ b/spec/workers/repository_fork_worker_spec.rb
@@ -19,11 +19,11 @@ RSpec.describe RepositoryForkWorker, feature_category: :source_code_management d
fork_project(project, forked_project.creator, target_project: forked_project, repository: true)
end
- shared_examples 'RepositoryForkWorker performing' do
- def expect_fork_repository(success:)
+ shared_examples 'RepositoryForkWorker performing' do |branch|
+ def expect_fork_repository(success:, branch:)
allow(::Gitlab::GitalyClient::RepositoryService).to receive(:new).and_call_original
expect_next_instance_of(::Gitlab::GitalyClient::RepositoryService, forked_project.repository.raw) do |svc|
- exp = expect(svc).to receive(:fork_repository).with(project.repository.raw)
+ exp = expect(svc).to receive(:fork_repository).with(project.repository.raw, branch)
if success
exp.and_return(true)
@@ -39,20 +39,20 @@ RSpec.describe RepositoryForkWorker, feature_category: :source_code_management d
it 'creates a new repository from a fork' do
allow(subject).to receive(:jid).and_return(jid)
- expect_fork_repository(success: true)
+ expect_fork_repository(success: true, branch: branch)
perform!
end
end
it "creates a new repository from a fork" do
- expect_fork_repository(success: true)
+ expect_fork_repository(success: true, branch: branch)
perform!
end
it 'protects the default branch' do
- expect_fork_repository(success: true)
+ expect_fork_repository(success: true, branch: branch)
perform!
@@ -60,7 +60,7 @@ RSpec.describe RepositoryForkWorker, feature_category: :source_code_management d
end
it 'flushes various caches' do
- expect_fork_repository(success: true)
+ expect_fork_repository(success: true, branch: branch)
# Works around https://github.com/rspec/rspec-mocks/issues/910
expect(Project).to receive(:find).with(forked_project.id).and_return(forked_project)
@@ -79,13 +79,13 @@ RSpec.describe RepositoryForkWorker, feature_category: :source_code_management d
it 'handles bad fork' do
error_message = "Unable to fork project #{forked_project.id} for repository #{project.disk_path} -> #{forked_project.disk_path}: Failed to create fork repository"
- expect_fork_repository(success: false)
+ expect_fork_repository(success: false, branch: branch)
expect { perform! }.to raise_error(StandardError, error_message)
end
it 'calls Projects::LfsPointers::LfsLinkService#execute with OIDs of source project LFS objects' do
- expect_fork_repository(success: true)
+ expect_fork_repository(success: true, branch: branch)
expect_next_instance_of(Projects::LfsPointers::LfsLinkService) do |service|
expect(service).to receive(:execute).with(project.lfs_objects_oids)
end
@@ -96,7 +96,7 @@ RSpec.describe RepositoryForkWorker, feature_category: :source_code_management d
it "handles LFS objects link failure" do
error_message = "Unable to fork project #{forked_project.id} for repository #{project.disk_path} -> #{forked_project.disk_path}: Source project has too many LFS objects"
- expect_fork_repository(success: true)
+ expect_fork_repository(success: true, branch: branch)
expect_next_instance_of(Projects::LfsPointers::LfsLinkService) do |service|
expect(service).to receive(:execute).and_raise(Projects::LfsPointers::LfsLinkService::TooManyOidsError)
end
@@ -113,6 +113,16 @@ RSpec.describe RepositoryForkWorker, feature_category: :source_code_management d
it_behaves_like 'RepositoryForkWorker performing'
end
+ context 'when a specific branch is requested' do
+ def perform!
+ forked_project.create_import_data(data: { fork_branch: 'wip' })
+
+ subject.perform(forked_project.id)
+ end
+
+ it_behaves_like 'RepositoryForkWorker performing', 'wip'
+ end
+
context 'project ID, storage and repo paths passed' do
def perform!
subject.perform(forked_project.id, 'repos/path', project.disk_path)