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-06-08 15:08:54 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-06-08 15:08:54 +0300
commit473b876fe3d7e0b36eb6268cc44a4fe0d94f4422 (patch)
tree2f6d5f2ecad53015024b6b1509896f5933c5c3e6
parentdca8df0c90d8727d69b3501b15b481546897f3cd (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/ci/database.gitlab-ci.yml1
-rw-r--r--.rubocop_todo/rspec/factory_bot/avoid_create.yml11
-rw-r--r--CHANGELOG.md6
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--app/assets/javascripts/super_sidebar/components/context_switcher_toggle.vue2
-rw-r--r--app/helpers/admin/application_settings/settings_helper.rb49
-rw-r--r--app/helpers/application_settings_helper.rb2
-rw-r--r--app/models/application_setting.rb5
-rw-r--r--app/models/application_setting_implementation.rb2
-rw-r--r--app/models/concerns/application_setting_masked_attrs.rb14
-rw-r--r--app/services/auto_merge/merge_when_pipeline_succeeds_service.rb9
-rw-r--r--app/services/merge_requests/mergeability/logger.rb10
-rw-r--r--app/views/admin/application_settings/_ai_access.html.haml32
-rw-r--r--app/views/admin/application_settings/general.html.haml1
-rw-r--r--config/locales/en.yml2
-rw-r--r--config/open_api.yml2
-rw-r--r--db/post_migrate/20230517005523_ensure_backfill_bigint_id_is_completed.rb23
-rw-r--r--db/post_migrate/20230518005523_add_concurrent_index_for_ci_pipeline_variables_bigint_id.rb18
-rw-r--r--db/schema_migrations/202305170055231
-rw-r--r--db/schema_migrations/202305180055231
-rw-r--r--db/structure.sql2
-rw-r--r--doc/administration/auth/atlassian.md12
-rw-r--r--doc/administration/auth/cognito.md6
-rw-r--r--doc/administration/auth/crowd.md68
-rw-r--r--doc/administration/auth/jwt.md14
-rw-r--r--doc/administration/auth/ldap/google_secure_ldap.md6
-rw-r--r--doc/administration/auth/ldap/index.md4
-rw-r--r--doc/administration/auth/oidc.md40
-rw-r--r--doc/administration/auth/smartcard.md18
-rw-r--r--doc/administration/clusters/kas.md12
-rw-r--r--doc/administration/operations/puma.md65
-rw-r--r--doc/administration/package_information/postgresql_versions.md1
-rw-r--r--doc/user/profile/account/delete_account.md2
-rw-r--r--lib/api/api.rb1
-rw-r--r--lib/api/ml_model_packages.rb111
-rw-r--r--lib/gitlab/regex.rb12
-rw-r--r--locale/gitlab.pot24
-rwxr-xr-xscripts/review_apps/review-apps.sh4
-rw-r--r--spec/helpers/admin/application_settings/settings_helper_spec.rb14
-rw-r--r--spec/lib/sidebars/admin/menus/abuse_reports_menu_spec.rb2
-rw-r--r--spec/lib/sidebars/admin/menus/monitoring_menu_spec.rb2
-rw-r--r--spec/lib/sidebars/concerns/container_with_html_options_spec.rb2
-rw-r--r--spec/lib/sidebars/concerns/link_with_html_options_spec.rb2
-rw-r--r--spec/lib/sidebars/groups/menus/ci_cd_menu_spec.rb2
-rw-r--r--spec/lib/sidebars/groups/menus/observability_menu_spec.rb6
-rw-r--r--spec/lib/sidebars/groups/menus/settings_menu_spec.rb2
-rw-r--r--spec/lib/sidebars/menu_item_spec.rb2
-rw-r--r--spec/lib/sidebars/projects/context_spec.rb2
-rw-r--r--spec/lib/sidebars/projects/menus/analytics_menu_spec.rb2
-rw-r--r--spec/lib/sidebars/projects/menus/ci_cd_menu_spec.rb2
-rw-r--r--spec/lib/sidebars/projects/menus/confluence_menu_spec.rb2
-rw-r--r--spec/lib/sidebars/projects/menus/external_issue_tracker_menu_spec.rb2
-rw-r--r--spec/lib/sidebars/projects/menus/hidden_menu_spec.rb2
-rw-r--r--spec/lib/sidebars/projects/menus/issues_menu_spec.rb2
-rw-r--r--spec/lib/sidebars/projects/menus/monitor_menu_spec.rb2
-rw-r--r--spec/lib/sidebars/projects/menus/settings_menu_spec.rb4
-rw-r--r--spec/lib/sidebars/projects/menus/zentao_menu_spec.rb2
-rw-r--r--spec/lib/sidebars/projects/super_sidebar_panel_spec.rb2
-rw-r--r--spec/lib/sidebars/search/panel_spec.rb4
-rw-r--r--spec/lib/sidebars/user_profile/panel_spec.rb4
-rw-r--r--spec/lib/sidebars/user_settings/panel_spec.rb2
-rw-r--r--spec/lib/sidebars/your_work/menus/issues_menu_spec.rb2
-rw-r--r--spec/lib/sidebars/your_work/menus/merge_requests_menu_spec.rb2
-rw-r--r--spec/lib/sidebars/your_work/menus/todos_menu_spec.rb2
-rw-r--r--spec/lib/sidebars/your_work/panel_spec.rb2
-rw-r--r--spec/models/application_setting_spec.rb25
-rw-r--r--spec/requests/api/ml_model_packages_spec.rb200
-rw-r--r--spec/services/merge_requests/mergeability/logger_spec.rb31
-rw-r--r--spec/support/shared_examples/requests/api/ml_model_packages_shared_examples.rb108
-rw-r--r--spec/views/admin/application_settings/_ai_access.html.haml_spec.rb38
-rw-r--r--spec/views/admin/application_settings/general.html.haml_spec.rb26
-rw-r--r--workhorse/internal/upstream/routes.go3
-rw-r--r--workhorse/upload_test.go1
73 files changed, 962 insertions, 141 deletions
diff --git a/.gitlab/ci/database.gitlab-ci.yml b/.gitlab/ci/database.gitlab-ci.yml
index 45aa6a35d6c..37befd78bb5 100644
--- a/.gitlab/ci/database.gitlab-ci.yml
+++ b/.gitlab/ci/database.gitlab-ci.yml
@@ -72,6 +72,7 @@ db:check-schema-single-db:
db:check-migrations:
extends:
- .db-job-base
+ - .use-pg13 # Should match the db same version used by GDK
- .rails:rules:ee-and-foss-mr-with-migration
script:
- git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:$CI_MERGE_REQUEST_TARGET_BRANCH_NAME --depth 20
diff --git a/.rubocop_todo/rspec/factory_bot/avoid_create.yml b/.rubocop_todo/rspec/factory_bot/avoid_create.yml
index a6037c5093e..dc68e204685 100644
--- a/.rubocop_todo/rspec/factory_bot/avoid_create.yml
+++ b/.rubocop_todo/rspec/factory_bot/avoid_create.yml
@@ -336,13 +336,11 @@ RSpec/FactoryBot/AvoidCreate:
- 'spec/helpers/wiki_helper_spec.rb'
- 'spec/helpers/wiki_page_version_helper_spec.rb'
- 'spec/lib/sidebars/admin/menus/abuse_reports_menu_spec.rb'
- - 'spec/lib/sidebars/admin/menus/monitoring_menu_spec.rb'
- 'spec/lib/sidebars/groups/menus/ci_cd_menu_spec.rb'
- 'spec/lib/sidebars/groups/menus/group_information_menu_spec.rb'
- 'spec/lib/sidebars/groups/menus/issues_menu_spec.rb'
- 'spec/lib/sidebars/groups/menus/kubernetes_menu_spec.rb'
- 'spec/lib/sidebars/groups/menus/merge_requests_menu_spec.rb'
- - 'spec/lib/sidebars/groups/menus/observability_menu_spec.rb'
- 'spec/lib/sidebars/groups/menus/packages_registries_menu_spec.rb'
- 'spec/lib/sidebars/groups/menus/settings_menu_spec.rb'
- 'spec/lib/sidebars/groups/super_sidebar_panel_spec.rb'
@@ -358,17 +356,8 @@ RSpec/FactoryBot/AvoidCreate:
- 'spec/lib/sidebars/projects/menus/project_information_menu_spec.rb'
- 'spec/lib/sidebars/projects/menus/repository_menu_spec.rb'
- 'spec/lib/sidebars/projects/menus/security_compliance_menu_spec.rb'
- - 'spec/lib/sidebars/projects/menus/settings_menu_spec.rb'
- 'spec/lib/sidebars/projects/menus/shimo_menu_spec.rb'
- 'spec/lib/sidebars/projects/panel_spec.rb'
- - 'spec/lib/sidebars/projects/super_sidebar_panel_spec.rb'
- - 'spec/lib/sidebars/search/panel_spec.rb'
- - 'spec/lib/sidebars/user_profile/panel_spec.rb'
- - 'spec/lib/sidebars/user_settings/panel_spec.rb'
- - 'spec/lib/sidebars/your_work/menus/issues_menu_spec.rb'
- - 'spec/lib/sidebars/your_work/menus/merge_requests_menu_spec.rb'
- - 'spec/lib/sidebars/your_work/menus/todos_menu_spec.rb'
- - 'spec/lib/sidebars/your_work/panel_spec.rb'
- 'spec/mailers/abuse_report_mailer_spec.rb'
- 'spec/mailers/devise_mailer_spec.rb'
- 'spec/mailers/emails/auto_devops_spec.rb'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5312e970f39..f6a441270ca 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,12 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
+## 16.0.4 (2023-06-08)
+
+### Fixed (1 change)
+
+- [Fix LDAP tls_options not working](gitlab-org/gitlab@e6038d0d4e8bb190ccfeca5fe7204d6a6af266e5) ([merge request](gitlab-org/gitlab!122797))
+
## 16.0.3 (2023-06-06)
### Fixed (3 changes)
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 7b9a37398c1..8df471bc6d2 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-1934b9991139b48ed58d78dc89b35c262acd5150
+468ba7de9380a1eb6321dbdf9b7ddffd7eda90f7
diff --git a/app/assets/javascripts/super_sidebar/components/context_switcher_toggle.vue b/app/assets/javascripts/super_sidebar/components/context_switcher_toggle.vue
index cfb7e7732e9..17227a2b123 100644
--- a/app/assets/javascripts/super_sidebar/components/context_switcher_toggle.vue
+++ b/app/assets/javascripts/super_sidebar/components/context_switcher_toggle.vue
@@ -34,7 +34,7 @@ export default {
<template>
<button
type="button"
- class="context-switcher-toggle gl-p-0 gl-bg-transparent gl-hover-bg-t-gray-a-08 gl-focus-bg-t-gray-a-08 gl-border-0 border-top border-bottom gl-border-gray-a-08 gl-box-shadow-none gl-display-flex gl-align-items-center gl-font-weight-bold gl-w-full gl-h-8 gl-flex-shrink-0"
+ class="context-switcher-toggle gl-p-0 gl-bg-transparent gl-hover-bg-t-gray-a-08 gl-focus-bg-t-gray-a-08 gl-border-0 border-top border-bottom gl-border-gray-a-08! gl-box-shadow-none gl-display-flex gl-align-items-center gl-font-weight-bold gl-w-full gl-h-8 gl-flex-shrink-0"
data-qa-selector="context_switcher"
>
<span
diff --git a/app/helpers/admin/application_settings/settings_helper.rb b/app/helpers/admin/application_settings/settings_helper.rb
index 1741d6a953a..0a7f20caa02 100644
--- a/app/helpers/admin/application_settings/settings_helper.rb
+++ b/app/helpers/admin/application_settings/settings_helper.rb
@@ -15,6 +15,55 @@ module Admin
def project_missing_pipeline_yaml?(project)
project.repository&.gitlab_ci_yml.blank?
end
+
+ def code_suggestions_token_explanation
+ link_start = code_suggestions_link_start(code_suggestions_pat_docs_url)
+
+ # rubocop:disable Layout/LineLength
+ # rubocop:disable Style/FormatString
+ s_('CodeSuggestionsSM|Your personal access token from GitLab.com. See the %{link_start}documentation%{link_end} for information on creating a personal access token.')
+ .html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
+ # rubocop:enable Style/FormatString
+ # rubocop:enable Layout/LineLength
+ end
+
+ def code_suggestions_agreement
+ terms_link_start = code_suggestions_link_start(code_suggestions_agreement_url)
+ ai_docs_link_start = code_suggestions_link_start(code_suggestions_ai_docs_url)
+
+ # rubocop:disable Layout/LineLength
+ # rubocop:disable Style/FormatString
+ s_('CodeSuggestionsSM|&#8226; Agree to the %{terms_link_start}GitLab Testing Agreement%{link_end}.%{br} &#8226; Acknowledge that GitLab will send data from the instance, including personal data, to Google for cloud hosting.%{br} &nbsp;&nbsp;&nbsp;We may also send data to %{ai_docs_link_start}third-party AI providers%{link_end} to provide this feature.')
+ .html_safe % { terms_link_start: terms_link_start, ai_docs_link_start: ai_docs_link_start, link_end: '</a>'.html_safe, br: '</br>'.html_safe }
+ # rubocop:enable Style/FormatString
+ # rubocop:enable Layout/LineLength
+ end
+
+ private
+
+ # rubocop:disable Gitlab/DocUrl
+ # We want to link SaaS docs for flexibility for every URL related to Code Suggestions on Self Managed.
+ # We expect to update docs often during the Beta and we want to point user to the most up to date information.
+ def code_suggestions_docs_url
+ 'https://docs.gitlab.com/ee/user/project/repository/code_suggestions.html'
+ end
+
+ def code_suggestions_agreement_url
+ 'https://about.gitlab.com/handbook/legal/testing-agreement/'
+ end
+
+ def code_suggestions_ai_docs_url
+ 'https://docs.gitlab.com/ee/user/ai_features.html'
+ end
+
+ def code_suggestions_pat_docs_url
+ 'https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#create-a-personal-access-token'
+ end
+ # rubocop:enable Gitlab/DocUrl
+
+ def code_suggestions_link_start(url)
+ "<a href=\"#{url}\" target=\"_blank\" rel=\"noopener noreferrer\">".html_safe
+ end
end
end
end
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index bf8dea15c58..adbf7ab7cf2 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -218,6 +218,7 @@ module ApplicationSettingsHelper
:admin_mode,
:after_sign_out_path,
:after_sign_up_text,
+ :ai_access_token,
:akismet_api_key,
:akismet_enabled,
:allow_local_requests_from_hooks_and_services,
@@ -309,6 +310,7 @@ module ApplicationSettingsHelper
:inactive_projects_delete_after_months,
:inactive_projects_min_size_mb,
:inactive_projects_send_warning_email_after_months,
+ :instance_level_code_suggestions_enabled,
:invisible_captcha_enabled,
:jira_connect_application_key,
:jira_connect_public_key_storage_enabled,
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index db858fd6796..a823b8a93fb 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -720,6 +720,10 @@ class ApplicationSetting < MainClusterwide::ApplicationRecord
allow_nil: false,
inclusion: { in: [true, false], message: N_('must be a boolean value') }
+ validates :ai_access_token,
+ presence: { message: N_("is required to enable Code Suggestions") },
+ if: :instance_level_code_suggestions_enabled
+
attr_encrypted :asset_proxy_secret_key,
mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated,
@@ -948,4 +952,5 @@ class ApplicationSetting < MainClusterwide::ApplicationRecord
end
end
+ApplicationSetting.prepend(ApplicationSettingMaskedAttrs)
ApplicationSetting.prepend_mod_with('ApplicationSetting')
diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb
index ea07fe99c99..c73bdf8793c 100644
--- a/app/models/application_setting_implementation.rb
+++ b/app/models/application_setting_implementation.rb
@@ -37,6 +37,7 @@ module ApplicationSettingImplementation
{
admin_mode: false,
after_sign_up_text: nil,
+ ai_access_token: nil,
akismet_enabled: false,
akismet_api_key: nil,
allow_local_requests_from_system_hooks: true,
@@ -104,6 +105,7 @@ module ApplicationSettingImplementation
housekeeping_gc_period: 200,
housekeeping_incremental_repack_period: 10,
import_sources: Settings.gitlab['import_sources'],
+ instance_level_code_suggestions_enabled: false,
invisible_captcha_enabled: false,
issues_create_limit: 300,
jira_connect_application_key: nil,
diff --git a/app/models/concerns/application_setting_masked_attrs.rb b/app/models/concerns/application_setting_masked_attrs.rb
new file mode 100644
index 00000000000..14a7185e39e
--- /dev/null
+++ b/app/models/concerns/application_setting_masked_attrs.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+# Similar to MASK_PASSWORD mechanism we do for EE, see:
+# https://gitlab.com/gitlab-org/gitlab/-/blob/463bb1f855d71fadef931bd50f1692ee04f211a8/ee/app/models/ee/application_setting.rb#L15
+# but for non-EE attributes.
+module ApplicationSettingMaskedAttrs
+ MASK = '*****'
+
+ def ai_access_token=(value)
+ return if value == MASK
+
+ super
+ end
+end
diff --git a/app/services/auto_merge/merge_when_pipeline_succeeds_service.rb b/app/services/auto_merge/merge_when_pipeline_succeeds_service.rb
index d18f2935d92..2bbb8f925a4 100644
--- a/app/services/auto_merge/merge_when_pipeline_succeeds_service.rb
+++ b/app/services/auto_merge/merge_when_pipeline_succeeds_service.rb
@@ -11,9 +11,14 @@ module AutoMerge
end
def process(merge_request)
+ logger.info("Processing Automerge")
return unless merge_request.actual_head_pipeline_success?
+
+ logger.info("Pipeline Success")
return unless merge_request.mergeable?
+ logger.info("Merge request mergeable")
+
merge_request.merge_async(merge_request.merge_user_id, merge_request.merge_params)
end
@@ -40,5 +45,9 @@ module AutoMerge
def notify(merge_request)
notification_service.async.merge_when_pipeline_succeeds(merge_request, current_user) if merge_request.saved_change_to_auto_merge_enabled?
end
+
+ def logger
+ @logger ||= Gitlab::AppLogger
+ end
end
end
diff --git a/app/services/merge_requests/mergeability/logger.rb b/app/services/merge_requests/mergeability/logger.rb
index 88ef6d81eaa..612c79f0aae 100644
--- a/app/services/merge_requests/mergeability/logger.rb
+++ b/app/services/merge_requests/mergeability/logger.rb
@@ -22,8 +22,8 @@ module MergeRequests
result = yield
+ observe_result(mergeability_name, result)
observe("mergeability.#{mergeability_name}.duration_s", current_monotonic_time - op_started_at)
-
observe_sql_counters(mergeability_name, op_start_db_counters, current_db_counter_payload)
result
@@ -31,7 +31,13 @@ module MergeRequests
private
- attr_reader :destination, :merge_request
+ attr_reader :destination, :merge_request, :stored_result
+
+ def observe_result(name, result)
+ return unless result.respond_to?(:success?)
+
+ observe("mergeability.#{name}.successful", result.success?)
+ end
def observe(name, value)
observations[name.to_s].push(value)
diff --git a/app/views/admin/application_settings/_ai_access.html.haml b/app/views/admin/application_settings/_ai_access.html.haml
new file mode 100644
index 00000000000..41b0a08128e
--- /dev/null
+++ b/app/views/admin/application_settings/_ai_access.html.haml
@@ -0,0 +1,32 @@
+- return if Gitlab.org_or_com?
+
+- expanded = integration_expanded?('ai_access')
+- token_is_present = @application_setting.ai_access_token.present?
+- token_label = token_is_present ? s_('CodeSuggestionsSM|Enter new personal access token') : s_('CodeSuggestionsSM|Personal access token')
+- token_value = token_is_present ? ApplicationSettingMaskedAttrs::MASK : ''
+
+%section.settings.no-animate#js-ai-access-settings{ class: ('expanded' if expanded) }
+ .settings-header
+ %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
+ = s_('CodeSuggestionsSM|Code Suggestions')
+ = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
+ = expanded ? _('Collapse') : _('Expand')
+ %p
+ = s_('CodeSuggestionsSM|Enable Code Suggestion for users of this GitLab instance.')
+ = link_to sprite_icon('question-o'), code_suggestions_docs_url, target: '_blank', class: 'has-tooltip', title: _('More information')
+
+ .settings-content
+ = gitlab_ui_form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-ai-access-settings'), html: { class: 'fieldset-form', id: 'ai-access-settings' } do |f|
+ = form_errors(@application_setting)
+
+ %fieldset
+ .form-group
+ = f.gitlab_ui_checkbox_component :instance_level_code_suggestions_enabled,
+ s_('CodeSuggestionsSM|Turn on Code Suggestions for this instance. By turning on this feature, you:'),
+ help_text: code_suggestions_agreement
+ = f.label :ai_access_token, token_label, class: 'label-bold'
+ = f.password_field :ai_access_token, value: token_value, autocomplete: 'on', class: 'form-control gl-form-input', aria: { describedby: 'code_suggestions_token_explanation' }
+ %p.form-text.text-muted{ id: 'code_suggestions_token_explanation' }
+ = code_suggestions_token_explanation
+
+ = f.submit _('Save changes'), pajamas_button: true
diff --git a/app/views/admin/application_settings/general.html.haml b/app/views/admin/application_settings/general.html.haml
index 3413774b361..022930bd6b4 100644
--- a/app/views/admin/application_settings/general.html.haml
+++ b/app/views/admin/application_settings/general.html.haml
@@ -109,3 +109,4 @@
= render 'admin/application_settings/floc'
= render_if_exists 'admin/application_settings/add_license'
= render 'admin/application_settings/jira_connect'
+= render_if_exists 'admin/application_settings/ai_access'
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 87184d51a17..1de1c20259d 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -10,6 +10,8 @@ en:
pwa_short_name: "PWA short name"
pwa_description: "PWA description"
pwa_icon: "Icon"
+ application_setting:
+ ai_access_token: "Personal access token"
incident_management/timeline_event:
note: 'Timeline text'
issue_link:
diff --git a/config/open_api.yml b/config/open_api.yml
index cbf70c24ce1..257db9dd692 100644
--- a/config/open_api.yml
+++ b/config/open_api.yml
@@ -95,6 +95,8 @@ metadata:
description: Operations related to metadata of the GitLab instance
- name: metrics_user_starred_dashboards
description: Operations related to User-starred metrics dashboards
+ - name: ml_model_registry
+ description: Operations related to Model registry
- name: npm_packages
description: Operations related to NPM packages
- name: nuget_packages
diff --git a/db/post_migrate/20230517005523_ensure_backfill_bigint_id_is_completed.rb b/db/post_migrate/20230517005523_ensure_backfill_bigint_id_is_completed.rb
new file mode 100644
index 00000000000..850ac7bcf5d
--- /dev/null
+++ b/db/post_migrate/20230517005523_ensure_backfill_bigint_id_is_completed.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class EnsureBackfillBigintIdIsCompleted < Gitlab::Database::Migration[2.1]
+ include Gitlab::Database::MigrationHelpers::ConvertToBigint
+
+ restrict_gitlab_migration gitlab_schema: :gitlab_ci
+ disable_ddl_transaction!
+
+ TABLE_NAME = :ci_pipeline_variables
+
+ def up
+ ensure_batched_background_migration_is_finished(
+ job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+ table_name: TABLE_NAME,
+ column_name: 'id',
+ job_arguments: [['id'], ['id_convert_to_bigint']]
+ )
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20230518005523_add_concurrent_index_for_ci_pipeline_variables_bigint_id.rb b/db/post_migrate/20230518005523_add_concurrent_index_for_ci_pipeline_variables_bigint_id.rb
new file mode 100644
index 00000000000..19c48f7bf11
--- /dev/null
+++ b/db/post_migrate/20230518005523_add_concurrent_index_for_ci_pipeline_variables_bigint_id.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class AddConcurrentIndexForCiPipelineVariablesBigintId < Gitlab::Database::Migration[2.1]
+ include Gitlab::Database::MigrationHelpers::ConvertToBigint
+
+ disable_ddl_transaction!
+
+ TABLE_NAME = :ci_pipeline_variables
+ INDEX_NAME = "index_#{TABLE_NAME}_on_id_convert_to_bigint"
+
+ def up
+ add_concurrent_index TABLE_NAME, :id_convert_to_bigint, unique: true, name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name TABLE_NAME, INDEX_NAME
+ end
+end
diff --git a/db/schema_migrations/20230517005523 b/db/schema_migrations/20230517005523
new file mode 100644
index 00000000000..7fdac2b9961
--- /dev/null
+++ b/db/schema_migrations/20230517005523
@@ -0,0 +1 @@
+4d84a87532b45436e64d0c919b361548b4b69b200ec3a91f454af718a51fd22a \ No newline at end of file
diff --git a/db/schema_migrations/20230518005523 b/db/schema_migrations/20230518005523
new file mode 100644
index 00000000000..700da3dff74
--- /dev/null
+++ b/db/schema_migrations/20230518005523
@@ -0,0 +1 @@
+7428675eac2c572aa3521df7af7e79f7cf1b6e8f8472e99c842dddf2f3c7ce77 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index d106f3f7064..8fe5a4c0011 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -30525,6 +30525,8 @@ CREATE INDEX index_ci_pipeline_schedules_on_owner_id_and_id_and_active ON ci_pip
CREATE INDEX index_ci_pipeline_schedules_on_project_id ON ci_pipeline_schedules USING btree (project_id);
+CREATE UNIQUE INDEX index_ci_pipeline_variables_on_id_convert_to_bigint ON ci_pipeline_variables USING btree (id_convert_to_bigint);
+
CREATE UNIQUE INDEX index_ci_pipeline_variables_on_pipeline_id_and_key ON ci_pipeline_variables USING btree (pipeline_id, key);
CREATE INDEX index_ci_pipelines_config_on_pipeline_id ON ci_pipelines_config USING btree (pipeline_id);
diff --git a/doc/administration/auth/atlassian.md b/doc/administration/auth/atlassian.md
index 45617b9965c..27e33c85761 100644
--- a/doc/administration/auth/atlassian.md
+++ b/doc/administration/auth/atlassian.md
@@ -29,13 +29,13 @@ To enable the Atlassian OmniAuth provider for passwordless authentication you mu
1. On your GitLab server, open the configuration file:
- For Omnibus GitLab installations:
+ For Linux package installations:
```shell
sudo editor /etc/gitlab/gitlab.rb
```
- For installations from source:
+ For self-compiled installations:
```shell
sudo -u git -H editor /home/git/gitlab/config/gitlab.yml
@@ -47,7 +47,7 @@ To enable the Atlassian OmniAuth provider for passwordless authentication you mu
GitLab account.
1. Add the provider configuration for Atlassian:
- For Omnibus GitLab installations:
+ For Linux package installations:
```ruby
gitlab_rails['omniauth_providers'] = [
@@ -61,7 +61,7 @@ To enable the Atlassian OmniAuth provider for passwordless authentication you mu
]
```
- For installations from source:
+ For self-compiled installations:
```yaml
- { name: "atlassian_oauth2",
@@ -76,8 +76,8 @@ To enable the Atlassian OmniAuth provider for passwordless authentication you mu
1. Save the configuration file.
1. For the changes to take effect:
- - If you installed via Omnibus, [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
- - If you installed from source, [restart GitLab](../restart_gitlab.md#installations-from-source).
+ - If you installed using the Linux package, [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+ - If you self-compiled your installation, [restart GitLab](../restart_gitlab.md#installations-from-source).
On the sign-in page there should now be an Atlassian icon below the regular sign in form. Select the icon to begin the authentication process.
diff --git a/doc/administration/auth/cognito.md b/doc/administration/auth/cognito.md
index cfac958e297..d821a1e9cfe 100644
--- a/doc/administration/auth/cognito.md
+++ b/doc/administration/auth/cognito.md
@@ -37,16 +37,14 @@ To enable AWS Cognito as an authentication provider, complete the following step
1. Save changes for the app client settings.
1. Under **Domain name**, include the AWS domain name for your AWS Cognito application.
-1. Under **App Clients**, find your app client ID. Select **Show details* to display the app client secret. These values correspond to the OAuth 2.0 Client ID and Client Secret. Save these values.
+1. Under **App Clients**, find your app client ID. Select **Show details** to display the app client secret. These values correspond to the OAuth 2.0 Client ID and Client Secret. Save these values.
## Configure GitLab
1. Configure the [common settings](../../integration/omniauth.md#configure-common-settings)
to add `cognito` as a single sign-on provider. This enables Just-In-Time
account provisioning for users who do not have an existing GitLab account.
-1. On your GitLab server, open the configuration file.
-
- **For Omnibus installations**
+1. On your GitLab server, open the configuration file. For Linux package installations:
```shell
sudo editor /etc/gitlab/gitlab.rb
diff --git a/doc/administration/auth/crowd.md b/doc/administration/auth/crowd.md
index f89e1a00928..c4ebb9a5dee 100644
--- a/doc/administration/auth/crowd.md
+++ b/doc/administration/auth/crowd.md
@@ -26,19 +26,19 @@ this provider also allows Crowd authentication for Git-over-https requests.
1. On your GitLab server, open the configuration file.
- **Omnibus:**
+ - Linux package installations:
- ```shell
- sudo editor /etc/gitlab/gitlab.rb
- ```
+ ```shell
+ sudo editor /etc/gitlab/gitlab.rb
+ ```
- **Source:**
+ - Self-compiled installations:
- ```shell
- cd /home/git/gitlab
+ ```shell
+ cd /home/git/gitlab
- sudo -u git -H editor config/gitlab.yml
- ```
+ sudo -u git -H editor config/gitlab.yml
+ ```
1. Configure the [common settings](../../integration/omniauth.md#configure-common-settings)
to add `crowd` as a single sign-on provider. This enables Just-In-Time
@@ -46,39 +46,39 @@ this provider also allows Crowd authentication for Git-over-https requests.
1. Add the provider configuration:
- **Omnibus:**
-
- ```ruby
- gitlab_rails['omniauth_providers'] = [
- {
- name: "crowd",
- # label: "Provider name", # optional label for login button, defaults to "Crowd"
- args: {
- crowd_server_url: "CROWD_SERVER_URL",
- application_name: "YOUR_APP_NAME",
- application_password: "YOUR_APP_PASSWORD"
+ - Linux package installations:
+
+ ```ruby
+ gitlab_rails['omniauth_providers'] = [
+ {
+ name: "crowd",
+ # label: "Provider name", # optional label for login button, defaults to "Crowd"
+ args: {
+ crowd_server_url: "CROWD_SERVER_URL",
+ application_name: "YOUR_APP_NAME",
+ application_password: "YOUR_APP_PASSWORD"
+ }
}
- }
- ]
- ```
+ ]
+ ```
- **Source:**
+ - Self-compiled installations:
- ```yaml
- - { name: 'crowd',
- # label: 'Provider name', # optional label for login button, defaults to "Crowd"
- args: {
- crowd_server_url: 'CROWD_SERVER_URL',
- application_name: 'YOUR_APP_NAME',
- application_password: 'YOUR_APP_PASSWORD' } }
- ```
+ ```yaml
+ - { name: 'crowd',
+ # label: 'Provider name', # optional label for login button, defaults to "Crowd"
+ args: {
+ crowd_server_url: 'CROWD_SERVER_URL',
+ application_name: 'YOUR_APP_NAME',
+ application_password: 'YOUR_APP_PASSWORD' } }
+ ```
1. Change `CROWD_SERVER_URL` to the [base URL of your Crowd server](https://confluence.atlassian.com/crowdkb/how-to-change-the-crowd-base-url-245827278.html).
1. Change `YOUR_APP_NAME` to the application name from Crowd applications page.
1. Change `YOUR_APP_PASSWORD` to the application password you've set.
1. Save the configuration file.
-1. [Reconfigure](../restart_gitlab.md#omnibus-gitlab-reconfigure) (Omnibus GitLab) or [restart](../restart_gitlab.md#installations-from-source) (source installations) for
- the changes to take effect.
+1. [Reconfigure](../restart_gitlab.md#omnibus-gitlab-reconfigure) (Linux package installations) or
+ [restart](../restart_gitlab.md#installations-from-source) (self-compiled installations) for the changes to take effect.
On the sign in page there should now be a Crowd tab in the sign in form.
diff --git a/doc/administration/auth/jwt.md b/doc/administration/auth/jwt.md
index bdcd6fc89cc..0f2036bea04 100644
--- a/doc/administration/auth/jwt.md
+++ b/doc/administration/auth/jwt.md
@@ -12,13 +12,13 @@ JWT provides you with a secret key for you to use.
1. On your GitLab server, open the configuration file.
- For Omnibus GitLab:
+ For Linux package installations:
```shell
sudo editor /etc/gitlab/gitlab.rb
```
- For installations from source:
+ For self-compiled installations:
```shell
cd /home/git/gitlab
@@ -30,7 +30,7 @@ JWT provides you with a secret key for you to use.
account provisioning for users who do not have an existing GitLab account.
1. Add the provider configuration.
- For Omnibus GitLab:
+ For Linux package installations:
```ruby
gitlab_rails['omniauth_providers'] = [
@@ -49,7 +49,7 @@ JWT provides you with a secret key for you to use.
]
```
- For installation from source:
+ For self-compiled installations:
```yaml
- { name: 'jwt',
@@ -75,9 +75,9 @@ JWT provides you with a secret key for you to use.
1. Change `YOUR_APP_SECRET` to the client secret and set `auth_url` to your redirect URL.
1. Save the configuration file.
-1. For the changes to take effect:
- - If you installed via Omnibus, [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
- - If you installed from source, [restart GitLab](../restart_gitlab.md#installations-from-source).
+1. For changes to take effect, if you:
+ - Used the Linux package to install GitLab, [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+ - Self-compiled your GitLab installation, [restart GitLab](../restart_gitlab.md#installations-from-source).
On the sign in page there should now be a JWT icon below the regular sign in form.
Select the icon to begin the authentication process. JWT asks the user to
diff --git a/doc/administration/auth/ldap/google_secure_ldap.md b/doc/administration/auth/ldap/google_secure_ldap.md
index 042a65be500..8084633c3ba 100644
--- a/doc/administration/auth/ldap/google_secure_ldap.md
+++ b/doc/administration/auth/ldap/google_secure_ldap.md
@@ -72,7 +72,7 @@ values obtained during the LDAP client configuration earlier:
- `cert`: The `.crt` file text from the downloaded certificate bundle
- `key`: The `.key` file text from the downloaded certificate bundle
-**For Omnibus installations**
+For Linux package installations:
1. Edit `/etc/gitlab/gitlab.rb`:
@@ -142,9 +142,7 @@ values obtained during the LDAP client configuration earlier:
1. Save the file and [reconfigure](../../restart_gitlab.md#omnibus-gitlab-reconfigure) GitLab for the changes to take effect.
----
-
-**For installations from source**
+For self-compiled installations:
1. Edit `config/gitlab.yml`:
diff --git a/doc/administration/auth/ldap/index.md b/doc/administration/auth/ldap/index.md
index efed9d76746..a4484da5940 100644
--- a/doc/administration/auth/ldap/index.md
+++ b/doc/administration/auth/ldap/index.md
@@ -1037,8 +1037,8 @@ For more information on synchronizing users and groups between LDAP and GitLab,
## Move from LDAP to SAML
1. [Configure SAML](../../../integration/saml.md). Add `auto_link_ldap_user` to:
- - [`gitlab.rb` for Omnibus](../../../integration/saml.html?tab=Linux+package+%28Omnibus%29).
- - [`values.yml` for Kubernetes](../../../integration/saml.html?tab=Helm+chart+%28Kubernetes%29).
+ - [`gitlab.rb` for Linux package installations](../../../integration/saml.html?tab=Linux+package+%28Omnibus%29).
+ - [`values.yml` for Helm chart installations](../../../integration/saml.html?tab=Helm+chart+%28Kubernetes%29).
For more information, see the [initial settings for all providers](../../../integration/omniauth.md#configure-initial-settings).
1. Optional. [Disable the LDAP auth from the sign-in page](#disable-ldap-web-sign-in).
diff --git a/doc/administration/auth/oidc.md b/doc/administration/auth/oidc.md
index 106cc6c23eb..88c9a669441 100644
--- a/doc/administration/auth/oidc.md
+++ b/doc/administration/auth/oidc.md
@@ -16,7 +16,7 @@ The OpenID Connect provides you with a client's details and secret for you to us
1. On your GitLab server, open the configuration file.
- For Omnibus GitLab:
+ For Linux package installations:
```shell
sudo editor /etc/gitlab/gitlab.rb
@@ -35,7 +35,7 @@ The OpenID Connect provides you with a client's details and secret for you to us
1. Add the provider configuration.
- For Omnibus GitLab:
+ For Linux package installations:
```ruby
gitlab_rails['omniauth_providers'] = [
@@ -63,7 +63,7 @@ The OpenID Connect provides you with a client's details and secret for you to us
]
```
- For Omnibus GitLab with multiple identity providers:
+ For Linux package installations with multiple identity providers:
```ruby
{ 'name' => 'openid_connect',
@@ -108,7 +108,7 @@ The OpenID Connect provides you with a client's details and secret for you to us
NOTE:
For more information on using multiple identity providers with OIDC, see [issue 5992](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/5992).
- For installation from source:
+ For self-compiled installations:
```yaml
- { name: 'openid_connect', # do not change this parameter
@@ -184,10 +184,10 @@ The OpenID Connect provides you with a client's details and secret for you to us
- `jwks_uri` is the URL to the endpoint where the Token signer publishes its keys.
1. Save the configuration file.
-1. For changes to take effect, if you installed GitLab:
+1. For changes to take effect, if you:
- - With Omnibus, [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
- - From source, [restart GitLab](../restart_gitlab.md#installations-from-source).
+ - Used the Linux package to install GitLab, [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+ - Self-compiled your GitLab installation, [restart GitLab](../restart_gitlab.md#installations-from-source).
On the sign in page, you have an OpenID Connect option below the regular sign in form.
Select this option to begin the authentication process. The OpenID Connect provider
@@ -197,7 +197,7 @@ by the client. You are redirected to GitLab and signed in.
## Example configurations
The following configurations illustrate how to set up OpenID with
-different providers with Omnibus GitLab.
+different providers when using the GitLab Linux package installation.
### Configure Google
@@ -240,7 +240,7 @@ you need the following information:
[Microsoft Quickstart Register an Application](https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app) documentation
to obtain the tenant ID, client ID, and client secret for your app.
-Example Omnibus configuration block:
+Example configuration block for Linux package installations:
```ruby
gitlab_rails['omniauth_providers'] = [
@@ -372,7 +372,7 @@ but `LocalAccounts` authenticates against local Active Directory accounts. Befor
```
1. Configure the issuer URL with the custom policy used for `signup_signin`. For example, this is
- the Omnibus configuration with a custom policy for `b2c_1a_signup_signin`:
+ the configuration with a custom policy for `b2c_1a_signup_signin` for Linux package installations:
```ruby
gitlab_rails['omniauth_providers'] = [
@@ -432,7 +432,7 @@ HS256 or HS358) to sign tokens. Public key encryption algorithms are:
1. Select **Realm Settings > Tokens > Default Signature Algorithm**.
1. Configure the signature algorithm.
-Example Omnibus configuration block:
+Example configuration block for Linux package installations:
```ruby
gitlab_rails['omniauth_providers'] = [
@@ -556,7 +556,7 @@ For your app, complete the following steps on Casdoor:
See the [Casdoor documentation](https://casdoor.org/docs/integration/ruby/gitlab) for more details.
-Example Omnibus GitLab configuration (file path: `/etc/gitlab/gitlab.rb`):
+Example configuration for Linux package installations (file path: `/etc/gitlab/gitlab.rb`):
```ruby
gitlab_rails['omniauth_providers'] = [
@@ -617,7 +617,7 @@ This is not compatible with [configuring users based on OIDC group membership](#
The following example configurations show how to offer different levels of authentication, one option with 2FA and one without 2FA.
-For Omnibus GitLab:
+For Linux package installations:
```ruby
gitlab_rails['omniauth_providers'] = [
@@ -668,7 +668,7 @@ gitlab_rails['omniauth_providers'] = [
]
```
-For installation from source:
+For self-compiled installations:
```yaml
- { name: 'openid_connect',
@@ -774,7 +774,7 @@ response to require users to be members of a certain group, configure GitLab to
If you do not set `required_groups` or leave the setting empty, any user authenticated by the IdP through OIDC can use GitLab.
-For Omnibus GitLab:
+For Linux package installations:
1. Edit `/etc/gitlab/gitlab.rb`:
@@ -808,7 +808,7 @@ For Omnibus GitLab:
1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure)
for the changes to take effect.
-For installation from source:
+For self-compiled installations:
1. Edit `/home/git/gitlab/config/gitlab.yml`:
@@ -853,7 +853,7 @@ based on group membership, configure GitLab to identify:
[external user](../../user/admin_area/external_users.md), using the
`external_groups` setting.
-For Omnibus GitLab:
+For Linux package installations:
1. Edit `/etc/gitlab/gitlab.rb`:
@@ -887,7 +887,7 @@ For Omnibus GitLab:
1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure)
for the changes to take effect.
-For installation from source:
+For self-compiled installations:
1. Edit `/home/git/gitlab/config/gitlab.yml`:
@@ -930,7 +930,7 @@ response to assign users as administrator based on group membership, configure G
- Which group memberships grant the user administrator access, using the
`admin_groups` setting.
-For Omnibus GitLab:
+For Linux package installations:
1. Edit `/etc/gitlab/gitlab.rb`:
@@ -964,7 +964,7 @@ For Omnibus GitLab:
1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure)
for the changes to take effect.
-For installation from source:
+For self-compiled installations:
1. Edit `/home/git/gitlab/config/gitlab.yml`:
diff --git a/doc/administration/auth/smartcard.md b/doc/administration/auth/smartcard.md
index 5b6d299f171..0fa585bace5 100644
--- a/doc/administration/auth/smartcard.md
+++ b/doc/administration/auth/smartcard.md
@@ -115,7 +115,7 @@ more information, see [the relevant issue](https://gitlab.com/gitlab-org/gitlab/
## Configure GitLab for smartcard authentication
-**For Omnibus installations**
+For Linux package installations:
1. Edit `/etc/gitlab/gitlab.rb`:
@@ -140,9 +140,7 @@ more information, see [the relevant issue](https://gitlab.com/gitlab-org/gitlab/
1. Save the file and [reconfigure](../restart_gitlab.md#omnibus-gitlab-reconfigure)
GitLab for the changes to take effect.
----
-
-**For installations from source**
+For self-compiled installations:
1. Configure NGINX to request a client side certificate
@@ -237,7 +235,7 @@ more information, see [the relevant issue](https://gitlab.com/gitlab-org/gitlab/
### Additional steps when using SAN extensions
-**For Omnibus installations**
+For Linux package installations:
1. Add to `/etc/gitlab/gitlab.rb`:
@@ -248,7 +246,7 @@ more information, see [the relevant issue](https://gitlab.com/gitlab-org/gitlab/
1. Save the file and [reconfigure](../restart_gitlab.md#omnibus-gitlab-reconfigure)
GitLab for the changes to take effect.
-**For installations from source**
+For self-compiled installations:
1. Add the `san_extensions` line to `config/gitlab.yml` within the smartcard section:
@@ -267,7 +265,7 @@ more information, see [the relevant issue](https://gitlab.com/gitlab-org/gitlab/
### Additional steps when authenticating against an LDAP server
-**For Omnibus installations**
+For Linux package installations:
1. Edit `/etc/gitlab/gitlab.rb`:
@@ -284,7 +282,7 @@ more information, see [the relevant issue](https://gitlab.com/gitlab-org/gitlab/
1. Save the file and [reconfigure](../restart_gitlab.md#omnibus-gitlab-reconfigure)
GitLab for the changes to take effect.
-**For installations from source**
+For self-compiled installations:
1. Edit `config/gitlab.yml`:
@@ -304,7 +302,7 @@ more information, see [the relevant issue](https://gitlab.com/gitlab-org/gitlab/
### Require browser session with smartcard sign-in for Git access
-**For Omnibus installations**
+For Linux package installations:
1. Edit `/etc/gitlab/gitlab.rb`:
@@ -315,7 +313,7 @@ more information, see [the relevant issue](https://gitlab.com/gitlab-org/gitlab/
1. Save the file and [reconfigure](../restart_gitlab.md#omnibus-gitlab-reconfigure)
GitLab for the changes to take effect.
-**For installations from source**
+For self-compiled installations:
1. Edit `config/gitlab.yml`:
diff --git a/doc/administration/clusters/kas.md b/doc/administration/clusters/kas.md
index 6d6e8e5513c..cbd32dea95c 100644
--- a/doc/administration/clusters/kas.md
+++ b/doc/administration/clusters/kas.md
@@ -21,12 +21,12 @@ If you use self-managed GitLab, you must install an agent server or specify an e
As a GitLab administrator, you can install the agent server:
-- For [Omnibus installations](#for-omnibus).
-- For [GitLab Helm Chart installations](#for-gitlab-helm-chart).
+- For [Linux package installations](#for-linux-package-installations).
+- For [GitLab Helm chart installations](#for-gitlab-helm-chart).
-### For Omnibus
+### For Linux package installations
-You can enable the agent server for [Omnibus](https://docs.gitlab.com/omnibus/) package installations on a single node, or on multiple nodes at once.
+You can enable the agent server for Linux package installations on a single node, or on multiple nodes at once.
#### Enable on a single node
@@ -167,7 +167,7 @@ service logs by running the following command:
kubectl logs -f -l=app=kas -n <YOUR-GITLAB-NAMESPACE>
```
-In Omnibus GitLab, find the logs in `/var/log/gitlab/gitlab-kas/`.
+In Linux package installations, find the logs in `/var/log/gitlab/gitlab-kas/`.
You can also [troubleshoot issues with individual agents](../../user/clusters/agent/troubleshooting.md).
@@ -212,7 +212,7 @@ When the agent server tries to connect to the GitLab API, the following error mi
{"level":"error","time":"2021-08-16T14:56:47.289Z","msg":"GetAgentInfo()","correlation_id":"01FD7QE35RXXXX8R47WZFBAXTN","grpc_service":"gitlab.agent.reverse_tunnel.rpc.ReverseTunnel","grpc_method":"Connect","error":"Get \"https://gitlab.example.com/api/v4/internal/kubernetes/agent_info\": dial tcp 172.17.0.4:443: connect: connection refused"}
```
-To fix this issue for [Omnibus](https://docs.gitlab.com/omnibus/) package installations,
+To fix this issue for Linux package installations,
set the following parameter in `/etc/gitlab/gitlab.rb`. Replace `gitlab.example.com` with your GitLab instance's hostname:
```ruby
diff --git a/doc/administration/operations/puma.md b/doc/administration/operations/puma.md
index efc55a5fbc3..63f3c66622d 100644
--- a/doc/administration/operations/puma.md
+++ b/doc/administration/operations/puma.md
@@ -211,6 +211,71 @@ make Prometheus scrape them over HTTPS, and support for it is being discussed
Hence, it is not technically possible to turn off this HTTP listener without
losing Prometheus metrics.
+### Using an encrypted SSL key
+
+> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/7799) in GitLab 16.1.
+
+Puma supports the use of an encrypted private SSL key, which can be
+decrypted at runtime. The following instructions illustrate how to
+configure this:
+
+1. Encrypt the key with a password if it is not already:
+
+ ```shell
+ openssl rsa -aes256 -in /path/to/ssl-key.pem -out /path/to/encrypted-ssl-key.pem
+ ```
+
+ Enter in a password twice to write the encrypted file. In this
+ example, we use `some-password-here`.
+
+1. Create a script or executable that prints the password. For
+ example, create a basic script in
+ `/var/opt/gitlab/gitlab-rails/etc/puma-ssl-key-password` that echoes
+ the password:
+
+ ```shell
+ #!/bin/sh
+ echo some-password-here
+ ```
+
+ Note that in production, you should avoid storing the password on
+ disk and use a secure mechanism for retrieving a password, such as
+ Vault. For example, the script might look like:
+
+ ```shell
+ #!/bin/sh
+ export VAULT_ADDR=http://vault-password-distribution-point:8200
+ export VAULT_TOKEN=<some token>
+
+ echo "$(vault kv get -mount=secret puma-ssl-password)"
+ ```
+
+1. Ensure the Puma process has sufficient permissions to execute the
+ script and to read the encrypted key:
+
+ ```shell
+ chown git:git /var/opt/gitlab/gitlab-rails/etc/puma-ssl-key-password
+ chmod 770 /var/opt/gitlab/gitlab-rails/etc/puma-ssl-key-password
+ chmod 660 /path/to/encrypted-ssl-key.pem
+ ```
+
+1. Edit `/etc/gitlab/gitlab.rb`, and replace `puma['ssl_certificate_key']` with the encrypted key and specify
+ `puma['ssl_key_password_command]`:
+
+ ```ruby
+ puma['ssl_certificate_key'] = '/path/to/encrypted-ssl-key.pem'
+ puma['ssl_key_password_command'] = '/var/opt/gitlab/gitlab-rails/etc/puma-ssl-key-password'
+ ```
+
+1. Reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+1. If GitLab comes up successfully, you should be able to remove the
+ unencrypted SSL key that was stored on the GitLab instance.
+
## Switch from Unicorn to Puma
NOTE:
diff --git a/doc/administration/package_information/postgresql_versions.md b/doc/administration/package_information/postgresql_versions.md
index c1e9f7320ea..44032883eb4 100644
--- a/doc/administration/package_information/postgresql_versions.md
+++ b/doc/administration/package_information/postgresql_versions.md
@@ -30,6 +30,7 @@ Read more about update policies and warnings in the PostgreSQL
| GitLab version | PostgreSQL versions | Default version for fresh installs | Default version for upgrades | Notes |
| -------------- | --------------------- | ---------------------------------- | ---------------------------- | ----- |
+| 16.0 | 13.11 | 13.11 | 13.11 | |
| 15.6 | 12.12, 13.8 | 13.8 | 12.12 | For upgrades, users can manually upgrade to 13.8 following the [upgrade documentation](https://docs.gitlab.com/omnibus/settings/database.html#gitlab-150-and-later). |
| 15.0 | 12.10, 13.6 | 13.6 | 12.10 | For upgrades, users can manually upgrade to 13.6 following the [upgrade documentation](https://docs.gitlab.com/omnibus/settings/database.html#gitlab-150-and-later). |
| 14.1 | 12.7, 13.3 | 12.7 | 12.7 | PostgreSQL 13 available for fresh installations if not using [Geo](../geo/index.md#requirements-for-running-geo) or [Patroni](../postgresql/index.md#postgresql-replication-and-failover-with-omnibus-gitlab).
diff --git a/doc/user/profile/account/delete_account.md b/doc/user/profile/account/delete_account.md
index 0b6aed01309..1ffe01d6e00 100644
--- a/doc/user/profile/account/delete_account.md
+++ b/doc/user/profile/account/delete_account.md
@@ -32,6 +32,8 @@ As a user, to delete your own account:
NOTE:
On GitLab.com, there is a seven day delay between a user deleting their own account and deletion of the user record. During this time, that user is [blocked](../../admin_area/moderate_users.md#block-a-user) and a new account with the same email address or username cannot be created.
+Unblocking the account does not undo the deletion because the account will still be in the deletion queue, and there is no quick method to reverse this process.
+
## Delete users and user contributions **(FREE SELF)**
As an administrator, to delete a user account:
diff --git a/lib/api/api.rb b/lib/api/api.rb
index a7acd44e72a..5f7faa7eb7d 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -255,6 +255,7 @@ module API
mount ::API::Metadata
mount ::API::Metrics::Dashboard::Annotations
mount ::API::Metrics::UserStarredDashboards
+ mount ::API::MlModelPackages
mount ::API::Namespaces
mount ::API::NpmGroupPackages
mount ::API::NpmInstancePackages
diff --git a/lib/api/ml_model_packages.rb b/lib/api/ml_model_packages.rb
new file mode 100644
index 00000000000..fec72b03ffd
--- /dev/null
+++ b/lib/api/ml_model_packages.rb
@@ -0,0 +1,111 @@
+# frozen_string_literal: true
+
+module API
+ class MlModelPackages < ::API::Base
+ include APIGuard
+ include ::API::Helpers::Authentication
+
+ ML_MODEL_PACKAGES_REQUIREMENTS = {
+ package_name: API::NO_SLASH_URL_PART_REGEX,
+ file_name: API::NO_SLASH_URL_PART_REGEX
+ }.freeze
+
+ ALLOWED_STATUSES = %w[default hidden].freeze
+
+ feature_category :mlops
+ urgency :low
+
+ after_validation do
+ require_packages_enabled!
+ authenticate_non_get!
+
+ not_found! unless can?(current_user, :read_model_registry, user_project)
+ end
+
+ authenticate_with do |accept|
+ accept.token_types(:personal_access_token, :deploy_token, :job_token)
+ .sent_through(:http_token)
+ end
+
+ helpers do
+ include ::API::Helpers::PackagesHelpers
+ include ::API::Helpers::Packages::BasicAuthHelpers
+
+ def project
+ authorized_user_project
+ end
+
+ def max_file_size_exceeded?
+ project.actual_limits.exceeded?(:ml_model_max_file_size, params[:file].size)
+ end
+ end
+
+ params do
+ requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
+ end
+
+ resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
+ namespace ':id/packages/ml_models' do
+ params do
+ requires :package_name, type: String, desc: 'Package name', regexp: Gitlab::Regex.ml_model_name_regex,
+ file_path: true
+ requires :package_version, type: String, desc: 'Package version',
+ regexp: Gitlab::Regex.ml_model_version_regex
+ requires :file_name, type: String, desc: 'Package file name',
+ regexp: Gitlab::Regex.ml_model_file_name_regex, file_path: true
+ optional :status, type: String, values: ALLOWED_STATUSES, desc: 'Package status'
+ end
+ namespace ':package_name/*package_version/:file_name', requirements: ML_MODEL_PACKAGES_REQUIREMENTS do
+ desc 'Workhorse authorize model package file' do
+ detail 'Introduced in GitLab 16.1'
+ success code: 200
+ failure [
+ { code: 401, message: 'Unauthorized' },
+ { code: 403, message: 'Forbidden' },
+ { code: 404, message: 'Not Found' }
+ ]
+ tags %w[ml_model_registry]
+ end
+ put 'authorize' do
+ authorize_workhorse!(subject: project, maximum_size: project.actual_limits.ml_model_max_file_size)
+ end
+
+ desc 'Workhorse upload model package file' do
+ detail 'Introduced in GitLab 16.1'
+ success code: 201
+ failure [
+ { code: 401, message: 'Unauthorized' },
+ { code: 403, message: 'Forbidden' },
+ { code: 404, message: 'Not Found' }
+ ]
+ tags %w[ml_model_registry]
+ end
+ params do
+ requires :file,
+ type: ::API::Validations::Types::WorkhorseFile,
+ desc: 'The package file to be published (generated by Multipart middleware)',
+ documentation: { type: 'file' }
+ end
+ put do
+ authorize_upload!(project)
+
+ bad_request!('File is too large') if max_file_size_exceeded?
+
+ create_package_file_params = declared(params).merge(build: current_authenticated_job)
+ package_file = ::Packages::MlModel::CreatePackageFileService
+ .new(project, current_user, create_package_file_params)
+ .execute
+
+ bad_request!('Package creation failed') unless package_file
+
+ created!
+ rescue ObjectStorage::RemoteStoreError => e
+ Gitlab::ErrorTracking.track_exception(e, extra: { file_name: params[:file_name], project_id: project.id })
+
+ forbidden!
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb
index 79f12ee13f7..26ca9d2547c 100644
--- a/lib/gitlab/regex.rb
+++ b/lib/gitlab/regex.rb
@@ -623,6 +623,18 @@ module Gitlab
def x509_subject_key_identifier_regex
@x509_subject_key_identifier_regex ||= /\A(?:\h{2}:)*\h{2}\z/.freeze
end
+
+ def ml_model_version_regex
+ maven_version_regex
+ end
+
+ def ml_model_name_regex
+ package_name_regex
+ end
+
+ def ml_model_file_name_regex
+ maven_file_name_regex
+ end
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 9a6218e486a..a65b08a5ede 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -11070,6 +11070,27 @@ msgstr ""
msgid "CodeSuggestionsAlert|Get started with Code Suggestions, available for free during the beta period."
msgstr ""
+msgid "CodeSuggestionsSM|&#8226; Agree to the %{terms_link_start}GitLab Testing Agreement%{link_end}.%{br} &#8226; Acknowledge that GitLab will send data from the instance, including personal data, to Google for cloud hosting.%{br} &nbsp;&nbsp;&nbsp;We may also send data to %{ai_docs_link_start}third-party AI providers%{link_end} to provide this feature."
+msgstr ""
+
+msgid "CodeSuggestionsSM|Code Suggestions"
+msgstr ""
+
+msgid "CodeSuggestionsSM|Enable Code Suggestion for users of this GitLab instance."
+msgstr ""
+
+msgid "CodeSuggestionsSM|Enter new personal access token"
+msgstr ""
+
+msgid "CodeSuggestionsSM|Personal access token"
+msgstr ""
+
+msgid "CodeSuggestionsSM|Turn on Code Suggestions for this instance. By turning on this feature, you:"
+msgstr ""
+
+msgid "CodeSuggestionsSM|Your personal access token from GitLab.com. See the %{link_start}documentation%{link_end} for information on creating a personal access token."
+msgstr ""
+
msgid "CodeSuggestions|%{link_start}What are code suggestions?%{link_end}"
msgstr ""
@@ -54137,6 +54158,9 @@ msgstr ""
msgid "is read-only"
msgstr ""
+msgid "is required to enable Code Suggestions"
+msgstr ""
+
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
diff --git a/scripts/review_apps/review-apps.sh b/scripts/review_apps/review-apps.sh
index 6ebb0f61a04..660257b042a 100755
--- a/scripts/review_apps/review-apps.sh
+++ b/scripts/review_apps/review-apps.sh
@@ -133,8 +133,8 @@ function disable_sign_ups() {
# We use this weird syntax because we need to pass a one-liner ruby command to a Kubernetes container via kubectl.
read -r -d '' multiline_ruby_code <<RUBY
user = User.find_by_username('root');
-puts 'Error: Could not find root user. Check that the database was properly seeded'; exit(1) unless user;
-token = user.personal_access_tokens.create(scopes: [:api], name: 'Token to disable sign-ups');
+(puts 'Error: Could not find root user. Check that the database was properly seeded'; exit(1)) unless user;
+token = user.personal_access_tokens.create(scopes: [:api], name: 'Token to disable sign-ups', expires_at: 30.days.from_now);
token.set_token('${REVIEW_APPS_ROOT_TOKEN}');
begin;
token.save!;
diff --git a/spec/helpers/admin/application_settings/settings_helper_spec.rb b/spec/helpers/admin/application_settings/settings_helper_spec.rb
index 9981e0d12bd..efffc224eb2 100644
--- a/spec/helpers/admin/application_settings/settings_helper_spec.rb
+++ b/spec/helpers/admin/application_settings/settings_helper_spec.rb
@@ -31,4 +31,18 @@ RSpec.describe Admin::ApplicationSettings::SettingsHelper do
})
end
end
+
+ describe 'Code Suggestions for Self-Managed instances', feature_category: :code_suggestions do
+ describe '#code_suggestions_token_explanation' do
+ subject { helper.code_suggestions_token_explanation }
+
+ it { is_expected.to include 'https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#create-a-personal-access-token' }
+ end
+
+ describe '#code_suggestions_agreement' do
+ subject { helper.code_suggestions_agreement }
+
+ it { is_expected.to include 'https://about.gitlab.com/handbook/legal/testing-agreement/' }
+ end
+ end
end
diff --git a/spec/lib/sidebars/admin/menus/abuse_reports_menu_spec.rb b/spec/lib/sidebars/admin/menus/abuse_reports_menu_spec.rb
index 5926852ff57..ef5b8055bec 100644
--- a/spec/lib/sidebars/admin/menus/abuse_reports_menu_spec.rb
+++ b/spec/lib/sidebars/admin/menus/abuse_reports_menu_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe Sidebars::Admin::Menus::AbuseReportsMenu, feature_category: :navi
it_behaves_like 'Admin menu without sub menus', active_routes: { controller: :abuse_reports }
describe '#pill_count' do
- let_it_be(:user) { create(:user, :admin) }
+ let(:user) { build_stubbed(:user, :admin) }
let(:context) { Sidebars::Context.new(current_user: user, container: nil) }
diff --git a/spec/lib/sidebars/admin/menus/monitoring_menu_spec.rb b/spec/lib/sidebars/admin/menus/monitoring_menu_spec.rb
index 3bf43b9a251..4e1d56dc001 100644
--- a/spec/lib/sidebars/admin/menus/monitoring_menu_spec.rb
+++ b/spec/lib/sidebars/admin/menus/monitoring_menu_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Sidebars::Admin::Menus::MonitoringMenu, feature_category: :navigation do
- let_it_be(:user) { create(:user, :admin) }
+ let(:user) { build_stubbed(:user, :admin) }
let(:context) { Sidebars::Context.new(current_user: user, container: nil) }
let(:menu) { described_class.new(context) }
diff --git a/spec/lib/sidebars/concerns/container_with_html_options_spec.rb b/spec/lib/sidebars/concerns/container_with_html_options_spec.rb
index d95cdb9e0fe..588e89a80f7 100644
--- a/spec/lib/sidebars/concerns/container_with_html_options_spec.rb
+++ b/spec/lib/sidebars/concerns/container_with_html_options_spec.rb
@@ -2,7 +2,7 @@
require 'fast_spec_helper'
-RSpec.describe Sidebars::Concerns::ContainerWithHtmlOptions do
+RSpec.describe Sidebars::Concerns::ContainerWithHtmlOptions, feature_category: :navigation do
subject do
Class.new do
include Sidebars::Concerns::ContainerWithHtmlOptions
diff --git a/spec/lib/sidebars/concerns/link_with_html_options_spec.rb b/spec/lib/sidebars/concerns/link_with_html_options_spec.rb
index f7e6701c37d..64f19ed9e98 100644
--- a/spec/lib/sidebars/concerns/link_with_html_options_spec.rb
+++ b/spec/lib/sidebars/concerns/link_with_html_options_spec.rb
@@ -2,7 +2,7 @@
require 'fast_spec_helper'
-RSpec.describe Sidebars::Concerns::LinkWithHtmlOptions do
+RSpec.describe Sidebars::Concerns::LinkWithHtmlOptions, feature_category: :navigation do
let(:options) { {} }
subject { Class.new { include Sidebars::Concerns::LinkWithHtmlOptions }.new }
diff --git a/spec/lib/sidebars/groups/menus/ci_cd_menu_spec.rb b/spec/lib/sidebars/groups/menus/ci_cd_menu_spec.rb
index 246df2e409b..2b9a4133f3f 100644
--- a/spec/lib/sidebars/groups/menus/ci_cd_menu_spec.rb
+++ b/spec/lib/sidebars/groups/menus/ci_cd_menu_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Sidebars::Groups::Menus::CiCdMenu do
+RSpec.describe Sidebars::Groups::Menus::CiCdMenu, feature_category: :navigation do
let_it_be(:owner) { create(:user) }
let_it_be(:root_group) do
build(:group, :private).tap do |g|
diff --git a/spec/lib/sidebars/groups/menus/observability_menu_spec.rb b/spec/lib/sidebars/groups/menus/observability_menu_spec.rb
index 20af8ea00be..573760cddb6 100644
--- a/spec/lib/sidebars/groups/menus/observability_menu_spec.rb
+++ b/spec/lib/sidebars/groups/menus/observability_menu_spec.rb
@@ -2,9 +2,9 @@
require 'spec_helper'
-RSpec.describe Sidebars::Groups::Menus::ObservabilityMenu do
- let_it_be(:owner) { create(:user) }
- let_it_be(:root_group) do
+RSpec.describe Sidebars::Groups::Menus::ObservabilityMenu, feature_category: :navigation do
+ let(:owner) { build_stubbed(:user) }
+ let(:root_group) do
build(:group, :private).tap do |g|
g.add_owner(owner)
end
diff --git a/spec/lib/sidebars/groups/menus/settings_menu_spec.rb b/spec/lib/sidebars/groups/menus/settings_menu_spec.rb
index bc30d7628af..8628696ebd8 100644
--- a/spec/lib/sidebars/groups/menus/settings_menu_spec.rb
+++ b/spec/lib/sidebars/groups/menus/settings_menu_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Sidebars::Groups::Menus::SettingsMenu, :with_license do
+RSpec.describe Sidebars::Groups::Menus::SettingsMenu, :with_license, feature_category: :navigation do
let_it_be(:owner) { create(:user) }
let_it_be_with_refind(:group) do
diff --git a/spec/lib/sidebars/menu_item_spec.rb b/spec/lib/sidebars/menu_item_spec.rb
index 84bc3430260..3ff5b80e5d9 100644
--- a/spec/lib/sidebars/menu_item_spec.rb
+++ b/spec/lib/sidebars/menu_item_spec.rb
@@ -2,7 +2,7 @@
require 'fast_spec_helper'
-RSpec.describe Sidebars::MenuItem do
+RSpec.describe Sidebars::MenuItem, feature_category: :navigation do
let(:title) { 'foo' }
let(:html_options) { {} }
let(:menu_item) { described_class.new(title: title, active_routes: {}, link: '', container_html_options: html_options) }
diff --git a/spec/lib/sidebars/projects/context_spec.rb b/spec/lib/sidebars/projects/context_spec.rb
index 44578ae1583..bdf6439b85b 100644
--- a/spec/lib/sidebars/projects/context_spec.rb
+++ b/spec/lib/sidebars/projects/context_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Sidebars::Projects::Context do
+RSpec.describe Sidebars::Projects::Context, feature_category: :navigation do
let(:project) { build(:project) }
subject { described_class.new(current_user: nil, container: project) }
diff --git a/spec/lib/sidebars/projects/menus/analytics_menu_spec.rb b/spec/lib/sidebars/projects/menus/analytics_menu_spec.rb
index 878da747abe..45aa93bef1c 100644
--- a/spec/lib/sidebars/projects/menus/analytics_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/analytics_menu_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Sidebars::Projects::Menus::AnalyticsMenu do
+RSpec.describe Sidebars::Projects::Menus::AnalyticsMenu, feature_category: :navigation do
let_it_be_with_refind(:project) { create(:project, :repository) }
let_it_be(:guest) do
create(:user).tap { |u| project.add_guest(u) }
diff --git a/spec/lib/sidebars/projects/menus/ci_cd_menu_spec.rb b/spec/lib/sidebars/projects/menus/ci_cd_menu_spec.rb
index 6116fff792a..f6602bf2b46 100644
--- a/spec/lib/sidebars/projects/menus/ci_cd_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/ci_cd_menu_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Sidebars::Projects::Menus::CiCdMenu do
+RSpec.describe Sidebars::Projects::Menus::CiCdMenu, feature_category: :navigation do
let(:project) { build(:project) }
let(:user) { project.first_owner }
let(:can_view_pipeline_editor) { true }
diff --git a/spec/lib/sidebars/projects/menus/confluence_menu_spec.rb b/spec/lib/sidebars/projects/menus/confluence_menu_spec.rb
index 55c55b70a43..61ee16c3cf6 100644
--- a/spec/lib/sidebars/projects/menus/confluence_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/confluence_menu_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Sidebars::Projects::Menus::ConfluenceMenu do
+RSpec.describe Sidebars::Projects::Menus::ConfluenceMenu, feature_category: :navigation do
let_it_be_with_refind(:project) { create(:project, has_external_wiki: true) }
let(:user) { project.first_owner }
diff --git a/spec/lib/sidebars/projects/menus/external_issue_tracker_menu_spec.rb b/spec/lib/sidebars/projects/menus/external_issue_tracker_menu_spec.rb
index 2033d40897e..dc7c2ec6ed8 100644
--- a/spec/lib/sidebars/projects/menus/external_issue_tracker_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/external_issue_tracker_menu_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Sidebars::Projects::Menus::ExternalIssueTrackerMenu do
+RSpec.describe Sidebars::Projects::Menus::ExternalIssueTrackerMenu, feature_category: :navigation do
let(:project) { build(:project) }
let(:user) { project.first_owner }
let(:jira_issues_integration_active) { false }
diff --git a/spec/lib/sidebars/projects/menus/hidden_menu_spec.rb b/spec/lib/sidebars/projects/menus/hidden_menu_spec.rb
index e64b0de9c62..a9e870934c4 100644
--- a/spec/lib/sidebars/projects/menus/hidden_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/hidden_menu_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Sidebars::Projects::Menus::HiddenMenu do
+RSpec.describe Sidebars::Projects::Menus::HiddenMenu, feature_category: :navigation do
let_it_be(:project) { create(:project, :repository) }
let(:user) { project.first_owner }
diff --git a/spec/lib/sidebars/projects/menus/issues_menu_spec.rb b/spec/lib/sidebars/projects/menus/issues_menu_spec.rb
index 544cbcb956d..53d92d013a9 100644
--- a/spec/lib/sidebars/projects/menus/issues_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/issues_menu_spec.rb
@@ -71,7 +71,7 @@ RSpec.describe Sidebars::Projects::Menus::IssuesMenu, feature_category: :navigat
context 'when there are open issues' do
it 'returns the number of open issues' do
create_list(:issue, 2, :opened, project: project)
- create(:issue, :closed, project: project)
+ build_stubbed(:issue, :closed, project: project)
expect(subject.pill_count).to eq '2'
end
diff --git a/spec/lib/sidebars/projects/menus/monitor_menu_spec.rb b/spec/lib/sidebars/projects/menus/monitor_menu_spec.rb
index 8bb7e8c8518..363822ee5e4 100644
--- a/spec/lib/sidebars/projects/menus/monitor_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/monitor_menu_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Sidebars::Projects::Menus::MonitorMenu do
+RSpec.describe Sidebars::Projects::Menus::MonitorMenu, feature_category: :navigation do
let_it_be_with_refind(:project) { create(:project) }
let(:user) { project.first_owner }
diff --git a/spec/lib/sidebars/projects/menus/settings_menu_spec.rb b/spec/lib/sidebars/projects/menus/settings_menu_spec.rb
index 4be99892631..a60e46582f9 100644
--- a/spec/lib/sidebars/projects/menus/settings_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/settings_menu_spec.rb
@@ -2,8 +2,8 @@
require 'spec_helper'
-RSpec.describe Sidebars::Projects::Menus::SettingsMenu do
- let_it_be(:project) { create(:project) }
+RSpec.describe Sidebars::Projects::Menus::SettingsMenu, feature_category: :navigation do
+ let(:project) { build_stubbed(:project) }
let(:user) { project.first_owner }
let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project) }
diff --git a/spec/lib/sidebars/projects/menus/zentao_menu_spec.rb b/spec/lib/sidebars/projects/menus/zentao_menu_spec.rb
index f0bce6b7ea5..749b0df7c08 100644
--- a/spec/lib/sidebars/projects/menus/zentao_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/zentao_menu_spec.rb
@@ -2,6 +2,6 @@
require 'spec_helper'
-RSpec.describe Sidebars::Projects::Menus::ZentaoMenu do
+RSpec.describe Sidebars::Projects::Menus::ZentaoMenu, feature_category: :navigation do
it_behaves_like 'ZenTao menu with CE version'
end
diff --git a/spec/lib/sidebars/projects/super_sidebar_panel_spec.rb b/spec/lib/sidebars/projects/super_sidebar_panel_spec.rb
index bcc8f51901d..3fc6cd5083f 100644
--- a/spec/lib/sidebars/projects/super_sidebar_panel_spec.rb
+++ b/spec/lib/sidebars/projects/super_sidebar_panel_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Sidebars::Projects::SuperSidebarPanel, feature_category: :navigation do
- let_it_be(:project) { create(:project, :repository) }
+ let(:project) { build_stubbed(:project, :repository) }
let(:user) { project.first_owner }
let(:context) do
diff --git a/spec/lib/sidebars/search/panel_spec.rb b/spec/lib/sidebars/search/panel_spec.rb
index 30801ff800e..39c0f112793 100644
--- a/spec/lib/sidebars/search/panel_spec.rb
+++ b/spec/lib/sidebars/search/panel_spec.rb
@@ -3,8 +3,8 @@
require 'spec_helper'
RSpec.describe Sidebars::Search::Panel, feature_category: :navigation do
- let_it_be(:current_user) { create(:user) }
- let_it_be(:user) { create(:user) }
+ let(:current_user) { build_stubbed(:user) }
+ let(:user) { build_stubbed(:user) }
let(:context) { Sidebars::Context.new(current_user: current_user, container: user) }
let(:panel) { described_class.new(context) }
diff --git a/spec/lib/sidebars/user_profile/panel_spec.rb b/spec/lib/sidebars/user_profile/panel_spec.rb
index c62c7f9fd96..a2bf490bc58 100644
--- a/spec/lib/sidebars/user_profile/panel_spec.rb
+++ b/spec/lib/sidebars/user_profile/panel_spec.rb
@@ -3,8 +3,8 @@
require 'spec_helper'
RSpec.describe Sidebars::UserProfile::Panel, feature_category: :navigation do
- let_it_be(:current_user) { create(:user) }
- let_it_be(:user) { create(:user) }
+ let(:current_user) { build_stubbed(:user) }
+ let(:user) { build_stubbed(:user) }
let(:context) { Sidebars::Context.new(current_user: current_user, container: user) }
diff --git a/spec/lib/sidebars/user_settings/panel_spec.rb b/spec/lib/sidebars/user_settings/panel_spec.rb
index 0c02bf77d0e..d574652188d 100644
--- a/spec/lib/sidebars/user_settings/panel_spec.rb
+++ b/spec/lib/sidebars/user_settings/panel_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Sidebars::UserSettings::Panel, feature_category: :navigation do
- let_it_be(:user) { create(:user) }
+ let(:user) { build_stubbed(:user) }
let(:context) { Sidebars::Context.new(current_user: user, container: nil) }
diff --git a/spec/lib/sidebars/your_work/menus/issues_menu_spec.rb b/spec/lib/sidebars/your_work/menus/issues_menu_spec.rb
index a1206c0bc1c..2348054752f 100644
--- a/spec/lib/sidebars/your_work/menus/issues_menu_spec.rb
+++ b/spec/lib/sidebars/your_work/menus/issues_menu_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Sidebars::YourWork::Menus::IssuesMenu, feature_category: :navigation do
- let(:user) { create(:user) }
+ let(:user) { build_stubbed(:user) }
let(:context) { Sidebars::Context.new(current_user: user, container: nil) }
subject { described_class.new(context) }
diff --git a/spec/lib/sidebars/your_work/menus/merge_requests_menu_spec.rb b/spec/lib/sidebars/your_work/menus/merge_requests_menu_spec.rb
index 8941c11006e..d7d24bb55c8 100644
--- a/spec/lib/sidebars/your_work/menus/merge_requests_menu_spec.rb
+++ b/spec/lib/sidebars/your_work/menus/merge_requests_menu_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Sidebars::YourWork::Menus::MergeRequestsMenu, feature_category: :navigation do
- let_it_be(:user) { create(:user) }
+ let(:user) { build_stubbed(:user) }
let(:context) { Sidebars::Context.new(current_user: user, container: nil) }
diff --git a/spec/lib/sidebars/your_work/menus/todos_menu_spec.rb b/spec/lib/sidebars/your_work/menus/todos_menu_spec.rb
index a8177a6a01b..d3b51645cca 100644
--- a/spec/lib/sidebars/your_work/menus/todos_menu_spec.rb
+++ b/spec/lib/sidebars/your_work/menus/todos_menu_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Sidebars::YourWork::Menus::TodosMenu, feature_category: :navigation do
- let(:user) { create(:user) }
+ let(:user) { build_stubbed(:user) }
let(:context) { Sidebars::Context.new(current_user: user, container: nil) }
subject { described_class.new(context) }
diff --git a/spec/lib/sidebars/your_work/panel_spec.rb b/spec/lib/sidebars/your_work/panel_spec.rb
index ae9c3aa18e6..65c2786a16d 100644
--- a/spec/lib/sidebars/your_work/panel_spec.rb
+++ b/spec/lib/sidebars/your_work/panel_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Sidebars::YourWork::Panel, feature_category: :navigation do
- let_it_be(:user) { create(:user) }
+ let(:user) { build_stubbed(:user) }
let(:context) { Sidebars::Context.new(current_user: user, container: nil) }
diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb
index bac9b58056b..b0c7f8c6dfc 100644
--- a/spec/models/application_setting_spec.rb
+++ b/spec/models/application_setting_spec.rb
@@ -1650,4 +1650,29 @@ RSpec.describe ApplicationSetting, feature_category: :shared, type: :model do
expect(setting.personal_access_tokens_disabled?).to eq(false)
end
end
+
+ describe '#ai_access_token' do
+ context 'when `instance_level_code_suggestions_enabled` is true' do
+ before do
+ setting.instance_level_code_suggestions_enabled = true
+ end
+
+ it { is_expected.not_to allow_value(nil).for(:ai_access_token) }
+ end
+
+ context 'when `instance_level_code_suggestions_enabled` is false' do
+ before do
+ setting.instance_level_code_suggestions_enabled = false
+ end
+
+ it { is_expected.to allow_value(nil).for(:ai_access_token) }
+ end
+
+ it 'does not modify the token if it is unchanged in the form' do
+ setting.ai_access_token = 'foo'
+ setting.ai_access_token = ApplicationSettingMaskedAttrs::MASK
+
+ expect(setting.ai_access_token).to eq('foo')
+ end
+ end
end
diff --git a/spec/requests/api/ml_model_packages_spec.rb b/spec/requests/api/ml_model_packages_spec.rb
new file mode 100644
index 00000000000..9c19f522e46
--- /dev/null
+++ b/spec/requests/api/ml_model_packages_spec.rb
@@ -0,0 +1,200 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::API::MlModelPackages, feature_category: :mlops do
+ include HttpBasicAuthHelpers
+ include PackagesManagerApiSpecHelpers
+ include WorkhorseHelpers
+ using RSpec::Parameterized::TableSyntax
+
+ include_context 'workhorse headers'
+
+ let_it_be(:project, reload: true) { create(:project) }
+ let_it_be(:personal_access_token) { create(:personal_access_token) }
+ let_it_be(:job) { create(:ci_build, :running, user: personal_access_token.user, project: project) }
+ let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
+ let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
+ let_it_be(:another_project, reload: true) { create(:project) }
+
+ let_it_be(:tokens) do
+ {
+ personal_access_token: personal_access_token.token,
+ deploy_token: deploy_token.token,
+ job_token: job.token
+ }
+ end
+
+ let(:user) { personal_access_token.user }
+ let(:user_role) { :developer }
+ let(:member) { true }
+ let(:ci_build) { create(:ci_build, :running, user: user, project: project) }
+ let(:project_to_enable_ff) { project }
+ let(:headers) { {} }
+
+ shared_context 'ml model authorize permissions table' do # rubocop:disable RSpec/ContextWording
+ # rubocop:disable Metrics/AbcSize
+ # :visibility, :user_role, :member, :token_type, :valid_token, :expected_status
+ def authorize_permissions_table
+ :public | :developer | true | :personal_access_token | true | :success
+ :public | :guest | true | :personal_access_token | true | :forbidden
+ :public | :developer | true | :personal_access_token | false | :unauthorized
+ :public | :guest | true | :personal_access_token | false | :unauthorized
+ :public | :developer | false | :personal_access_token | true | :forbidden
+ :public | :guest | false | :personal_access_token | true | :forbidden
+ :public | :developer | false | :personal_access_token | false | :unauthorized
+ :public | :guest | false | :personal_access_token | false | :unauthorized
+ :public | :anonymous | false | :personal_access_token | true | :unauthorized
+ :private | :developer | true | :personal_access_token | true | :success
+ :private | :guest | true | :personal_access_token | true | :forbidden
+ :private | :developer | true | :personal_access_token | false | :unauthorized
+ :private | :guest | true | :personal_access_token | false | :unauthorized
+ :private | :developer | false | :personal_access_token | true | :not_found
+ :private | :guest | false | :personal_access_token | true | :not_found
+ :private | :developer | false | :personal_access_token | false | :unauthorized
+ :private | :guest | false | :personal_access_token | false | :unauthorized
+ :private | :anonymous | false | :personal_access_token | true | :unauthorized
+ :public | :developer | true | :job_token | true | :success
+ :public | :guest | true | :job_token | true | :forbidden
+ :public | :developer | true | :job_token | false | :unauthorized
+ :public | :guest | true | :job_token | false | :unauthorized
+ :public | :developer | false | :job_token | true | :forbidden
+ :public | :guest | false | :job_token | true | :forbidden
+ :public | :developer | false | :job_token | false | :unauthorized
+ :public | :guest | false | :job_token | false | :unauthorized
+ :private | :developer | true | :job_token | true | :success
+ :private | :guest | true | :job_token | true | :forbidden
+ :private | :developer | true | :job_token | false | :unauthorized
+ :private | :guest | true | :job_token | false | :unauthorized
+ :private | :developer | false | :job_token | true | :not_found
+ :private | :guest | false | :job_token | true | :not_found
+ :private | :developer | false | :job_token | false | :unauthorized
+ :private | :guest | false | :job_token | false | :unauthorized
+ :public | :developer | true | :deploy_token | true | :success
+ :public | :developer | true | :deploy_token | false | :unauthorized
+ :private | :developer | true | :deploy_token | true | :success
+ :private | :developer | true | :deploy_token | false | :unauthorized
+ end
+ # rubocop:enable Metrics/AbcSize
+ end
+
+ before do
+ project.send("add_#{user_role}", user) if member && user_role != :anonymous
+ end
+
+ subject(:api_response) do
+ request
+ response
+ end
+
+ describe 'PUT /api/v4/projects/:id/packages/ml_models/:package_name/:package_version/:file_name/authorize' do
+ include_context 'ml model authorize permissions table'
+
+ let(:token) { tokens[:personal_access_token] }
+ let(:user_headers) { { 'HTTP_AUTHORIZATION' => token } }
+ let(:headers) { user_headers.merge(workhorse_headers) }
+ let(:request) { authorize_upload_file(headers) }
+
+ describe 'user access' do
+ where(:visibility, :user_role, :member, :token_type, :valid_token, :expected_status) do
+ authorize_permissions_table
+ end
+
+ with_them do
+ let(:token) { valid_token ? tokens[token_type] : 'invalid-token123' }
+ let(:user_headers) { user_role == :anonymous ? {} : { 'HTTP_AUTHORIZATION' => token } }
+
+ before do
+ project.update_column(:visibility_level, Gitlab::VisibilityLevel.level_value(visibility.to_s))
+ end
+
+ it { is_expected.to have_gitlab_http_status(expected_status) }
+ end
+
+ it_behaves_like 'Endpoint not found if read_model_registry not available'
+ end
+
+ describe 'application security' do
+ where(:param_name, :param_value) do
+ :package_name | 'my-package/../'
+ :package_name | 'my-package%2f%2e%2e%2f'
+ :file_name | '../.ssh%2fauthorized_keys'
+ :file_name | '%2e%2e%2f.ssh%2fauthorized_keys'
+ end
+
+ with_them do
+ let(:request) { authorize_upload_file(headers, param_name => param_value) }
+
+ it 'rejects malicious request' do
+ is_expected.to have_gitlab_http_status(:bad_request)
+ end
+ end
+ end
+ end
+
+ describe 'PUT /api/v4/projects/:id/packages/ml_models/:package_name/:package_version/:file_name' do
+ include_context 'ml model authorize permissions table'
+
+ let_it_be(:file_name) { 'model.md5' }
+
+ let(:token) { tokens[:personal_access_token] }
+ let(:user_headers) { { 'HTTP_AUTHORIZATION' => token } }
+ let(:headers) { user_headers.merge(workhorse_headers) }
+ let(:params) { { file: temp_file(file_name) } }
+ let(:file_key) { :file }
+ let(:send_rewritten_field) { true }
+
+ let(:request) do
+ upload_file(headers)
+ end
+
+ describe 'success' do
+ it 'creates a new package' do
+ expect { api_response }.to change { Packages::PackageFile.count }.by(1)
+ expect(api_response).to have_gitlab_http_status(:created)
+ end
+ end
+
+ describe 'user access' do
+ where(:visibility, :user_role, :member, :token_type, :valid_token, :expected_status) do
+ authorize_permissions_table
+ end
+
+ with_them do
+ let(:token) { valid_token ? tokens[token_type] : 'invalid-token123' }
+ let(:user_headers) { user_role == :anonymous ? {} : { 'HTTP_AUTHORIZATION' => token } }
+
+ before do
+ project.update_column(:visibility_level, Gitlab::VisibilityLevel.level_value(visibility.to_s))
+ end
+
+ if params[:expected_status] == :success
+ it_behaves_like 'process ml model package upload'
+ else
+ it { is_expected.to have_gitlab_http_status(expected_status) }
+ end
+ end
+
+ it_behaves_like 'Endpoint not found if read_model_registry not available'
+ end
+ end
+
+ def authorize_upload_file(request_headers, package_name: 'mypackage', file_name: 'myfile.tar.gz')
+ url = "/projects/#{project.id}/packages/ml_models/#{package_name}/0.0.1/#{file_name}/authorize"
+
+ put api(url), headers: request_headers
+ end
+
+ def upload_file(request_headers, package_name: 'mypackage')
+ url = "/projects/#{project.id}/packages/ml_models/#{package_name}/0.0.1/#{file_name}"
+
+ workhorse_finalize(
+ api(url),
+ method: :put,
+ file_key: file_key,
+ params: params,
+ headers: request_headers,
+ send_rewritten_field: send_rewritten_field
+ )
+ end
+end
diff --git a/spec/services/merge_requests/mergeability/logger_spec.rb b/spec/services/merge_requests/mergeability/logger_spec.rb
index 1f56b6bebdb..7863b69abf6 100644
--- a/spec/services/merge_requests/mergeability/logger_spec.rb
+++ b/spec/services/merge_requests/mergeability/logger_spec.rb
@@ -40,6 +40,37 @@ RSpec.describe MergeRequests::Mergeability::Logger, :request_store, feature_cate
logger.commit
end
+ context 'when block value responds to #success?' do
+ let(:success?) { true }
+ let(:check_result) { instance_double(Gitlab::MergeRequests::Mergeability::CheckResult, success?: success?) }
+
+ let(:extra_data) do
+ {
+ 'mergeability.expensive_operation.successful.values' => [success?]
+ }
+ end
+
+ shared_examples_for 'success state logger' do
+ it 'records operation success state' do
+ expect_next_instance_of(Gitlab::AppJsonLogger) do |app_logger|
+ expect(app_logger).to receive(:info).with(match(a_hash_including(loggable_data(**extra_data))))
+ end
+
+ expect(logger.instrument(mergeability_name: :expensive_operation) { check_result }).to eq(check_result)
+
+ logger.commit
+ end
+ end
+
+ it_behaves_like 'success state logger'
+
+ context 'when not successful' do
+ let(:success?) { false }
+
+ it_behaves_like 'success state logger'
+ end
+ end
+
context 'with multiple observations' do
let(:operation_count) { 2 }
diff --git a/spec/support/shared_examples/requests/api/ml_model_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/ml_model_packages_shared_examples.rb
new file mode 100644
index 00000000000..81ff004779a
--- /dev/null
+++ b/spec/support/shared_examples/requests/api/ml_model_packages_shared_examples.rb
@@ -0,0 +1,108 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'Endpoint not found if read_model_registry not available' do
+ context 'when read_model_registry disabled for current project' do
+ before do
+ allow(Ability).to receive(:allowed?).and_call_original
+ allow(Ability).to receive(:allowed?)
+ .with(user, :read_model_registry, project)
+ .and_return(false)
+ end
+
+ it "is not found" do
+ is_expected.to have_gitlab_http_status(:not_found)
+ end
+ end
+end
+
+RSpec.shared_examples 'creates model experiments package files' do
+ it 'creates package files', :aggregate_failures do
+ expect { api_response }
+ .to change { project.packages.count }.by(1)
+ .and change { Packages::PackageFile.count }.by(1)
+ expect(api_response).to have_gitlab_http_status(:created)
+
+ package_file = project.packages.last.package_files.reload.last
+ expect(package_file.file_name).to eq(file_name)
+ end
+
+ it 'returns bad request if package creation fails' do
+ allow_next_instance_of(::Packages::MlModel::CreatePackageFileService) do |instance|
+ expect(instance).to receive(:execute).and_return(nil)
+ end
+
+ expect(api_response).to have_gitlab_http_status(:bad_request)
+ end
+
+ context 'when file is too large' do
+ it 'is bad request', :aggregate_failures do
+ allow_next_instance_of(UploadedFile) do |uploaded_file|
+ allow(uploaded_file).to receive(:size).and_return(project.actual_limits.ml_model_max_file_size + 1)
+ end
+
+ expect(api_response).to have_gitlab_http_status(:bad_request)
+ end
+ end
+end
+
+RSpec.shared_examples 'process ml model package upload' do
+ context 'with object storage disabled' do
+ before do
+ stub_package_file_object_storage(enabled: false)
+ end
+
+ context 'without a file from workhorse' do
+ let(:send_rewritten_field) { false }
+
+ it_behaves_like 'returning response status', :bad_request
+ end
+
+ context 'with correct params' do
+ it_behaves_like 'package workhorse uploads'
+ it_behaves_like 'creates model experiments package files'
+ # To be reactivated with https://gitlab.com/gitlab-org/gitlab/-/issues/414270
+ # it_behaves_like 'a package tracking event', '::API::MlModelPackages', 'push_package'
+ end
+ end
+
+ context 'with object storage enabled' do
+ let(:tmp_object) do
+ fog_connection.directories.new(key: 'packages').files.create( # rubocop:disable Rails/SaveBang
+ key: "tmp/uploads/#{file_name}",
+ body: 'content'
+ )
+ end
+
+ let(:fog_file) { fog_to_uploaded_file(tmp_object) }
+ let(:params) { { file: fog_file, 'file.remote_id' => file_name } }
+
+ context 'and direct upload enabled' do
+ let(:fog_connection) do
+ stub_package_file_object_storage(direct_upload: true)
+ end
+
+ it_behaves_like 'creates model experiments package files'
+
+ ['123123', '../../123123'].each do |remote_id|
+ context "with invalid remote_id: #{remote_id}" do
+ let(:params) do
+ {
+ file: fog_file,
+ 'file.remote_id' => remote_id
+ }
+ end
+
+ it { is_expected.to have_gitlab_http_status(:forbidden) }
+ end
+ end
+ end
+
+ context 'and direct upload disabled' do
+ let(:fog_connection) do
+ stub_package_file_object_storage(direct_upload: false)
+ end
+
+ it_behaves_like 'creates model experiments package files'
+ end
+ end
+end
diff --git a/spec/views/admin/application_settings/_ai_access.html.haml_spec.rb b/spec/views/admin/application_settings/_ai_access.html.haml_spec.rb
new file mode 100644
index 00000000000..e9e640f7cc6
--- /dev/null
+++ b/spec/views/admin/application_settings/_ai_access.html.haml_spec.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'admin/application_settings/_ai_access.html.haml', feature_category: :code_suggestions do
+ let_it_be(:admin) { build_stubbed(:admin) }
+ let(:page) { Capybara::Node::Simple.new(rendered) }
+
+ before do
+ allow(::Gitlab).to receive(:org_or_com?).and_return(false) # Will not render partial for .com or .org
+ assign(:application_setting, application_setting)
+ allow(view).to receive(:current_user) { admin }
+ allow(view).to receive(:expanded).and_return(true)
+ end
+
+ context 'when ai_access_token is not set' do
+ let(:application_setting) { build(:application_setting) }
+
+ it 'renders an empty password field' do
+ render
+ expect(rendered).to have_field('Personal access token', type: 'password')
+ expect(page.find_field('Personal access token').value).to be_blank
+ end
+ end
+
+ context 'when ai_access_token is set' do
+ let(:application_setting) do
+ build(:application_setting, ai_access_token: 'ai_access_token',
+ instance_level_code_suggestions_enabled: true)
+ end
+
+ it 'renders masked password field' do
+ render
+ expect(rendered).to have_field('Enter new personal access token', type: 'password')
+ expect(page.find_field('Enter new personal access token').value).to eq(ApplicationSettingMaskedAttrs::MASK)
+ end
+ end
+end
diff --git a/spec/views/admin/application_settings/general.html.haml_spec.rb b/spec/views/admin/application_settings/general.html.haml_spec.rb
index dd49de8f880..861f3fffa83 100644
--- a/spec/views/admin/application_settings/general.html.haml_spec.rb
+++ b/spec/views/admin/application_settings/general.html.haml_spec.rb
@@ -110,4 +110,30 @@ RSpec.describe 'admin/application_settings/general.html.haml' do
end
end
end
+
+ describe 'instance-level code suggestions settings', feature_category: :code_suggestions do
+ before do
+ allow(::Gitlab).to receive(:org_or_com?).and_return(gitlab_org_or_com?)
+
+ render
+ end
+
+ context 'when on .com or .org' do
+ let(:gitlab_org_or_com?) { true }
+
+ it 'does not render the form' do
+ expect(rendered).not_to have_field('application_setting_instance_level_code_suggestions_enabled')
+ expect(rendered).not_to have_field('application_setting_ai_access_token')
+ end
+ end
+
+ context 'when not on .com and not on .org' do
+ let(:gitlab_org_or_com?) { false }
+
+ it 'renders the form' do
+ expect(rendered).to have_field('application_setting_instance_level_code_suggestions_enabled')
+ expect(rendered).to have_field('application_setting_ai_access_token')
+ end
+ end
+ end
end
diff --git a/workhorse/internal/upstream/routes.go b/workhorse/internal/upstream/routes.go
index c5af9dc3f00..dd1725a723e 100644
--- a/workhorse/internal/upstream/routes.go
+++ b/workhorse/internal/upstream/routes.go
@@ -279,6 +279,9 @@ func configureRoutes(u *upstream) {
// Generic Packages Repository
u.route("PUT", apiProjectPattern+`/packages/generic/`, requestBodyUploader),
+ // Ml Model Packages Repository
+ u.route("PUT", apiProjectPattern+`/packages/ml_models/`, requestBodyUploader),
+
// NuGet Artifact Repository
u.route("PUT", apiProjectPattern+`/packages/nuget/`, mimeMultipartUploader),
diff --git a/workhorse/upload_test.go b/workhorse/upload_test.go
index c05af731797..8effe291979 100644
--- a/workhorse/upload_test.go
+++ b/workhorse/upload_test.go
@@ -580,6 +580,7 @@ func TestPackageFilesUpload(t *testing.T) {
{"PUT", "/api/v4/projects/group%2Fproject/packages/conan/v1/files"},
{"PUT", "/api/v4/projects/group%2Fproject/packages/maven/v1/files"},
{"PUT", "/api/v4/projects/group%2Fproject/packages/generic/mypackage/0.0.1/myfile.tar.gz"},
+ {"PUT", "/api/v4/projects/group%2Fproject/packages/ml_models/mymodel/0.0.1/myfile.tar.gz"},
{"PUT", "/api/v4/projects/group%2Fproject/packages/debian/libsample0_1.2.3~alpha2-1_amd64.deb"},
{"POST", "/api/v4/projects/group%2Fproject/packages/rubygems/api/v1/gems/sample.gem"},
{"POST", "/api/v4/projects/group%2Fproject/packages/rpm/sample-4.23.fc21.x86_64.rpm"},