-
{{ $options.i18n.MLFLOW_ID_LABEL }}:
+
{{ s__('MlModelRegistry|MLflow run ID') }}:
{{ candidate.info.eid }}
diff --git a/app/assets/javascripts/ml/model_registry/translations.js b/app/assets/javascripts/ml/model_registry/translations.js
deleted file mode 100644
index bcdec61c7f1..00000000000
--- a/app/assets/javascripts/ml/model_registry/translations.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import { __, s__, sprintf } from '~/locale';
-
-export const DESCRIPTION_LABEL = __('Description');
-export const NO_DESCRIPTION_PROVIDED_LABEL = s__('MlModelRegistry|No description provided');
-export const INFO_LABEL = s__('MlModelRegistry|Info');
-export const DETAILS_LABEL = s__('MlModelRegistry|Details & Metadata');
-export const ID_LABEL = s__('MlModelRegistry|ID');
-export const MLFLOW_ID_LABEL = s__('MlModelRegistry|MLflow run ID');
-export const STATUS_LABEL = s__('MlModelRegistry|Status');
-export const EXPERIMENT_LABEL = s__('MlModelRegistry|Experiment');
-export const ARTIFACTS_LABEL = s__('MlModelRegistry|Artifacts');
-export const NO_ARTIFACTS_MESSAGE = s__('MlModelRegistry|No logged artifacts.');
-export const PARAMETERS_LABEL = s__('MlModelRegistry|Parameters');
-export const PERFORMANCE_LABEL = s__('MlModelRegistry|Performance');
-export const METADATA_LABEL = s__('MlModelRegistry|Metadata');
-export const NO_PARAMETERS_MESSAGE = s__('MlModelRegistry|No logged parameters');
-export const NO_METRICS_MESSAGE = s__('MlModelRegistry|No logged metrics');
-export const NO_METADATA_MESSAGE = s__('MlModelRegistry|No logged metadata');
-export const NO_CI_MESSAGE = s__('MlModelRegistry|Run not linked to a CI build');
-export const CI_SECTION_LABEL = s__('MlModelRegistry|CI Info');
-export const JOB_LABEL = __('Job');
-export const CI_USER_LABEL = s__('MlModelRegistry|Triggered by');
-export const CI_MR_LABEL = __('Merge request');
-export const NEW_MODEL_LABEL = s__('MlModelRegistry|New model');
-export const CREATE_MODEL_LABEL = s__('MlModelRegistry|Create model');
-export const ERROR_CREATING_MODEL_LABEL = s__(
- 'MlModelRegistry|An error has occurred when saving the model.',
-);
-export const CREATE_MODEL_WITH_CLIENT_LABEL = s__(
- 'MlModelRegistry|Creating models is also possible through the MLflow client. %{linkStart}Follow the documentation to learn more.%{linkEnd}',
-);
-export const NAME_LABEL = __('Name');
-
-export const makeLoadVersionsErrorMessage = (message) =>
- sprintf(s__('MlModelRegistry|Failed to load model versions with error: %{message}'), {
- message,
- });
-
-export const CREATE_MODEL_LINK_TITLE = s__('MlModelRegistry|Create model');
diff --git a/app/assets/javascripts/pages/import/bitbucket_server/new/index.js b/app/assets/javascripts/pages/import/bitbucket_server/new/index.js
new file mode 100644
index 00000000000..d9e73477919
--- /dev/null
+++ b/app/assets/javascripts/pages/import/bitbucket_server/new/index.js
@@ -0,0 +1,3 @@
+import { initBitbucketServerImportProjectForm } from '~/import/bitbucket_server';
+
+initBitbucketServerImportProjectForm();
diff --git a/app/assets/javascripts/todos/components/todo_item.vue b/app/assets/javascripts/todos/components/todo_item.vue
index 9d1d8a575d8..cb7f9d647fd 100644
--- a/app/assets/javascripts/todos/components/todo_item.vue
+++ b/app/assets/javascripts/todos/components/todo_item.vue
@@ -113,7 +113,7 @@ export default {
diff --git a/app/assets/javascripts/vue_shared/directives/validation.js b/app/assets/javascripts/vue_shared/directives/validation.js
index 2aeaacc2ab1..075cda3e19c 100644
--- a/app/assets/javascripts/vue_shared/directives/validation.js
+++ b/app/assets/javascripts/vue_shared/directives/validation.js
@@ -28,7 +28,7 @@ const getFeedbackForElement = (feedbackMap, el) => {
elMessage = el.getAttribute('validation-message');
}
- return field?.message || elMessage || el.validationMessage;
+ return elMessage || field?.message || el.validationMessage;
};
const focusFirstInvalidInput = (e) => {
diff --git a/app/controllers/jwks_controller.rb b/app/controllers/jwks_controller.rb
index e4e00ecfb79..d3e195fdb63 100644
--- a/app/controllers/jwks_controller.rb
+++ b/app/controllers/jwks_controller.rb
@@ -10,15 +10,24 @@ class JwksController < Doorkeeper::OpenidConnect::DiscoveryController
private
def payload
+ load_keys.flatten.compact.uniq.map { |key_data| pem_to_jwk(key_data) }
+ end
+
+ # overridden in EE
+ def load_keys
[
- Rails.application.credentials.openid_connect_signing_key,
- Gitlab::CurrentSettings.ci_jwt_signing_key
- ].compact.map do |key_data|
- OpenSSL::PKey::RSA.new(key_data)
+ ::Rails.application.credentials.openid_connect_signing_key,
+ ::Gitlab::CurrentSettings.ci_jwt_signing_key
+ ]
+ end
+
+ def pem_to_jwk(key_data)
+ OpenSSL::PKey::RSA.new(key_data)
.public_key
.to_jwk
.slice(:kty, :kid, :e, :n)
.merge(use: 'sig', alg: 'RS256')
- end
end
end
+
+JwksController.prepend_mod
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index ee9182cd95b..1e6d3bda0c9 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -162,8 +162,6 @@ class Projects::PipelinesController < Projects::ApplicationController
@stage = pipeline.stage(params[:stage])
return not_found unless @stage
- return unless stage_stale?
-
render json: StageSerializer
.new(project: @project, current_user: @current_user)
.represent(@stage, details: true, retried: params[:retried])
@@ -270,14 +268,6 @@ class Projects::PipelinesController < Projects::ApplicationController
redirect_to url_for(safe_params.except(:scope).merge(status: safe_params[:scope])), status: :moved_permanently
end
- def stage_stale?
- return true if Feature.disabled?(:pipeline_stage_set_last_modified, @current_user)
-
- last_modified = [@stage.updated_at.utc, @stage.statuses.maximum(:updated_at)].max
-
- stale?(last_modified: last_modified, etag: @stage)
- end
-
# rubocop: disable CodeReuse/ActiveRecord
def pipeline
return @pipeline if defined?(@pipeline)
diff --git a/app/models/pages_deployment.rb b/app/models/pages_deployment.rb
index 3792a296753..82094fafee0 100644
--- a/app/models/pages_deployment.rb
+++ b/app/models/pages_deployment.rb
@@ -96,6 +96,7 @@ class PagesDeployment < ApplicationRecord
def restore
update_attribute(:deleted_at, nil)
+ deactivate_deployments_with_same_path_prefix
end
private
@@ -121,6 +122,11 @@ class PagesDeployment < ApplicationRecord
update_column(:upload_ready, true)
end
+
+ # Stop existing active deployment with same path when a deleted one is restored
+ def deactivate_deployments_with_same_path_prefix
+ project.pages_deployments.active.where.not(id: id).with_path_prefix(path_prefix).each(&:deactivate)
+ end
end
PagesDeployment.prepend_mod
diff --git a/app/views/import/bitbucket_server/new.html.haml b/app/views/import/bitbucket_server/new.html.haml
index c981c859602..19205733fa8 100644
--- a/app/views/import/bitbucket_server/new.html.haml
+++ b/app/views/import/bitbucket_server/new.html.haml
@@ -2,27 +2,33 @@
- header_title _("New project"), new_project_path
- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_project_path(anchor: 'import_project')
-= render ::Layouts::PageHeadingComponent.new('') do |c|
- - c.with_heading do
- %span.gl-inline-flex.gl-items-center.gl-gap-3
- = sprite_icon('bitbucket', size: 32)
- = _('Import repositories from Bitbucket Server')
- - c.with_description do
- = _('Enter in your Bitbucket Server URL and personal access token below')
+- if Feature.enabled?(:new_project_creation_form, @user)
+ #js-vue-import-bitbucket-server-project-root{ data: {
+ back_button_path: new_project_path(anchor: 'import_project'),
+ form_path: configure_import_bitbucket_server_path(namespace_id: params[:namespace_id])
+ } }
+- else
+ = render ::Layouts::PageHeadingComponent.new('') do |c|
+ - c.with_heading do
+ %span.gl-inline-flex.gl-items-center.gl-gap-3
+ = sprite_icon('bitbucket', size: 32)
+ = _('Import repositories from Bitbucket Server')
+ - c.with_description do
+ = _('Enter in your Bitbucket Server URL and personal access token below')
-= form_tag configure_import_bitbucket_server_path(namespace_id: params[:namespace_id]), method: :post do
- .form-group.row
- = label_tag :bitbucket_server_url, 'Bitbucket Server URL', class: 'col-form-label col-md-2'
- .col-md-4
- = text_field_tag :bitbucket_server_url, '', class: 'form-control gl-form-input gl-mr-3', placeholder: _('https://your-bitbucket-server'), size: 40
- .form-group.row
- = label_tag :bitbucket_server_url, 'Username', class: 'col-form-label col-md-2'
- .col-md-4
- = text_field_tag :bitbucket_server_username, '', class: 'form-control gl-form-input gl-mr-3', placeholder: _('username'), size: 40
- .form-group.row
- = label_tag :personal_access_token, 'Password/Personal access token', class: 'col-form-label col-md-2'
- .col-md-4
- = password_field_tag :personal_access_token, '', class: 'form-control gl-form-input gl-mr-3', placeholder: _('Personal access token'), size: 40
- .col-sm-12.gl-mt-5
- = render Pajamas::ButtonComponent.new(type: 'submit', variant: :confirm) do
- = _('List your Bitbucket Server repositories')
+ = form_tag configure_import_bitbucket_server_path(namespace_id: params[:namespace_id]), method: :post do
+ .form-group.row
+ = label_tag :bitbucket_server_url, 'Bitbucket Server URL', class: 'col-form-label col-md-2'
+ .col-md-4
+ = text_field_tag :bitbucket_server_url, '', class: 'form-control gl-form-input gl-mr-3', placeholder: _('https://your-bitbucket-server'), size: 40
+ .form-group.row
+ = label_tag :bitbucket_server_url, 'Username', class: 'col-form-label col-md-2'
+ .col-md-4
+ = text_field_tag :bitbucket_server_username, '', class: 'form-control gl-form-input gl-mr-3', placeholder: _('username'), size: 40
+ .form-group.row
+ = label_tag :personal_access_token, 'Password/Personal access token', class: 'col-form-label col-md-2'
+ .col-md-4
+ = password_field_tag :personal_access_token, '', class: 'form-control gl-form-input gl-mr-3', placeholder: _('Personal access token'), size: 40
+ .col-sm-12.gl-mt-5
+ = render Pajamas::ButtonComponent.new(type: 'submit', variant: :confirm) do
+ = _('List your Bitbucket Server repositories')
diff --git a/config/feature_flags/development/frontend_caching.yml b/config/feature_flags/development/frontend_caching.yml
index 148bb3f6062..9dc961de3c4 100644
--- a/config/feature_flags/development/frontend_caching.yml
+++ b/config/feature_flags/development/frontend_caching.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/386275
milestone: '15.7'
type: development
group: group::project management
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/pipeline_stage_set_last_modified.yml b/config/feature_flags/development/pipeline_stage_set_last_modified.yml
deleted file mode 100644
index 55790f7a447..00000000000
--- a/config/feature_flags/development/pipeline_stage_set_last_modified.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: pipeline_stage_set_last_modified
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/138499
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/433359
-milestone: '16.7'
-type: development
-group: group::global search
-default_enabled: false
diff --git a/db/docs/batched_background_migrations/backfill_evidences_project_id.yml b/db/docs/batched_background_migrations/backfill_evidences_project_id.yml
index 153f4914029..5c69d976962 100644
--- a/db/docs/batched_background_migrations/backfill_evidences_project_id.yml
+++ b/db/docs/batched_background_migrations/backfill_evidences_project_id.yml
@@ -5,4 +5,4 @@ feature_category: release_evidence
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/159580
milestone: '17.3'
queued_migration_version: 20240716133952
-finalized_by: # version of the migration that finalized this BBM
+finalized_by: '20250218231541'
diff --git a/db/post_migrate/20240214204800_drop_invalid_vulnerabilities_gdk.rb b/db/post_migrate/20240214204800_drop_invalid_vulnerabilities_gdk.rb
index 229610e94f2..824e1577707 100644
--- a/db/post_migrate/20240214204800_drop_invalid_vulnerabilities_gdk.rb
+++ b/db/post_migrate/20240214204800_drop_invalid_vulnerabilities_gdk.rb
@@ -2,7 +2,7 @@
class DropInvalidVulnerabilitiesGdk < Gitlab::Database::Migration[2.2]
disable_ddl_transaction!
- restrict_gitlab_migration gitlab_schema: :gitlab_main
+ restrict_gitlab_migration gitlab_schema: :gitlab_sec
milestone '16.10'
class Vulnerability < MigrationRecord
diff --git a/db/post_migrate/20250217164552_remove_virtual_registries_packages_maven_cache_entries_file_final_path.rb b/db/post_migrate/20250217164552_remove_virtual_registries_packages_maven_cache_entries_file_final_path.rb
new file mode 100644
index 00000000000..b79f2e5a8ef
--- /dev/null
+++ b/db/post_migrate/20250217164552_remove_virtual_registries_packages_maven_cache_entries_file_final_path.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveVirtualRegistriesPackagesMavenCacheEntriesFileFinalPath < Gitlab::Database::Migration[2.2]
+ milestone '17.10'
+ disable_ddl_transaction!
+
+ TABLE_NAME = :virtual_registries_packages_maven_cache_entries
+ COLUMN = :file_final_path
+
+ def up
+ remove_column TABLE_NAME, COLUMN
+ end
+
+ def down
+ add_column TABLE_NAME, COLUMN, :text, if_not_exists: true
+
+ add_text_limit TABLE_NAME, COLUMN, 1024
+ end
+end
diff --git a/db/post_migrate/20250218231541_finalize_hk_backfill_evidences_project_id.rb b/db/post_migrate/20250218231541_finalize_hk_backfill_evidences_project_id.rb
new file mode 100644
index 00000000000..e1603a93891
--- /dev/null
+++ b/db/post_migrate/20250218231541_finalize_hk_backfill_evidences_project_id.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+class FinalizeHkBackfillEvidencesProjectId < Gitlab::Database::Migration[2.2]
+ milestone '17.10'
+
+ disable_ddl_transaction!
+
+ restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
+
+ def up
+ ensure_batched_background_migration_is_finished(
+ job_class_name: 'BackfillEvidencesProjectId',
+ table_name: :evidences,
+ column_name: :id,
+ job_arguments: [:project_id, :releases, :project_id, :release_id],
+ finalize: true
+ )
+ end
+
+ def down; end
+end
diff --git a/db/schema_migrations/20250217164552 b/db/schema_migrations/20250217164552
new file mode 100644
index 00000000000..cf530a14813
--- /dev/null
+++ b/db/schema_migrations/20250217164552
@@ -0,0 +1 @@
+86024c9820b87fdbdef4271787ab0aa88f10d6283399a2cef507d7d2d9e268c2
\ No newline at end of file
diff --git a/db/schema_migrations/20250218231541 b/db/schema_migrations/20250218231541
new file mode 100644
index 00000000000..a0650330d0f
--- /dev/null
+++ b/db/schema_migrations/20250218231541
@@ -0,0 +1 @@
+9bda2b766d3aa46184d8e5a199a934e883e9bbc918318b8090ecbe2fb03efddb
\ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 356ce37b003..663e6af3d2b 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -6360,14 +6360,12 @@ CREATE TABLE virtual_registries_packages_maven_cache_entries (
object_storage_key text NOT NULL,
upstream_etag text,
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
- file_final_path text,
file_md5 bytea,
file_sha1 bytea NOT NULL,
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
- CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
@@ -6388,14 +6386,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
object_storage_key text NOT NULL,
upstream_etag text,
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
- file_final_path text,
file_md5 bytea,
file_sha1 bytea NOT NULL,
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
- CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
@@ -6415,14 +6411,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
object_storage_key text NOT NULL,
upstream_etag text,
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
- file_final_path text,
file_md5 bytea,
file_sha1 bytea NOT NULL,
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
- CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
@@ -6442,14 +6436,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
object_storage_key text NOT NULL,
upstream_etag text,
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
- file_final_path text,
file_md5 bytea,
file_sha1 bytea NOT NULL,
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
- CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
@@ -6469,14 +6461,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
object_storage_key text NOT NULL,
upstream_etag text,
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
- file_final_path text,
file_md5 bytea,
file_sha1 bytea NOT NULL,
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
- CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
@@ -6496,14 +6486,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
object_storage_key text NOT NULL,
upstream_etag text,
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
- file_final_path text,
file_md5 bytea,
file_sha1 bytea NOT NULL,
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
- CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
@@ -6523,14 +6511,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
object_storage_key text NOT NULL,
upstream_etag text,
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
- file_final_path text,
file_md5 bytea,
file_sha1 bytea NOT NULL,
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
- CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
@@ -6550,14 +6536,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
object_storage_key text NOT NULL,
upstream_etag text,
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
- file_final_path text,
file_md5 bytea,
file_sha1 bytea NOT NULL,
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
- CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
@@ -6577,14 +6561,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
object_storage_key text NOT NULL,
upstream_etag text,
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
- file_final_path text,
file_md5 bytea,
file_sha1 bytea NOT NULL,
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
- CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
@@ -6604,14 +6586,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
object_storage_key text NOT NULL,
upstream_etag text,
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
- file_final_path text,
file_md5 bytea,
file_sha1 bytea NOT NULL,
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
- CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
@@ -6631,14 +6611,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
object_storage_key text NOT NULL,
upstream_etag text,
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
- file_final_path text,
file_md5 bytea,
file_sha1 bytea NOT NULL,
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
- CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
@@ -6658,14 +6636,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
object_storage_key text NOT NULL,
upstream_etag text,
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
- file_final_path text,
file_md5 bytea,
file_sha1 bytea NOT NULL,
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
- CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
@@ -6685,14 +6661,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
object_storage_key text NOT NULL,
upstream_etag text,
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
- file_final_path text,
file_md5 bytea,
file_sha1 bytea NOT NULL,
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
- CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
@@ -6712,14 +6686,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
object_storage_key text NOT NULL,
upstream_etag text,
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
- file_final_path text,
file_md5 bytea,
file_sha1 bytea NOT NULL,
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
- CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
@@ -6739,14 +6711,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
object_storage_key text NOT NULL,
upstream_etag text,
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
- file_final_path text,
file_md5 bytea,
file_sha1 bytea NOT NULL,
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
- CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
@@ -6766,14 +6736,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
object_storage_key text NOT NULL,
upstream_etag text,
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
- file_final_path text,
file_md5 bytea,
file_sha1 bytea NOT NULL,
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
- CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
@@ -6793,14 +6761,12 @@ CREATE TABLE gitlab_partitions_static.virtual_registries_packages_maven_cache_en
object_storage_key text NOT NULL,
upstream_etag text,
content_type text DEFAULT 'application/octet-stream'::text NOT NULL,
- file_final_path text,
file_md5 bytea,
file_sha1 bytea NOT NULL,
CONSTRAINT check_215f531366 CHECK ((char_length(content_type) <= 255)),
CONSTRAINT check_2a52b4e0fc CHECK ((char_length(file) <= 1024)),
CONSTRAINT check_36391449ea CHECK ((char_length(object_storage_key) <= 1024)),
CONSTRAINT check_45d3174f8a CHECK ((char_length(relative_path) <= 1024)),
- CONSTRAINT check_c9d6e475d9 CHECK ((char_length(file_final_path) <= 1024)),
CONSTRAINT check_cc222855d6 CHECK (((file_md5 IS NULL) OR (octet_length(file_md5) = 16))),
CONSTRAINT check_f2ea43b900 CHECK ((octet_length(file_sha1) = 20)),
CONSTRAINT check_fd9fc90696 CHECK ((char_length(upstream_etag) <= 255))
diff --git a/doc/user/analytics/dora_metrics.md b/doc/user/analytics/dora_metrics.md
index e1d7408c9c8..bc96975a5e0 100644
--- a/doc/user/analytics/dora_metrics.md
+++ b/doc/user/analytics/dora_metrics.md
@@ -246,7 +246,7 @@ and use it to automatically:
DORA metrics are displayed in the following analytics features:
-- [Value Streams Dashboard](value_streams_dashboard.md) includes the [DORA metrics comparison panel](value_streams_dashboard.md#devsecops-metrics-comparison-panels) and [DORA Performers score panel](value_streams_dashboard.md#dora-performers-score-panel).
+- [Value Streams Dashboard](value_streams_dashboard.md) includes the [DORA metrics comparison panel](value_streams_dashboard.md#devsecops-metrics-comparison) and [DORA Performers score panel](value_streams_dashboard.md#dora-performers-score).
- [CI/CD analytics charts](ci_cd_analytics.md) show the history of DORA metrics over time.
- [Insights reports](../project/insights/_index.md) provide the option to create custom charts with [DORA query parameters](../project/insights/_index.md#dora-query-parameters).
- [GraphQL API](../../api/graphql/reference/_index.md) (with the interactive [GraphQL explorer](../../api/graphql/_index.md#interactive-graphql-explorer)) and [REST API](../../api/dora/metrics.md) support the retrieval of metrics data.
diff --git a/doc/user/analytics/value_streams_dashboard.md b/doc/user/analytics/value_streams_dashboard.md
index 12b8ef5adf1..b0c06178c90 100644
--- a/doc/user/analytics/value_streams_dashboard.md
+++ b/doc/user/analytics/value_streams_dashboard.md
@@ -25,7 +25,7 @@ For more information, see the [Value Stream Management category direction page](
The Value Streams Dashboard is a customizable dashboard you can use to identify trends, patterns, and opportunities for digital transformation improvements.
The centralized UI in the Value Streams Dashboard acts as the single source of truth (SSOT), where all stakeholders can access and view the same set of metrics that are relevant to the organization.
-The Value Streams Dashboard includes [panels](#value-streams-dashboard-panels) that visualize the following metrics:
+The Value Streams Dashboard includes panels that visualize the following metrics:
- [DORA metrics](dora_metrics.md)
- [Value Stream Analytics (VSA) - flow metrics](../group/value_stream_analytics/_index.md)
@@ -55,11 +55,11 @@ If you upgrade to the Ultimate tier, you get access to historical data, and can
{{< /alert >}}
-## Value Streams Dashboard panels
+## Panels
-The Value Streams Dashboard panels have a default configuration, but you can also [customize the dashboard panels](#customize-the-dashboard-panels).
+The Value Streams Dashboard panels have a default configuration, but you can also [customize the dashboard panels](#customize-dashboard-panels).
-### Overview panel
+### Overview
{{< history >}}
@@ -90,7 +90,7 @@ To view metrics on the Overview panel, the [background aggregation](#enable-or-d
{{< /alert >}}
-### DevSecOps metrics comparison panels
+### DevSecOps metrics comparison
{{< history >}}
@@ -120,7 +120,7 @@ The sparkline for the past six months represents value trends over this time per
The sparkline color ranges from blue to green, where green indicates a positive trend, and blue indicates a negative trend.
Sparklines help you identify patterns in metric trends (such as seasonal changes) over time.
-#### Filter a DevSecOps metrics comparison panel by labels
+#### Filter panels by label
Label filters are appended as query parameters to the URL of the drill-down report of each eligible metric and automatically applied.
If a comparison panel from the configuration file is enabled with `filters.labels`, the drill-down links inherit the labels from the panel filter.
@@ -143,7 +143,7 @@ Only labels that exactly match the specified filters are applied.
{{< /alert >}}
-### DORA Performers score panel
+### DORA Performers score
{{< history >}}
@@ -175,7 +175,7 @@ For example, if a project has a high score for deployment frequency (velocity),
To learn more, see the blog post [Inside DORA Performers score in GitLab Value Streams Dashboard](https://about.gitlab.com/blog/2024/01/18/inside-dora-performers-score-in-gitlab-value-streams-dashboard/).
-#### Filter the DORA Performers score by project topics
+#### Filter the panel by project topic
When you customize dashboards with a YAML configuration,
you can filter the displayed projects by assigned [topics](../project/project_topics.md).
@@ -240,13 +240,15 @@ To retrieve aggregated usage counts in the group, use the [GraphQL API](../../ap
## View the Value Streams Dashboard
+### For groups
+
Prerequisites:
- You must have at least the Reporter role for the group.
- Overview background aggregation for Value Streams Dashboards must be enabled.
- To view the contributor count metric in the comparison panel, you must [set up ClickHouse](../../integration/clickhouse.md).
-To view the Value Streams Dashboard:
+To view the Value Streams Dashboard for a group:
- From Analytics Dashboards:
@@ -260,7 +262,7 @@ To view the Value Streams Dashboard:
1. Below the **Filter results** text box, in the **Lifecycle metrics** row, select **Value Streams Dashboard / DORA**.
1. Optional. To open the new page, append this path `/analytics/dashboards/value_streams_dashboard` to the group URL (for example, `https://gitlab.com/groups/gitlab-org/-/analytics/dashboards/value_streams_dashboard`).
-### View the Value Streams Dashboard for a project
+### For projects
{{< history >}}
@@ -280,7 +282,7 @@ To view the Value Streams Dashboard as an analytics dashboard for a project:
1. Select **Analyze > Analytics dashboards**.
1. From the list of available dashboards, select **Value Streams Dashboard**.
-### Schedule Value Streams Dashboard reports
+## Schedule reports
You can schedule reports using the CI/CD component
[Value Streams Dashboard Scheduled Reports tool](https://gitlab.com/components/vsd-reports-generator).
@@ -294,7 +296,7 @@ The issue includes a comparison metrics table in Markdown format.
See an [example scheduled report](https://gitlab.com/components/vsd-reports-generator#example-for-monthly-executive-value-streams-report). To learn more, see the blog post [New Scheduled Reports Generation tool simplifies value stream management](https://about.gitlab.com/blog/2024/06/20/new-scheduled-reports-generation-tool-simplifies-value-stream-management/).
-## Customize the dashboard panels
+## Customize dashboard panels
You can customize the Value Streams Dashboard and configure what subgroups and projects to include in the page.
@@ -460,7 +462,7 @@ Filters for the `usage_overview` visualization.
| Critical vulnerabilities over time | Critical vulnerabilities over time in project or group | [Vulnerability report](https://gitlab.com/gitlab-org/gitlab/-/security/vulnerability_report) | [Vulnerability report](../application_security/vulnerability_report/_index.md) | `vulnerability_critical` |
| High vulnerabilities over time | High vulnerabilities over time in project or group | [Vulnerability report](https://gitlab.com/gitlab-org/gitlab/-/security/vulnerability_report) | [Vulnerability report](../application_security/vulnerability_report/_index.md) | `vulnerability_high` |
-## Value Streams Dashboard metrics with Jira
+## Metrics with Jira
The following metrics do not depend on using Jira:
diff --git a/doc/user/application_security/policies/pipeline_execution_policies.md b/doc/user/application_security/policies/pipeline_execution_policies.md
index a8d96d28234..ad55bd694b4 100644
--- a/doc/user/application_security/policies/pipeline_execution_policies.md
+++ b/doc/user/application_security/policies/pipeline_execution_policies.md
@@ -28,7 +28,7 @@ Use Pipeline execution policies to enforce CI/CD jobs for all applicable project
{{< history >}}
- [Enabled](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/159858) the `suffix` field in GitLab 17.4.
-- [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/165096) pipeline execution so later stages wait for the `.pipeline-policy-pre` stage to complete in GitLab 17.7. [with a flag](../../../administration/feature_flags.md) named `ensure_pipeline_policy_pre_stage_complete`. Disabled by default.
+- [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/165096) pipeline execution so later stages wait for the `.pipeline-policy-pre` stage to complete in GitLab 17.7. [with a flag](../../../administration/feature_flags.md) named `ensure_pipeline_policy_pre_stage_complete`. Enabled by default.
{{< /history >}}
@@ -401,7 +401,8 @@ the only jobs that run are the pipeline execution policy jobs.
{{< history >}}
-- Updated handling of workflow rules [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/175088) in GitLab 17.8 [with a flag](../../../administration/feature_flags.md) named `policies_always_override_project_ci`. Enabled by default.
+- Updated handling of workflow rules [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/175088) in GitLab 17.8 [with a flag](../../../administration/feature_flags.md) named `policies_always_override_project_ci`. Enabled by default.
+- Updated handling of workflow rules [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/512877) in GitLab 17.10. Feature flag `policies_always_override_project_ci` removed.
{{< /history >}}
@@ -504,14 +505,9 @@ ProjectVariablesYAML -- "Basis of the resulting pipeline" --> ResultingProjectVa
{{< alert type="note" >}}
-When a pipeline execution policy uses workflow rules that prevent policy jobs from running, the
-project's original CI/CD configuration remains in effect instead of being overridden. You can
-conditionally apply pipeline execution policies to control when the policy impacts the project's
-CI/CD configuration. For example, if you set a workflow rule `if: $CI_PIPELINE_SOURCE ==
-"merge_request_event"`, the project's CI/CD configuration is only overridden when the pipeline source
-is a merge request event. However, if the feature flag `policies_always_override_project_ci` is enabled,
-the workflow rules in the pipeline execution policy also override the project's original CI/CD configuration.
-As a result, if workflow rules cause the pipeline execution policy to be filtered out, no pipeline is created.
+The workflow rules in the pipeline execution policy override the project's original CI/CD configuration.
+By defining workflow rules in the policy, you can set rules that are enforced across all linked projects,
+like preventing the use of branch pipelines.
{{< /alert >}}
diff --git a/doc/user/project/import/_index.md b/doc/user/project/import/_index.md
index 8b56af5cbfd..8f6d1ed941d 100644
--- a/doc/user/project/import/_index.md
+++ b/doc/user/project/import/_index.md
@@ -228,8 +228,7 @@ Placeholder users are created per [import source](#supported-import-sources) and
- If you import the same project twice, but to a different top-level group on the destination instance, the second import
creates new placeholder users under that top-level group.
-If importing to GitLab.com, placeholder users are limited per top-level group on the destination instance. The limits
-differ depending on your plan and seat count. Placeholder users do not count towards license limits.
+If importing to GitLab.com, placeholder users are limited per top-level group on the destination instance. The limits differ depending on your plan and seat count. Placeholder users do not count towards license limits.
| GitLab.com plan | Number of seats | Placeholder user limit on top-level group |
|:-------------------------|:----------------|:------------------------------------------|
@@ -245,10 +244,29 @@ differ depending on your plan and seat count. Placeholder users do not count tow
Customers on legacy Bronze, Silver, or Gold plans have the corresponding Free, Premium, or Ultimate limits.
For Premium customers trying out Ultimate (Ultimate trial paid customer plan), Premium limits apply.
-
If these limits are not sufficient for your import, [contact GitLab Support](https://about.gitlab.com/support/).
-The above limits are for GitLab.com. GitLab Self-Managed has no placeholder limits by default. A self-managed instance administrator can [set a placeholder limit](../../../administration/instance_limits.md#import-placeholder-user-limits) for their installation.
+For GitLab Self-Managed and GitLab Dedicated, no placeholder limits apply by default.
+A GitLab administrator can [set a placeholder limit](../../../administration/instance_limits.md#import-placeholder-user-limits) on their instance.
+
+For imports to GitLab.com, some contributions might not be created
+because these contributions are mapped to the same user.
+For example, if multiple merge request approvers are mapped to the same user,
+only the first approval is added and the others are ignored.
+These contributions include:
+
+- Memberships
+- Merge request approvals, assignees, and reviewers
+- Issue assignees
+- Emoji
+- Push, merge request, and deploy access levels
+- Approval rules
+
+You cannot determine the number of placeholder users you need in advance.
+When the placeholder user limit is reached, the import does not fail.
+Instead, all contributions are assigned to a bot user called `Import User`.
+
+Every change creates a system note, which is not affected by the placeholder user limit.
### Reassign contributions and memberships
diff --git a/lib/api/usage_data.rb b/lib/api/usage_data.rb
index 1326200d35d..81892b2b784 100644
--- a/lib/api/usage_data.rb
+++ b/lib/api/usage_data.rb
@@ -35,7 +35,8 @@ module API
send_snowplow_event = !!params[:send_to_snowplow]
if Gitlab::Tracking::AiTracking::EVENTS_MIGRATED_TO_INSTRUMENTATION_LAYER.exclude?(event_name)
- Gitlab::Tracking::AiTracking.track_event(event_name, **additional_properties.merge(user: current_user))
+ Gitlab::Tracking::AiTracking.track_event(event_name,
+**additional_properties.merge(user: current_user, project_id: project_id, namespace_id: namespace_id))
end
track_event(
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 0d8faf5e668..adc44cf890c 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -6993,9 +6993,14 @@ msgstr ""
msgid "Analytics|Data table"
msgstr ""
-msgid "Analytics|Dates and times are displayed in the UTC timezone"
+msgid "Analytics|Dates and times are displayed in the UTC timezone."
msgstr ""
+msgid "Analytics|Dates and times are displayed in the UTC timezone. Date range is limited to %d day."
+msgid_plural "Analytics|Dates and times are displayed in the UTC timezone. Date range is limited to %d days."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Analytics|Default date range '%{defaultOption}' is not included in the list of dateRange options"
msgstr ""
@@ -19099,11 +19104,6 @@ msgstr ""
msgid "Date range filter validation"
msgstr ""
-msgid "Date range limited to %d day"
-msgid_plural "Date range limited to %d days"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Date range limited to %{number} days"
msgstr ""
@@ -36674,9 +36674,6 @@ msgstr ""
msgid "MlModelRegistry|All artifact uploads failed or were canceled."
msgstr ""
-msgid "MlModelRegistry|An error has occurred when saving the model."
-msgstr ""
-
msgid "MlModelRegistry|Are you sure you want to delete this model version?"
msgstr ""
@@ -36737,9 +36734,6 @@ msgstr ""
msgid "MlModelRegistry|Creating a model version"
msgstr ""
-msgid "MlModelRegistry|Creating models is also possible through the MLflow client. %{linkStart}Follow the documentation to learn more.%{linkEnd}"
-msgstr ""
-
msgid "MlModelRegistry|Creating models, model versions and runs is also possible using the MLflow client:"
msgstr ""
@@ -36815,6 +36809,9 @@ msgstr ""
msgid "MlModelRegistry|Failed to load model runs with error: %{message}"
msgstr ""
+msgid "MlModelRegistry|Failed to load model version with error: %{message}"
+msgstr ""
+
msgid "MlModelRegistry|Failed to load model versions with error: %{message}"
msgstr ""
@@ -36830,18 +36827,12 @@ msgstr ""
msgid "MlModelRegistry|For example 1.0.0"
msgstr ""
-msgid "MlModelRegistry|ID"
-msgstr ""
-
msgid "MlModelRegistry|Import model using MLflow"
msgstr ""
msgid "MlModelRegistry|Import your machine learning models"
msgstr ""
-msgid "MlModelRegistry|Info"
-msgstr ""
-
msgid "MlModelRegistry|Latest version"
msgstr ""
@@ -36899,9 +36890,6 @@ msgstr ""
msgid "MlModelRegistry|Must be unique. May not contain spaces."
msgstr ""
-msgid "MlModelRegistry|New model"
-msgstr ""
-
msgid "MlModelRegistry|New version"
msgstr ""
@@ -36911,9 +36899,6 @@ msgstr ""
msgid "MlModelRegistry|No description available. To add a description, click \"Edit model\" above."
msgstr ""
-msgid "MlModelRegistry|No description provided"
-msgstr ""
-
msgid "MlModelRegistry|No logged artifacts."
msgstr ""
@@ -36977,9 +36962,6 @@ msgstr ""
msgid "MlModelRegistry|Something went wrong while trying to delete the model version. Please try again later."
msgstr ""
-msgid "MlModelRegistry|Status"
-msgstr ""
-
msgid "MlModelRegistry|Step %{step}"
msgstr ""
@@ -46117,6 +46099,9 @@ msgstr ""
msgid "ProjectsNew|Available only for projects within groups"
msgstr ""
+msgid "ProjectsNew|Bitbucket Server URL"
+msgstr ""
+
msgid "ProjectsNew|Choose a group"
msgstr ""
@@ -46186,6 +46171,9 @@ msgstr ""
msgid "ProjectsNew|Import projects from Gitea"
msgstr ""
+msgid "ProjectsNew|Import repositories from Bitbucket Server"
+msgstr ""
+
msgid "ProjectsNew|Include a Getting Started README"
msgstr ""
@@ -46216,12 +46204,18 @@ msgstr ""
msgid "ProjectsNew|No import options available"
msgstr ""
+msgid "ProjectsNew|Password/Personal access token"
+msgstr ""
+
msgid "ProjectsNew|Pick a group or namespace"
msgstr ""
msgid "ProjectsNew|Pick a group or namespace where you want to create this project."
msgstr ""
+msgid "ProjectsNew|Please enter a valid Bitbucket Server URL."
+msgstr ""
+
msgid "ProjectsNew|Please enter a valid Gitea host URL."
msgstr ""
@@ -46234,6 +46228,12 @@ msgstr ""
msgid "ProjectsNew|Please enter a valid project slug."
msgstr ""
+msgid "ProjectsNew|Please enter a valid token."
+msgstr ""
+
+msgid "ProjectsNew|Please enter a valid username."
+msgstr ""
+
msgid "ProjectsNew|Please upload a valid GitLab project export file."
msgstr ""
@@ -53124,6 +53124,9 @@ msgstr ""
msgid "SecurityReports|Attach to new issue"
msgstr ""
+msgid "SecurityReports|Auto-resolve vulnerabilities that are no longer detected"
+msgstr ""
+
msgid "SecurityReports|CVSS v%{version}:"
msgstr ""
@@ -53253,6 +53256,9 @@ msgstr ""
msgid "SecurityReports|GitLab Duo (AI)"
msgstr ""
+msgid "SecurityReports|Go to policies"
+msgstr ""
+
msgid "SecurityReports|Group your vulnerabilities by one of the provided categories. Leave feedback or suggestions in %{feedbackIssueStart}this issue%{feedbackIssueEnd}."
msgstr ""
@@ -53477,6 +53483,9 @@ msgstr ""
msgid "SecurityReports|This selection is required."
msgstr ""
+msgid "SecurityReports|To automatically resolve vulnerabilities when they are no longer detected by automated scanning, use the new auto-resolve option in your vulnerability management policies. From the %{boldStart}Policies%{boldEnd} page, configure a policy by applying the %{boldStart}Auto-resolve%{boldEnd} option and make sure the policy is linked to the appropriate projects. You can also configure the policy to auto-resolve only the vulnerabilities of a specific severity or from specific security scanners. See the %{linkStart}release post%{linkEnd} for details."
+msgstr ""
+
msgid "SecurityReports|To widen your search, change or remove filters above"
msgstr ""
diff --git a/spec/controllers/import/bitbucket_server_controller_spec.rb b/spec/controllers/import/bitbucket_server_controller_spec.rb
index 777c1ccdbf5..010fcd770d5 100644
--- a/spec/controllers/import/bitbucket_server_controller_spec.rb
+++ b/spec/controllers/import/bitbucket_server_controller_spec.rb
@@ -17,6 +17,7 @@ RSpec.describe Import::BitbucketServerController, feature_category: :importers d
end
before do
+ stub_feature_flags(new_project_creation_form: false)
sign_in(user)
stub_application_setting(import_sources: ['bitbucket_server'])
end
diff --git a/spec/frontend/import/bitbucket_server/import_from_bitbucket_server_app_spec.js b/spec/frontend/import/bitbucket_server/import_from_bitbucket_server_app_spec.js
new file mode 100644
index 00000000000..105ff19a9ed
--- /dev/null
+++ b/spec/frontend/import/bitbucket_server/import_from_bitbucket_server_app_spec.js
@@ -0,0 +1,117 @@
+import { nextTick } from 'vue';
+import { GlFormInput } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import importFromBitbucketServerApp from '~/import/bitbucket_server/import_from_bitbucket_server_app.vue';
+import MultiStepFormTemplate from '~/vue_shared/components/multi_step_form_template.vue';
+
+jest.mock('~/lib/utils/csrf', () => ({ token: 'mock-csrf-token' }));
+
+describe('Import from Bitbucket Server app', () => {
+ let wrapper;
+
+ const createComponent = () => {
+ wrapper = shallowMountExtended(importFromBitbucketServerApp, {
+ propsData: {
+ backButtonPath: '/projects/new#import_project',
+ formPath: '/import/bitbucket_server/configure',
+ },
+ stubs: {
+ GlFormInput,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ const findMultiStepForm = () => wrapper.findComponent(MultiStepFormTemplate);
+ const findForm = () => wrapper.find('form');
+ const findUrlInput = () => wrapper.findByTestId('url-input');
+ const findUsernameInput = () => wrapper.findByTestId('username-input');
+ const findTokenInput = () => wrapper.findByTestId('token-input');
+ const findBackButton = () => wrapper.findByTestId('back-button');
+ const findNextButton = () => wrapper.findByTestId('next-button');
+
+ describe('form', () => {
+ it('renders the multi step form correctly', () => {
+ expect(findMultiStepForm().props()).toMatchObject({
+ currentStep: 3,
+ stepsTotal: 4,
+ });
+ });
+
+ it('renders the form element correctly', () => {
+ const form = findForm();
+
+ expect(form.attributes('action')).toBe('/import/bitbucket_server/configure');
+ expect(form.find('input[type=hidden][name=authenticity_token]').attributes('value')).toBe(
+ 'mock-csrf-token',
+ );
+ });
+
+ it('does not submit the form without required fields', () => {
+ const submitSpy = jest.spyOn(findForm().element, 'submit');
+
+ findForm().trigger('submit');
+ expect(submitSpy).not.toHaveBeenCalled();
+ });
+
+ it('submits the form with valid form data', async () => {
+ const submitSpy = jest.spyOn(findForm().element, 'submit');
+
+ await findUrlInput().setValue('https://your-bitbucket-server');
+ await findUsernameInput().setValue('username');
+ await findTokenInput().setValue('863638293ddkdl29');
+ await nextTick();
+
+ findForm().trigger('submit');
+ expect(submitSpy).toHaveBeenCalledWith();
+ });
+ });
+
+ describe('validation', () => {
+ it('shows an error message when url is cleared', async () => {
+ findUrlInput().setValue('');
+ findUrlInput().trigger('blur');
+ await nextTick();
+
+ const formGroup = wrapper.findByTestId('url-group');
+ expect(formGroup.attributes('invalid-feedback')).toBe(
+ 'Please enter a valid Bitbucket Server URL.',
+ );
+ });
+
+ it('shows an error message when username is cleared', async () => {
+ findUsernameInput().setValue('');
+ findUsernameInput().trigger('blur');
+ await nextTick();
+
+ const formGroup = wrapper.findByTestId('username-group');
+ expect(formGroup.attributes('invalid-feedback')).toBe('Please enter a valid username.');
+ });
+
+ it('shows an error message when token is cleared', async () => {
+ findTokenInput().setValue('');
+ findTokenInput().trigger('blur');
+ await nextTick();
+
+ const formGroup = wrapper.findByTestId('token-group');
+ expect(formGroup.attributes('invalid-feedback')).toBe('Please enter a valid token.');
+ });
+ });
+
+ describe('back button', () => {
+ it('renders a back button', () => {
+ expect(findBackButton().exists()).toBe(true);
+ expect(findBackButton().attributes('href')).toBe('/projects/new#import_project');
+ });
+ });
+
+ describe('next button', () => {
+ it('renders a button', () => {
+ expect(findNextButton().exists()).toBe(true);
+ expect(findNextButton().attributes('type')).toBe('submit');
+ });
+ });
+});
diff --git a/spec/frontend/ml/model_registry/apps/show_ml_model_version_spec.js b/spec/frontend/ml/model_registry/apps/show_ml_model_version_spec.js
index 45356d8c0bc..ed888b0eb31 100644
--- a/spec/frontend/ml/model_registry/apps/show_ml_model_version_spec.js
+++ b/spec/frontend/ml/model_registry/apps/show_ml_model_version_spec.js
@@ -292,7 +292,7 @@ describe('ml/model_registry/apps/show_model_version.vue', () => {
await waitForPromises();
expect(findLoadOrErrorOrShow().props('errorMessage')).toBe(
- 'Failed to load model versions with error: Failure!',
+ 'Failed to load model version with error: Failure!',
);
expect(Sentry.captureException).toHaveBeenCalled();
});
diff --git a/spec/frontend/ml/model_registry/components/candidate_detail_spec.js b/spec/frontend/ml/model_registry/components/candidate_detail_spec.js
index eaffc169c8c..671ab23903b 100644
--- a/spec/frontend/ml/model_registry/components/candidate_detail_spec.js
+++ b/spec/frontend/ml/model_registry/components/candidate_detail_spec.js
@@ -2,12 +2,6 @@ import { GlAvatarLabeled, GlLink, GlTableLite } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import CandidateDetail from '~/ml/model_registry/components/candidate_detail.vue';
import DetailRow from '~/ml/model_registry/components/candidate_detail_row.vue';
-import {
- NO_PARAMETERS_MESSAGE,
- NO_METRICS_MESSAGE,
- NO_METADATA_MESSAGE,
- NO_CI_MESSAGE,
-} from '~/ml/model_registry/translations';
import { stubComponent } from 'helpers/stub_component';
import { newCandidate } from '../mock_data';
@@ -139,19 +133,19 @@ describe('ml/model_registry/components/candidate_detail.vue', () => {
);
it('does not render params', () => {
- expect(findNoDataMessage(NO_PARAMETERS_MESSAGE).exists()).toBe(true);
+ expect(findNoDataMessage('No logged parameters').exists()).toBe(true);
});
it('does not render metadata', () => {
- expect(findNoDataMessage(NO_METADATA_MESSAGE).exists()).toBe(true);
+ expect(findNoDataMessage('No logged metadata').exists()).toBe(true);
});
it('does not render metrics', () => {
- expect(findNoDataMessage(NO_METRICS_MESSAGE).exists()).toBe(true);
+ expect(findNoDataMessage('No logged metrics').exists()).toBe(true);
});
it('does not render CI info', () => {
- expect(findNoDataMessage(NO_CI_MESSAGE).exists()).toBe(true);
+ expect(findNoDataMessage('Run not linked to a CI build').exists()).toBe(true);
});
});
diff --git a/spec/frontend/vue_shared/directives/validation_spec.js b/spec/frontend/vue_shared/directives/validation_spec.js
index 72a348c1a79..80fb673d11d 100644
--- a/spec/frontend/vue_shared/directives/validation_spec.js
+++ b/spec/frontend/vue_shared/directives/validation_spec.js
@@ -280,6 +280,7 @@ describe('validation directive', () => {
const feedbackMap = {
valueMissing: {
isInvalid: (el) => el.validity?.valueMissing,
+ feedback: 'Please fill out the name field.',
},
};
diff --git a/spec/lib/gitlab/background_migration/backfill_archived_and_traversal_ids_to_vulnerability_statistics_spec.rb b/spec/lib/gitlab/background_migration/backfill_archived_and_traversal_ids_to_vulnerability_statistics_spec.rb
index bc148786438..8bef2cc07df 100644
--- a/spec/lib/gitlab/background_migration/backfill_archived_and_traversal_ids_to_vulnerability_statistics_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_archived_and_traversal_ids_to_vulnerability_statistics_spec.rb
@@ -3,6 +3,13 @@
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillArchivedAndTraversalIdsToVulnerabilityStatistics, migration: :gitlab_sec, feature_category: :vulnerability_management do
+ before(:all) do
+ # Some spec in this file currently fails when a sec database is configured. We plan to ensure it all functions
+ # and passes prior to the sec db rollout.
+ # Consult https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180764 for more info.
+ skip_if_multiple_databases_are_setup(:sec)
+ end
+
let(:organizations) { table(:organizations) }
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
diff --git a/spec/lib/gitlab/background_migration/backfill_detected_at_from_created_at_column_spec.rb b/spec/lib/gitlab/background_migration/backfill_detected_at_from_created_at_column_spec.rb
index e7ff190bfb0..ab1296a8aae 100644
--- a/spec/lib/gitlab/background_migration/backfill_detected_at_from_created_at_column_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_detected_at_from_created_at_column_spec.rb
@@ -122,6 +122,13 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillDetectedAtFromCreatedAtColum
)
end
+ before(:all) do
+ # This test shares the db connection to establish it's fixtures, resulting in
+ # incorrect connection usage, so we're skipping it.
+ # Consult https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180764 for more info.
+ skip_if_multiple_databases_are_setup(:sec)
+ end
+
before do
# detected_at default value is NOW(), so update it to NULL
vulnerability_without_detected_at.update_column :detected_at, nil
diff --git a/spec/lib/gitlab/background_migration/backfill_missing_namespace_id_on_notes_spec.rb b/spec/lib/gitlab/background_migration/backfill_missing_namespace_id_on_notes_spec.rb
index 11f0aa31197..ef7116551b2 100644
--- a/spec/lib/gitlab/background_migration/backfill_missing_namespace_id_on_notes_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_missing_namespace_id_on_notes_spec.rb
@@ -46,6 +46,13 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillMissingNamespaceIdOnNotes, f
let!(:user_1) { users_table.create!(name: 'bob', email: 'bob@example.com', projects_limit: 1) }
+ before do
+ # This test shares the db connection to establish it's fixtures, resulting in
+ # incorrect connection usage, so we're skipping it.
+ # Consult https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180764 for more info.
+ skip_if_multiple_databases_are_setup(:sec)
+ end
+
context "when namespace_id is derived from note.project_id" do
let(:alert_management_alert_note) do
notes_table.create!(project_id: project_1.id, noteable_type: "AlertManagement::Alert")
diff --git a/spec/lib/gitlab/background_migration/backfill_project_id_to_dependency_list_exports_spec.rb b/spec/lib/gitlab/background_migration/backfill_project_id_to_dependency_list_exports_spec.rb
index d3eac3b5b40..9987aa5989d 100644
--- a/spec/lib/gitlab/background_migration/backfill_project_id_to_dependency_list_exports_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_project_id_to_dependency_list_exports_spec.rb
@@ -27,6 +27,13 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillProjectIdToDependencyListExp
subject(:perform_migration) { described_class.new(**args).perform }
+ before do
+ # This test shares the db connection to establish it's fixtures, resulting in
+ # incorrect connection usage, so we're skipping it.
+ # Consult https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180764 for more info.
+ skip_if_multiple_databases_are_setup(:sec)
+ end
+
context 'when export is missing project_id' do
let!(:export) { dependency_list_exports.create!(pipeline_id: pipeline.id) }
let!(:other_pipeline) { create_ci_pipeline('pipeline-2') }
diff --git a/spec/lib/gitlab/background_migration/backfill_project_id_to_security_scans_spec.rb b/spec/lib/gitlab/background_migration/backfill_project_id_to_security_scans_spec.rb
index 9f03c5231ef..927c079b969 100644
--- a/spec/lib/gitlab/background_migration/backfill_project_id_to_security_scans_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_project_id_to_security_scans_spec.rb
@@ -27,6 +27,13 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillProjectIdToSecurityScans, fe
subject(:perform_migration) { described_class.new(**args).perform }
+ before do
+ # This test shares the db connection to establish it's fixtures, resulting in
+ # incorrect connection usage, so we're skipping it.
+ # Consult https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180764 for more info.
+ skip_if_multiple_databases_are_setup(:sec)
+ end
+
context 'when security_scan.build_id does not exist' do
let!(:scan) do
security_scans.create!(
diff --git a/spec/lib/gitlab/background_migration/backfill_vulnerability_external_issue_links_project_id_spec.rb b/spec/lib/gitlab/background_migration/backfill_vulnerability_external_issue_links_project_id_spec.rb
index dcc30811c10..12c9b93601b 100644
--- a/spec/lib/gitlab/background_migration/backfill_vulnerability_external_issue_links_project_id_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_vulnerability_external_issue_links_project_id_spec.rb
@@ -5,6 +5,13 @@ require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillVulnerabilityExternalIssueLinksProjectId,
feature_category: :vulnerability_management,
schema: 20240624135059 do
+ before do
+ # This test shares the db connection to establish it's fixtures, resulting in
+ # incorrect connection usage, so we're skipping it.
+ # Consult https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180764 for more info.
+ skip_if_multiple_databases_are_setup(:sec)
+ end
+
include_examples 'desired sharding key backfill job' do
let(:batch_table) { :vulnerability_external_issue_links }
let(:backfill_column) { :project_id }
diff --git a/spec/lib/gitlab/background_migration/backfill_vulnerability_occurrence_identifiers_project_id_spec.rb b/spec/lib/gitlab/background_migration/backfill_vulnerability_occurrence_identifiers_project_id_spec.rb
index 649695f6fdb..8420fb58928 100644
--- a/spec/lib/gitlab/background_migration/backfill_vulnerability_occurrence_identifiers_project_id_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_vulnerability_occurrence_identifiers_project_id_spec.rb
@@ -5,6 +5,13 @@ require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillVulnerabilityOccurrenceIdentifiersProjectId,
feature_category: :vulnerability_management,
schema: 20240730171958 do
+ before do
+ # This test shares the db connection to establish it's fixtures, resulting in
+ # incorrect connection usage, so we're skipping it.
+ # Consult https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180764 for more info.
+ skip_if_multiple_databases_are_setup(:sec)
+ end
+
include_examples 'desired sharding key backfill job' do
let(:batch_table) { :vulnerability_occurrence_identifiers }
let(:backfill_column) { :project_id }
diff --git a/spec/lib/gitlab/background_migration/remove_namespace_from_os_type_sbom_components_spec.rb b/spec/lib/gitlab/background_migration/remove_namespace_from_os_type_sbom_components_spec.rb
index 0433708c062..b3334897ce7 100644
--- a/spec/lib/gitlab/background_migration/remove_namespace_from_os_type_sbom_components_spec.rb
+++ b/spec/lib/gitlab/background_migration/remove_namespace_from_os_type_sbom_components_spec.rb
@@ -33,6 +33,11 @@ RSpec.describe Gitlab::BackgroundMigration::RemoveNamespaceFromOsTypeSbomCompone
end
before do
+ # This test shares the db connection to establish it's fixtures, resulting in
+ # incorrect connection usage, so we're skipping it.
+ # Consult https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180764 for more info.
+ skip_if_multiple_databases_are_setup(:sec)
+
os_prefix_to_purl_type_mapping.each.with_index do |(namespace, purl_type), index|
components.create!(name: "#{namespace}/package-#{index}", purl_type: purl_type, component_type: 0)
end
diff --git a/spec/lib/gitlab/background_migration/resync_has_vulnerabilities_spec.rb b/spec/lib/gitlab/background_migration/resync_has_vulnerabilities_spec.rb
index ad8c6ee0797..a3c4085769d 100644
--- a/spec/lib/gitlab/background_migration/resync_has_vulnerabilities_spec.rb
+++ b/spec/lib/gitlab/background_migration/resync_has_vulnerabilities_spec.rb
@@ -68,6 +68,13 @@ RSpec.describe Gitlab::BackgroundMigration::ResyncHasVulnerabilities, feature_ca
subject(:perform_migration) { described_class.new(**args).perform }
+ before do
+ # This test shares the db connection to establish it's fixtures, resulting in
+ # incorrect connection usage, so we're skipping it.
+ # Consult https://gitlab.com/gitlab-org/gitlab/-/merge_requests/180764 for more info.
+ skip_if_multiple_databases_are_setup(:sec)
+ end
+
def create_project_setting(
name,
has_vulnerabilities_setting:,
diff --git a/spec/lib/gitlab/database/tables_locker_spec.rb b/spec/lib/gitlab/database/tables_locker_spec.rb
index abf8642a613..15f50488753 100644
--- a/spec/lib/gitlab/database/tables_locker_spec.rb
+++ b/spec/lib/gitlab/database/tables_locker_spec.rb
@@ -309,6 +309,11 @@ RSpec.describe Gitlab::Database::TablesLocker, :suppress_gitlab_schemas_validate
subject { described_class.new.lock_writes }
before do
+ # Some spec in this file currently fails when a sec database is configured. We plan to ensure it all functions
+ # and passes prior to the sec db rollout.
+ # Consult https://gitlab.com/gitlab-org/gitlab/-/issues/520270 for more info.
+ skip_if_multiple_databases_are_setup(:sec)
+
allow(::Gitlab::Database).to receive(:db_config_share_with).and_return(nil)
ci_db_config = Ci::ApplicationRecord.connection_db_config
allow(::Gitlab::Database).to receive(:db_config_share_with).with(ci_db_config).and_return('main')
diff --git a/spec/models/pages_deployment_spec.rb b/spec/models/pages_deployment_spec.rb
index f808eb447f5..201f9e24ff4 100644
--- a/spec/models/pages_deployment_spec.rb
+++ b/spec/models/pages_deployment_spec.rb
@@ -3,6 +3,7 @@
require 'spec_helper'
RSpec.describe PagesDeployment, feature_category: :pages do
+ using RSpec::Parameterized::TableSyntax
let_it_be(:project) { create(:project) }
describe 'associations' do
@@ -232,5 +233,63 @@ RSpec.describe PagesDeployment, feature_category: :pages do
expect { deployment.restore }
.to change { deployment.deleted_at }.from(Time.zone.now).to(nil)
end
+
+ context 'when restoring a deleted page deployment with path_prefix not nil', :freeze_time do
+ let(:deleted_deployment) do
+ create(:pages_deployment, project: project, deleted_at: Time.zone.now, path_prefix: 'test')
+ end
+
+ let(:past_deactivation_date) { '2020-02-16' }
+
+ where(:path_prefix, :deleted_at) do
+ 'test2' | nil # active deployment with different path_prefix stays active
+ 'test' | ref(:past_deactivation_date) # stopped deployment with same path_prefix stays stopped
+ 'test2' | ref(:past_deactivation_date) # stopped deployment with different path_prefix stays stopped
+ '' | nil # active deployment with no path_prefix stays active
+ '' | ref(:past_deactivation_date) # stopped deployment with no path_prefix stays stopped
+ end
+
+ with_them do
+ it 'deactivate active deployment with diff paths and others stays the same' do
+ deployment = create(:pages_deployment, project: project, path_prefix: path_prefix, deleted_at: deleted_at)
+ expect { deleted_deployment.restore }
+ .not_to change { deployment.reload.deleted_at }
+ end
+ end
+
+ it 'deactivate active deployment with same path_prefix' do
+ active_deployment = create(:pages_deployment, project: project, path_prefix: 'test')
+ expect { deleted_deployment.restore }
+ .to change { active_deployment.reload.deleted_at }.from(nil).to(Time.zone.now)
+ end
+ end
+
+ context 'when restoring a deleted page deployment with path_prefix nil', :freeze_time do
+ let(:deleted_deployment) do
+ create(:pages_deployment, project: project, deleted_at: Time.zone.now, path_prefix: '')
+ end
+
+ let(:past_deactivation_date) { '2020-02-16' }
+
+ where(:path_prefix, :deleted_at) do
+ 'test2' | nil # active deployment with a path_prefix stays active
+ 'test2' | ref(:past_deactivation_date) # stopped deployment with a path_prefix stays stopped
+ '' | ref(:past_deactivation_date) # stopped deployment with no path_prefix stays stopped
+ end
+
+ with_them do
+ it 'deactivate active deployment with diff paths and others stays the same' do
+ deployment = create(:pages_deployment, project: project, path_prefix: path_prefix, deleted_at: deleted_at)
+ expect { deleted_deployment.restore }
+ .not_to change { deployment.reload.deleted_at }
+ end
+ end
+
+ it 'deactivate active deployment with same path_prefix' do
+ active_deployment = create(:pages_deployment, project: project, path_prefix: '')
+ expect { deleted_deployment.restore }
+ .to change { active_deployment.reload.deleted_at }.from(nil).to(Time.zone.now)
+ end
+ end
end
end
diff --git a/spec/requests/jwks_controller_spec.rb b/spec/requests/jwks_controller_spec.rb
index 8a72f894d99..cd84a19f39f 100644
--- a/spec/requests/jwks_controller_spec.rb
+++ b/spec/requests/jwks_controller_spec.rb
@@ -16,4 +16,28 @@ RSpec.describe JwksController, feature_category: :system_access do
end
end
end
+
+ describe '/oauth/discovery/keys' do
+ include_context 'when doing OIDC key discovery'
+
+ it 'removes missing keys' do
+ expect(Rails.application.credentials).to receive(:openid_connect_signing_key).and_return(rsa_key_1.to_pem)
+ expect(Gitlab::CurrentSettings).to receive(:ci_jwt_signing_key).and_return(nil)
+
+ expect(jwks.size).to eq(1)
+ expect(jwks).to match_array([
+ satisfy { |jwk| key_match?(jwk, rsa_key_1) }
+ ])
+ end
+
+ it 'removes duplicate keys' do
+ expect(Rails.application.credentials).to receive(:openid_connect_signing_key).and_return(rsa_key_1.to_pem)
+ expect(Gitlab::CurrentSettings).to receive(:ci_jwt_signing_key).and_return(rsa_key_1.to_pem)
+
+ expect(jwks.size).to eq(1)
+ expect(jwks).to match_array([
+ satisfy { |jwk| key_match?(jwk, rsa_key_1) }
+ ])
+ end
+ end
end
diff --git a/spec/requests/projects/pipelines_controller_spec.rb b/spec/requests/projects/pipelines_controller_spec.rb
index 268c016a1a1..895b631f470 100644
--- a/spec/requests/projects/pipelines_controller_spec.rb
+++ b/spec/requests/projects/pipelines_controller_spec.rb
@@ -75,57 +75,14 @@ RSpec.describe Projects::PipelinesController, feature_category: :continuous_inte
expect(response).to have_gitlab_http_status(:ok)
end
- context 'when pipeline_stage_set_last_modified is disabled' do
- before do
- stub_feature_flags(pipeline_stage_set_last_modified: false)
- end
+ it 'does not set Last-Modified' do
+ create(:ci_build, :retried, :failed, pipeline: pipeline, stage: 'build')
- it 'does not set Last-Modified' do
- create(:ci_build, :retried, :failed, pipeline: pipeline, stage: 'build')
+ request_build_stage
- request_build_stage
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response.headers['Last-Modified']).to be_nil
- expect(response.headers['Cache-Control']).to eq('max-age=0, private, must-revalidate')
- end
- end
-
- context 'when pipeline_stage_set_last_modified is enabled' do
- before do
- stub_feature_flags(pipeline_stage_set_last_modified: true)
- stage.statuses.update_all(updated_at: status_timestamp)
- end
-
- let(:last_modified) { DateTime.parse(response.headers['Last-Modified']).utc }
- let(:cache_control) { response.headers['Cache-Control'] }
- let(:expected_cache_control) { 'max-age=0, private, must-revalidate' }
-
- context 'when status.updated_at is before stage.updated' do
- let(:stage) { pipeline.stage('build') }
- let(:status_timestamp) { stage.updated_at - 10.minutes }
-
- it 'sets correct Last-Modified of stage.updated_at' do
- request_build_stage
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(last_modified).to be_within(1.second).of stage.updated_at
- expect(cache_control).to eq(expected_cache_control)
- end
- end
-
- context 'when status.updated_at is after stage.updated' do
- let(:stage) { pipeline.stage('build') }
- let(:status_timestamp) { stage.updated_at + 10.minutes }
-
- it 'sets correct Last-Modified of max(status.updated_at)' do
- request_build_stage
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(last_modified).to be_within(1.second).of status_timestamp
- expect(cache_control).to eq(expected_cache_control)
- end
- end
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.headers['Last-Modified']).to be_nil
+ expect(response.headers['Cache-Control']).to eq('max-age=0, private, must-revalidate')
end
context 'with retried builds' do
diff --git a/spec/support/shared_contexts/requests/api/oidc_discovery_shared_context.rb b/spec/support/shared_contexts/requests/api/oidc_discovery_shared_context.rb
new file mode 100644
index 00000000000..f87b8a1efa4
--- /dev/null
+++ b/spec/support/shared_contexts/requests/api/oidc_discovery_shared_context.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.shared_context 'when doing OIDC key discovery' do
+ let_it_be(:rsa_key_1) { OpenSSL::PKey::RSA.new(2048) }
+ let_it_be(:rsa_key_2) { OpenSSL::PKey::RSA.new(2048) }
+
+ subject(:jwks) do
+ get '/oauth/discovery/keys'
+
+ jwks = Gitlab::Json.parse(response.body)
+ jwks['keys'].map { |json| ::JWT::JWK.new(json) }
+ end
+
+ def key_match?(jwk, private_key)
+ jwk.public_key.to_pem == private_key.public_key.to_pem
+ end
+end
diff --git a/spec/workers/loose_foreign_keys/cleanup_worker_spec.rb b/spec/workers/loose_foreign_keys/cleanup_worker_spec.rb
index 2734bd26903..75cfecbacbe 100644
--- a/spec/workers/loose_foreign_keys/cleanup_worker_spec.rb
+++ b/spec/workers/loose_foreign_keys/cleanup_worker_spec.rb
@@ -122,6 +122,11 @@ RSpec.describe LooseForeignKeys::CleanupWorker, feature_category: :cell do
end
it 'cleans up all rows' do
+ # Some spec in this file currently fails when a sec database is configured. We plan to ensure it all functions
+ # and passes prior to the sec db rollout.
+ # Consult https://gitlab.com/gitlab-org/gitlab/-/issues/520270 for more info.
+ skip_if_multiple_databases_are_setup(:sec)
+
perform_for(db: :main)
expect(loose_fk_child_table_1_1.count).to eq(0)
@@ -175,6 +180,13 @@ RSpec.describe LooseForeignKeys::CleanupWorker, feature_category: :cell do
end
describe 'turbo mode' do
+ before do
+ # Some spec in this file currently fails when a sec database is configured. We plan to ensure it all functions
+ # and passes prior to the sec db rollout.
+ # Consult https://gitlab.com/gitlab-org/gitlab/-/issues/520270 for more info.
+ skip_if_multiple_databases_are_setup(:sec)
+ end
+
context 'when turbo mode is off' do
where(:database_name, :feature_flag) do
:main | :loose_foreign_keys_turbo_mode_main