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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-11-01 18:09:40 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-11-01 18:09:40 +0300
commitb21334799a5226cdef52d4fb3b148f08af209f1a (patch)
tree43ccf0b97fe9bad89f48190e4958fbad27d42e31
parent0a0c5aaca5d1ce5403034cb234311518109a0c30 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--Gemfile1
-rw-r--r--Gemfile.checksum1
-rw-r--r--Gemfile.lock3
-rw-r--r--app/assets/javascripts/ci/runner/components/runner_created_at.vue2
-rw-r--r--app/assets/javascripts/observability/client.js2
-rw-r--r--app/assets/javascripts/observability/components/observability_container.vue7
-rw-r--r--app/assets/javascripts/projects/default_project_templates.js4
-rw-r--r--app/assets/javascripts/vue_shared/components/notes/system_note.vue2
-rw-r--r--app/models/ci/catalog/listing.rb17
-rw-r--r--app/models/ci/catalog/resource.rb4
-rw-r--r--app/services/releases/base_service.rb4
-rw-r--r--app/services/releases/create_service.rb2
-rw-r--r--app/services/releases/destroy_service.rb2
-rw-r--r--app/services/releases/update_service.rb2
-rw-r--r--config/feature_flags/development/activity_filter_has_remediations.yml8
-rw-r--r--db/migrate/20231024173744_add_path_to_catalog_resource_components.rb20
-rw-r--r--db/post_migrate/20231025031337_cleanup_ci_pipeline_messages_pipeline_id_bigint.rb29
-rw-r--r--db/post_migrate/20231025031539_swap_columns_for_ci_stages_pipeline_id_bigint_for_self_host.rb66
-rw-r--r--db/schema_migrations/202310241737441
-rw-r--r--db/schema_migrations/202310250313371
-rw-r--r--db/schema_migrations/202310250315391
-rw-r--r--db/structure.sql19
-rw-r--r--doc/policy/experiment-beta-support.md6
-rw-r--r--lib/api/releases.rb23
-rw-r--r--lib/gitlab/project_template.rb3
-rw-r--r--lib/gitlab/redis/multi_store.rb2
-rw-r--r--locale/gitlab.pot15
-rw-r--r--spec/frontend/observability/client_spec.js29
-rw-r--r--spec/frontend/observability/observability_container_spec.js13
-rw-r--r--spec/lib/gitlab/project_template_spec.rb2
-rw-r--r--spec/lib/gitlab/redis/multi_store_spec.rb24
-rw-r--r--spec/models/ci/catalog/resource_spec.rb10
-rw-r--r--spec/support/helpers/project_template_test_helper.rb1
-rw-r--r--vendor/project_templates/astro_tailwind.tar.gzbin0 -> 181171 bytes
34 files changed, 225 insertions, 101 deletions
diff --git a/Gemfile b/Gemfile
index d4c3ce91559..421828010c7 100644
--- a/Gemfile
+++ b/Gemfile
@@ -246,7 +246,6 @@ gem 'acts-as-taggable-on', '~> 10.0' # rubocop:todo Gemfile/MissingFeatureCatego
# Background jobs
gem 'sidekiq', '~> 6.5.10' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'sidekiq-cron', '~> 1.8.0' # rubocop:todo Gemfile/MissingFeatureCategory
-gem 'redis-namespace', '~> 1.9.0' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'gitlab-sidekiq-fetcher', path: 'vendor/gems/sidekiq-reliable-fetch', require: 'sidekiq-reliable-fetch' # rubocop:todo Gemfile/MissingFeatureCategory
# Cron Parser
diff --git a/Gemfile.checksum b/Gemfile.checksum
index 85e476f88f1..0f0a4fde96c 100644
--- a/Gemfile.checksum
+++ b/Gemfile.checksum
@@ -507,7 +507,6 @@
{"name":"redcarpet","version":"3.6.0","platform":"ruby","checksum":"8ad1889c0355ff4c47174af14edd06d62f45a326da1da6e8a121d59bdcd2e9e9"},
{"name":"redis","version":"4.8.0","platform":"ruby","checksum":"2000cf5014669c9dc821704b6d322a35a9a33852a95208911d9175d63b448a44"},
{"name":"redis-actionpack","version":"5.3.0","platform":"ruby","checksum":"3fb1ad0a8fd9d26a289c9399bb609dcaef38bf37711e6f677a53ca728fc19140"},
-{"name":"redis-namespace","version":"1.9.0","platform":"ruby","checksum":"0923961f38cf15b86cb57d92507e0a3b32480729eb5033249f5de8b12e0d8612"},
{"name":"redis-rack","version":"2.1.4","platform":"ruby","checksum":"0872eecb303e483c3863d6bd0d47323d230640d41c1a4ac4a2c7596ec0b1774c"},
{"name":"redis-store","version":"1.9.1","platform":"ruby","checksum":"7b4c7438d46f7b7ce8f67fc0eda3a04fc67d32d28cf606cc98a5df4d2b77071d"},
{"name":"regexp_parser","version":"2.6.0","platform":"ruby","checksum":"f163ba463a45ca2f2730e0902f2475bb0eefcd536dfc2f900a86d1e5a7d7a556"},
diff --git a/Gemfile.lock b/Gemfile.lock
index 601cfd70894..8bac7b3a18f 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1316,8 +1316,6 @@ GEM
actionpack (>= 5, < 8)
redis-rack (>= 2.1.0, < 3)
redis-store (>= 1.1.0, < 2)
- redis-namespace (1.9.0)
- redis (>= 4)
redis-rack (2.1.4)
rack (>= 2.0.8, < 3)
redis-store (>= 1.2, < 2)
@@ -1971,7 +1969,6 @@ DEPENDENCIES
recaptcha (~> 5.12)
redis (~> 4.8.0)
redis-actionpack (~> 5.3.0)
- redis-namespace (~> 1.9.0)
request_store (~> 1.5.1)
responders (~> 3.0)
retriable (~> 3.1.2)
diff --git a/app/assets/javascripts/ci/runner/components/runner_created_at.vue b/app/assets/javascripts/ci/runner/components/runner_created_at.vue
index 5594f4ab486..410142a0eb5 100644
--- a/app/assets/javascripts/ci/runner/components/runner_created_at.vue
+++ b/app/assets/javascripts/ci/runner/components/runner_created_at.vue
@@ -58,7 +58,7 @@ export default {
</template>
<template #user>
<gl-link
- class="js-user-link gl-reset-color gl-reset-font-size gl-font-weight-bold"
+ class="js-user-link gl-reset-color gl-font-weight-bold"
:href="createdBy.webUrl"
:data-user-id="createdById"
:data-username="createdBy.username"
diff --git a/app/assets/javascripts/observability/client.js b/app/assets/javascripts/observability/client.js
index 2f25184e9d6..884aa841b68 100644
--- a/app/assets/javascripts/observability/client.js
+++ b/app/assets/javascripts/observability/client.js
@@ -1,7 +1,9 @@
import * as Sentry from '~/sentry/sentry_browser_wrapper';
import axios from '~/lib/utils/axios_utils';
+import { logError } from '~/lib/logger';
function reportErrorAndThrow(e) {
+ logError(e);
Sentry.captureException(e);
throw e;
}
diff --git a/app/assets/javascripts/observability/components/observability_container.vue b/app/assets/javascripts/observability/components/observability_container.vue
index 0a9dec11430..33d05b01556 100644
--- a/app/assets/javascripts/observability/components/observability_container.vue
+++ b/app/assets/javascripts/observability/components/observability_container.vue
@@ -1,4 +1,6 @@
<script>
+import * as Sentry from '~/sentry/sentry_browser_wrapper';
+import { logError } from '~/lib/logger';
import { buildClient } from '../client';
import ObservabilityLoader from './loader/index.vue';
import { CONTENT_STATE } from './loader/constants';
@@ -72,8 +74,9 @@ export default {
this.$emit('observability-client-ready', this.observabilityClient);
this.loaderContentState = CONTENT_STATE.LOADED;
} else if (status === 'error') {
- // eslint-disable-next-line @gitlab/require-i18n-strings,no-console
- console.error('GOB auth failed with error:', message, statusCode);
+ const error = new Error(`GOB auth failed with error: ${message} - status: ${statusCode}`);
+ Sentry.captureException(error);
+ logError(error);
this.loaderContentState = CONTENT_STATE.ERROR;
}
this.authCompleted = true;
diff --git a/app/assets/javascripts/projects/default_project_templates.js b/app/assets/javascripts/projects/default_project_templates.js
index 5bbc881952f..e3599c87616 100644
--- a/app/assets/javascripts/projects/default_project_templates.js
+++ b/app/assets/javascripts/projects/default_project_templates.js
@@ -121,4 +121,8 @@ export default {
text: s__('ProjectTemplates|Laravel Framework'),
icon: '.template-option .icon-laravel',
},
+ astro_tailwind: {
+ text: s__('ProjectTemplates|Astro Tailwind'),
+ icon: '.template-option .icon-gitlab_logo',
+ },
};
diff --git a/app/assets/javascripts/vue_shared/components/notes/system_note.vue b/app/assets/javascripts/vue_shared/components/notes/system_note.vue
index abebdb84c17..6a5884e4857 100644
--- a/app/assets/javascripts/vue_shared/components/notes/system_note.vue
+++ b/app/assets/javascripts/vue_shared/components/notes/system_note.vue
@@ -143,7 +143,7 @@ export default {
<gl-icon
v-if="isAllowedIcon"
:name="note.system_note_icon_name"
- size="12"
+ :size="12"
data-testid="timeline-icon"
/>
</div>
diff --git a/app/models/ci/catalog/listing.rb b/app/models/ci/catalog/listing.rb
index a6f0caa7a40..51bd85016a5 100644
--- a/app/models/ci/catalog/listing.rb
+++ b/app/models/ci/catalog/listing.rb
@@ -14,8 +14,9 @@ module Ci
end
def resources(namespace: nil, sort: nil, search: nil)
- relation = all_resources(search)
+ relation = all_resources
relation = by_namespace(relation, namespace)
+ relation = by_search(relation, search)
case sort.to_s
when 'name_desc' then relation.order_by_name_desc
@@ -32,9 +33,9 @@ module Ci
attr_reader :current_user
- def all_resources(search)
+ def all_resources
Ci::Catalog::Resource.joins(:project).includes(:project)
- .merge(find_projects(search))
+ .merge(Project.public_or_visible_to_user(current_user))
end
def by_namespace(relation, namespace)
@@ -44,13 +45,11 @@ module Ci
relation.merge(Project.in_namespace(namespace.self_and_descendant_ids))
end
- def find_projects(search)
- finder_params = {
- minimum_search_length: MIN_SEARCH_LENGTH,
- search: search
- }
+ def by_search(relation, search)
+ return relation unless search
+ return relation.none if search.length < MIN_SEARCH_LENGTH
- ProjectsFinder.new(params: finder_params, current_user: current_user).execute
+ relation.search(search)
end
end
end
diff --git a/app/models/ci/catalog/resource.rb b/app/models/ci/catalog/resource.rb
index 38841cc309d..e3076e85d10 100644
--- a/app/models/ci/catalog/resource.rb
+++ b/app/models/ci/catalog/resource.rb
@@ -8,6 +8,8 @@ module Ci
# dependency on the Project model and its need to join with that table
# in order to generate the CI/CD catalog.
class Resource < ::ApplicationRecord
+ include Gitlab::SQL::Pattern
+
self.table_name = 'catalog_resources'
belongs_to :project
@@ -15,6 +17,8 @@ module Ci
has_many :versions, class_name: 'Ci::Catalog::Resources::Version', inverse_of: :catalog_resource
scope :for_projects, ->(project_ids) { where(project_id: project_ids) }
+ scope :search, ->(query) { fuzzy_search(query, [:name, :description], use_minimum_char_limit: false) }
+
scope :order_by_created_at_desc, -> { reorder(created_at: :desc) }
scope :order_by_created_at_asc, -> { reorder(created_at: :asc) }
scope :order_by_name_desc, -> { reorder(arel_table[:name].desc.nulls_last) }
diff --git a/app/services/releases/base_service.rb b/app/services/releases/base_service.rb
index 5d6cb372653..088776b896c 100644
--- a/app/services/releases/base_service.rb
+++ b/app/services/releases/base_service.rb
@@ -111,6 +111,10 @@ module Releases
# overridden in EE
def project_group_id; end
+
+ def audit(release, action:)
+ # overridden in EE
+ end
end
end
diff --git a/app/services/releases/create_service.rb b/app/services/releases/create_service.rb
index 95e0861a37a..034cb66c8b9 100644
--- a/app/services/releases/create_service.rb
+++ b/app/services/releases/create_service.rb
@@ -64,6 +64,8 @@ module Releases
create_evidence!(release, evidence_pipeline)
+ audit(release, action: :created)
+
success(tag: tag, release: release)
rescue StandardError => e
error(e.message, 400)
diff --git a/app/services/releases/destroy_service.rb b/app/services/releases/destroy_service.rb
index 78613c05ff1..1e8338651a8 100644
--- a/app/services/releases/destroy_service.rb
+++ b/app/services/releases/destroy_service.rb
@@ -11,6 +11,8 @@ module Releases
execute_hooks(release, 'delete')
+ audit(release, action: :deleted)
+
success(tag: existing_tag, release: release)
else
error(release.errors.messages || '400 Bad request', 400)
diff --git a/app/services/releases/update_service.rb b/app/services/releases/update_service.rb
index c11d9468814..13ece1c10c8 100644
--- a/app/services/releases/update_service.rb
+++ b/app/services/releases/update_service.rb
@@ -19,6 +19,8 @@ module Releases
ApplicationRecord.transaction do
if release.update(params)
execute_hooks(release, 'update')
+ audit(release, action: :updated)
+ audit(release, action: :milestones_updated) if milestones_updated?(previous_milestones)
success(tag: existing_tag, release: release, milestones_updated: milestones_updated?(previous_milestones))
else
error(release.errors.messages || '400 Bad request', 400)
diff --git a/config/feature_flags/development/activity_filter_has_remediations.yml b/config/feature_flags/development/activity_filter_has_remediations.yml
new file mode 100644
index 00000000000..7a0b5f958f3
--- /dev/null
+++ b/config/feature_flags/development/activity_filter_has_remediations.yml
@@ -0,0 +1,8 @@
+---
+name: activity_filter_has_remediations
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/135009
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/429262
+milestone: '16.6'
+type: development
+group: group::threat insights
+default_enabled: false
diff --git a/db/migrate/20231024173744_add_path_to_catalog_resource_components.rb b/db/migrate/20231024173744_add_path_to_catalog_resource_components.rb
new file mode 100644
index 00000000000..2473856faf1
--- /dev/null
+++ b/db/migrate/20231024173744_add_path_to_catalog_resource_components.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class AddPathToCatalogResourceComponents < Gitlab::Database::Migration[2.2]
+ milestone '16.6'
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ add_column :catalog_resource_components, :path, :text, if_not_exists: true
+ end
+
+ add_text_limit :catalog_resource_components, :path, 255
+ end
+
+ def down
+ with_lock_retries do
+ remove_column :catalog_resource_components, :path, :text, if_exists: true
+ end
+ end
+end
diff --git a/db/post_migrate/20231025031337_cleanup_ci_pipeline_messages_pipeline_id_bigint.rb b/db/post_migrate/20231025031337_cleanup_ci_pipeline_messages_pipeline_id_bigint.rb
new file mode 100644
index 00000000000..b9e44f8f2d0
--- /dev/null
+++ b/db/post_migrate/20231025031337_cleanup_ci_pipeline_messages_pipeline_id_bigint.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+class CleanupCiPipelineMessagesPipelineIdBigint < Gitlab::Database::Migration[2.1]
+ disable_ddl_transaction!
+
+ TABLE = :ci_pipeline_messages
+ COLUMNS = [:pipeline_id]
+
+ def up
+ with_lock_retries(raise_on_exhaustion: true) do
+ lock_tables(:ci_pipelines, TABLE)
+ cleanup_conversion_of_integer_to_bigint(TABLE, COLUMNS) # rubocop:disable Migration/WithLockRetriesDisallowedMethod
+ end
+ end
+
+ def down
+ restore_conversion_of_integer_to_bigint(TABLE, COLUMNS)
+
+ add_concurrent_index(
+ TABLE, :pipeline_id_convert_to_bigint,
+ name: :index_ci_pipeline_messages_on_pipeline_id_convert_to_bigint
+ )
+ add_concurrent_foreign_key(
+ TABLE, :ci_pipelines,
+ column: :pipeline_id_convert_to_bigint,
+ on_delete: :cascade, validate: true, reverse_lock_order: true
+ )
+ end
+end
diff --git a/db/post_migrate/20231025031539_swap_columns_for_ci_stages_pipeline_id_bigint_for_self_host.rb b/db/post_migrate/20231025031539_swap_columns_for_ci_stages_pipeline_id_bigint_for_self_host.rb
new file mode 100644
index 00000000000..c28f49899b6
--- /dev/null
+++ b/db/post_migrate/20231025031539_swap_columns_for_ci_stages_pipeline_id_bigint_for_self_host.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+class SwapColumnsForCiStagesPipelineIdBigintForSelfHost < Gitlab::Database::Migration[2.2]
+ include Gitlab::Database::MigrationHelpers::Swapping
+
+ milestone '16.6'
+ disable_ddl_transaction!
+
+ TABLE_NAME = :ci_stages
+ TRIGGER_FUNCTION_NAME = :trigger_07bc3c48f407
+ COLUMN_NAME = :pipeline_id
+ BIGINT_COLUMN_NAME = :pipeline_id_convert_to_bigint
+ FK_NAME = :fk_fb57e6cc56
+ BIGINT_FK_NAME = :fk_c5ddde695f
+ INDEX_NAMES = %i[
+ index_ci_stages_on_pipeline_id
+ index_ci_stages_on_pipeline_id_and_id
+ index_ci_stages_on_pipeline_id_and_name
+ index_ci_stages_on_pipeline_id_and_position
+ ]
+ BIGINT_INDEX_NAMES = %i[
+ index_ci_stages_on_pipeline_id_convert_to_bigint
+ index_ci_stages_on_pipeline_id_convert_to_bigint_and_id
+ index_ci_stages_on_pipeline_id_convert_to_bigint_and_name
+ index_ci_stages_on_pipeline_id_convert_to_bigint_and_position
+ ]
+
+ def up
+ return if column_type_of?(:bigint)
+
+ swap
+ end
+
+ def down
+ return if column_type_of?(:integer)
+
+ swap
+ end
+
+ private
+
+ def column_type_of?(type)
+ column_for(TABLE_NAME, COLUMN_NAME).sql_type.to_s == type.to_s
+ end
+
+ def swap
+ with_lock_retries(raise_on_exhaustion: true) do
+ # Lock the tables involved.
+ lock_tables(:ci_pipelines, :ci_stages)
+
+ # Rename the columns to swap names
+ swap_columns(TABLE_NAME, COLUMN_NAME, BIGINT_COLUMN_NAME)
+
+ # Reset the trigger function
+ reset_trigger_function(TRIGGER_FUNCTION_NAME)
+
+ # Swap fkey constraint
+ swap_foreign_keys(TABLE_NAME, FK_NAME, BIGINT_FK_NAME)
+
+ # Swap index
+ INDEX_NAMES.each_with_index do |index_name, i|
+ swap_indexes(TABLE_NAME, index_name, BIGINT_INDEX_NAMES[i])
+ end
+ end
+ end
+end
diff --git a/db/schema_migrations/20231024173744 b/db/schema_migrations/20231024173744
new file mode 100644
index 00000000000..b262f2a2ebb
--- /dev/null
+++ b/db/schema_migrations/20231024173744
@@ -0,0 +1 @@
+fd51e236973eaf1d4a2719eaa34dbd7955c2d73e37adf244472c8c69fc486fdf \ No newline at end of file
diff --git a/db/schema_migrations/20231025031337 b/db/schema_migrations/20231025031337
new file mode 100644
index 00000000000..8d28d710397
--- /dev/null
+++ b/db/schema_migrations/20231025031337
@@ -0,0 +1 @@
+7dc72ca807126bb992c22879a6d989f282e442ff2c6e15b046e6f3d0f464237f \ No newline at end of file
diff --git a/db/schema_migrations/20231025031539 b/db/schema_migrations/20231025031539
new file mode 100644
index 00000000000..4332cd2b867
--- /dev/null
+++ b/db/schema_migrations/20231025031539
@@ -0,0 +1 @@
+4de438a35ae2cbeee4cec03961cf7b5dddfcce2454a1e3ce08985e28b7065a0d \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index a9e416c4c57..255b362c5d0 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -341,15 +341,6 @@ BEGIN
END;
$$;
-CREATE FUNCTION trigger_bfad0e2b9c86() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
-BEGIN
- NEW."pipeline_id_convert_to_bigint" := NEW."pipeline_id";
- RETURN NEW;
-END;
-$$;
-
CREATE FUNCTION unset_has_issues_on_vulnerability_reads() RETURNS trigger
LANGUAGE plpgsql
AS $$
@@ -13196,6 +13187,8 @@ CREATE TABLE catalog_resource_components (
resource_type smallint DEFAULT 1 NOT NULL,
inputs jsonb DEFAULT '{}'::jsonb NOT NULL,
name text NOT NULL,
+ path text,
+ CONSTRAINT check_a76bfd47fe CHECK ((char_length(path) <= 255)),
CONSTRAINT check_ddca729980 CHECK ((char_length(name) <= 255))
);
@@ -13919,7 +13912,6 @@ ALTER SEQUENCE ci_pipeline_chat_data_id_seq OWNED BY ci_pipeline_chat_data.id;
CREATE TABLE ci_pipeline_messages (
id bigint NOT NULL,
severity smallint DEFAULT 0 NOT NULL,
- pipeline_id_convert_to_bigint integer DEFAULT 0 NOT NULL,
content text NOT NULL,
pipeline_id bigint NOT NULL,
CONSTRAINT check_58ca2981b2 CHECK ((char_length(content) <= 10000))
@@ -31934,8 +31926,6 @@ CREATE UNIQUE INDEX index_ci_pipeline_chat_data_on_pipeline_id ON ci_pipeline_ch
CREATE INDEX index_ci_pipeline_messages_on_pipeline_id ON ci_pipeline_messages USING btree (pipeline_id);
-CREATE INDEX index_ci_pipeline_messages_on_pipeline_id_convert_to_bigint ON ci_pipeline_messages USING btree (pipeline_id_convert_to_bigint);
-
CREATE INDEX index_ci_pipeline_metadata_on_project_id ON ci_pipeline_metadata USING btree (project_id);
CREATE UNIQUE INDEX index_ci_pipeline_schedule_variables_on_schedule_id_and_key ON ci_pipeline_schedule_variables USING btree (pipeline_schedule_id, key);
@@ -36832,8 +36822,6 @@ CREATE TRIGGER trigger_7f3d66a7d7f5 BEFORE INSERT OR UPDATE ON ci_pipeline_varia
CREATE TRIGGER trigger_b2d852e1e2cb BEFORE INSERT OR UPDATE ON ci_pipelines FOR EACH ROW EXECUTE FUNCTION trigger_b2d852e1e2cb();
-CREATE TRIGGER trigger_bfad0e2b9c86 BEFORE INSERT OR UPDATE ON ci_pipeline_messages FOR EACH ROW EXECUTE FUNCTION trigger_bfad0e2b9c86();
-
CREATE TRIGGER trigger_delete_project_namespace_on_project_delete AFTER DELETE ON projects FOR EACH ROW WHEN ((old.project_namespace_id IS NOT NULL)) EXECUTE FUNCTION delete_associated_project_namespace();
CREATE TRIGGER trigger_has_external_issue_tracker_on_delete AFTER DELETE ON integrations FOR EACH ROW WHEN ((((old.category)::text = 'issue_tracker'::text) AND (old.active = true) AND (old.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_issue_tracker();
@@ -36924,9 +36912,6 @@ ALTER TABLE ONLY user_interacted_projects
ALTER TABLE ONLY merge_request_assignment_events
ADD CONSTRAINT fk_08f7602bfd FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
-ALTER TABLE ONLY ci_pipeline_messages
- ADD CONSTRAINT fk_0946fea681 FOREIGN KEY (pipeline_id_convert_to_bigint) REFERENCES ci_pipelines(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY remote_development_agent_configs
ADD CONSTRAINT fk_0a3c0ada56 FOREIGN KEY (cluster_agent_id) REFERENCES cluster_agents(id) ON DELETE CASCADE;
diff --git a/doc/policy/experiment-beta-support.md b/doc/policy/experiment-beta-support.md
index a87a72d7910..41ffaec3aa4 100644
--- a/doc/policy/experiment-beta-support.md
+++ b/doc/policy/experiment-beta-support.md
@@ -13,7 +13,7 @@ All other features are considered to be Generally Available (GA).
## Experiment
Support is not provided for features listed as "Experimental" or "Alpha" or any similar designation. Issues regarding such features should be opened in the GitLab issue tracker. Teams should release features as GA from the start unless there are strong reasons to release them as Experiment or Beta versions first.
-All Experimental features must [initiate Production Readiness Review](https://about.gitlab.com/handbook/engineering/infrastructure/production/readiness/#process) and complete the [experiment section in the readiness template](https://gitlab.com/gitlab-com/gl-infra/readiness/-/blob/master/.gitlab/issue_templates/production_readiness.md#experiment).
+All Experimental features that [meet the review criteria](https://about.gitlab.com/handbook/engineering/infrastructure/production/readiness/#criteria-for-starting-a-production-readiness-review) must [initiate Production Readiness Review](https://about.gitlab.com/handbook/engineering/infrastructure/production/readiness/#process) and complete the [experiment section in the readiness template](https://gitlab.com/gitlab-com/gl-infra/readiness/-/blob/master/.gitlab/issue_templates/production_readiness.md#experiment).
Experimental features are:
@@ -36,7 +36,7 @@ Experimental features are:
## Beta
Commercially-reasonable efforts are made to provide limited support for features designated as "Beta," with the expectation that issues require extra time and assistance from development to troubleshoot.
-All Beta features must complete all sections up to and including the [beta section in the readiness template](https://gitlab.com/gitlab-com/gl-infra/readiness/-/blob/master/.gitlab/issue_templates/production_readiness.md#beta) by following the [Production Readiness Review process](https://about.gitlab.com/handbook/engineering/infrastructure/production/readiness/#process).
+All Beta features that [meet the review criteria](https://about.gitlab.com/handbook/engineering/infrastructure/production/readiness/#criteria-for-starting-a-production-readiness-review) must complete all sections up to and including the [beta section in the readiness template](https://gitlab.com/gitlab-com/gl-infra/readiness/-/blob/master/.gitlab/issue_templates/production_readiness.md#beta) by following the [Production Readiness Review process](https://about.gitlab.com/handbook/engineering/infrastructure/production/readiness/#process).
Beta features are:
@@ -56,7 +56,7 @@ Beta features are:
## Generally Available (GA)
-Generally Available features must complete the [Production Readiness Review](https://about.gitlab.com/handbook/engineering/infrastructure/production/readiness) and complete all sections up to and including the [GA section in the readiness template](https://gitlab.com/gitlab-com/gl-infra/readiness/-/blob/master/.gitlab/issue_templates/production_readiness.md#general-availability).
+Generally Available features that [meet the review criteria](https://about.gitlab.com/handbook/engineering/infrastructure/production/readiness/#criteria-for-starting-a-production-readiness-review) must complete the [Production Readiness Review](https://about.gitlab.com/handbook/engineering/infrastructure/production/readiness) and complete all sections up to and including the [GA section in the readiness template](https://gitlab.com/gitlab-com/gl-infra/readiness/-/blob/master/.gitlab/issue_templates/production_readiness.md#general-availability).
GA features are:
diff --git a/lib/api/releases.rb b/lib/api/releases.rb
index 5d056ade3da..83085b5b7e3 100644
--- a/lib/api/releases.rb
+++ b/lib/api/releases.rb
@@ -270,8 +270,6 @@ module API
.execute
if result[:status] == :success
- log_release_created_audit_event(result[:release])
-
present result[:release], with: Entities::Release, current_user: current_user
else
render_api_error!(result[:message], result[:http_status])
@@ -317,9 +315,6 @@ module API
.execute
if result[:status] == :success
- log_release_updated_audit_event
- log_release_milestones_updated_audit_event if result[:milestones_updated]
-
present result[:release], with: Entities::Release, current_user: current_user
else
render_api_error!(result[:message], result[:http_status])
@@ -350,8 +345,6 @@ module API
.execute
if result[:status] == :success
- log_release_deleted_audit_event
-
present result[:release], with: Entities::Release, current_user: current_user
else
render_api_error!(result[:message], result[:http_status])
@@ -406,22 +399,6 @@ module API
Rack::Utils.parse_nested_query(@request.query_string)
end
- def log_release_created_audit_event(release)
- # extended in EE
- end
-
- def log_release_updated_audit_event
- # extended in EE
- end
-
- def log_release_deleted_audit_event
- # extended in EE
- end
-
- def log_release_milestones_updated_audit_event
- # extended in EE
- end
-
def release_cli?
request.env['HTTP_USER_AGENT']&.include?(RELEASE_CLI_USER_AGENT) == true
end
diff --git a/lib/gitlab/project_template.rb b/lib/gitlab/project_template.rb
index 23dafc21392..5f2084ce011 100644
--- a/lib/gitlab/project_template.rb
+++ b/lib/gitlab/project_template.rb
@@ -81,7 +81,8 @@ module Gitlab
ProjectTemplate.new('cluster_management', 'GitLab Cluster Management', _('An example project for managing Kubernetes clusters integrated with GitLab'), 'https://gitlab.com/gitlab-org/project-templates/cluster-management'),
ProjectTemplate.new('kotlin_native_linux', 'Kotlin Native Linux', _('A basic template for developing Linux programs using Kotlin Native'), 'https://gitlab.com/gitlab-org/project-templates/kotlin-native-linux'),
ProjectTemplate.new('typo3_distribution', 'TYPO3 Distribution', _('A template for starting a new TYPO3 project'), 'https://gitlab.com/gitlab-org/project-templates/typo3-distribution', 'illustrations/logos/typo3.svg'),
- ProjectTemplate.new('laravel', 'Laravel Framework', _('A basic folder structure of a Laravel application, to help you get started.'), 'https://gitlab.com/gitlab-org/project-templates/laravel', 'illustrations/logos/laravel.svg')
+ ProjectTemplate.new('laravel', 'Laravel Framework', _('A basic folder structure of a Laravel application, to help you get started.'), 'https://gitlab.com/gitlab-org/project-templates/laravel', 'illustrations/logos/laravel.svg'),
+ ProjectTemplate.new('astro_tailwind', 'Astro Tailwind', _('A basic folder structure of Astro Starter Kit, to help you get started.'), 'https://gitlab.com/gitlab-org/project-templates/astro-tailwind')
]
end
# rubocop:enable Metrics/AbcSize
diff --git a/lib/gitlab/redis/multi_store.rb b/lib/gitlab/redis/multi_store.rb
index bbe5a8add4b..95d27cdb500 100644
--- a/lib/gitlab/redis/multi_store.rb
+++ b/lib/gitlab/redis/multi_store.rb
@@ -380,7 +380,7 @@ module Gitlab
end
def redis_store?(store)
- store.is_a?(::Redis) || store.is_a?(::Redis::Namespace)
+ store.is_a?(::Redis)
end
def validate_stores!
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index b885b883d81..5c82f344e3c 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -1765,6 +1765,9 @@ msgstr ""
msgid "A Work Item can be a parent or a child, but not both."
msgstr ""
+msgid "A basic folder structure of Astro Starter Kit, to help you get started."
+msgstr ""
+
msgid "A basic folder structure of a Laravel application, to help you get started."
msgstr ""
@@ -37845,6 +37848,9 @@ msgstr ""
msgid "ProjectTemplates|Android"
msgstr ""
+msgid "ProjectTemplates|Astro Tailwind"
+msgstr ""
+
msgid "ProjectTemplates|GitLab Cluster Management"
msgstr ""
@@ -43462,6 +43468,12 @@ msgstr ""
msgid "SecurityReports|Investigate this vulnerability by creating an issue"
msgstr ""
+msgid "SecurityReports|Is available"
+msgstr ""
+
+msgid "SecurityReports|Is not available"
+msgstr ""
+
msgid "SecurityReports|Issue"
msgstr ""
@@ -43578,6 +43590,9 @@ msgid_plural "SecurityReports|Show %d items"
msgstr[0] ""
msgstr[1] ""
+msgid "SecurityReports|Solution available"
+msgstr ""
+
msgid "SecurityReports|Sometimes a scanner can't determine a finding's severity. Those findings may still be a potential source of risk though. Please review these manually."
msgstr ""
diff --git a/spec/frontend/observability/client_spec.js b/spec/frontend/observability/client_spec.js
index 7da84b18a91..c8c51b261b6 100644
--- a/spec/frontend/observability/client_spec.js
+++ b/spec/frontend/observability/client_spec.js
@@ -2,9 +2,11 @@ import MockAdapter from 'axios-mock-adapter';
import * as Sentry from '~/sentry/sentry_browser_wrapper';
import { buildClient } from '~/observability/client';
import axios from '~/lib/utils/axios_utils';
+import { logError } from '~/lib/logger';
jest.mock('~/lib/utils/axios_utils');
jest.mock('~/sentry/sentry_browser_wrapper');
+jest.mock('~/lib/logger');
describe('buildClient', () => {
let client;
@@ -32,6 +34,11 @@ describe('buildClient', () => {
axiosMock.restore();
});
+ const expectErrorToBeReported = (e) => {
+ expect(Sentry.captureException).toHaveBeenCalledWith(e);
+ expect(logError).toHaveBeenCalledWith(e);
+ };
+
describe('buildClient', () => {
it('rejects if params are missing', () => {
const e = new Error(
@@ -89,7 +96,7 @@ describe('buildClient', () => {
const e = 'Request failed with status code 500';
await expect(client.isObservabilityEnabled()).rejects.toThrow(e);
- expect(Sentry.captureException).toHaveBeenCalledWith(new Error(e));
+ expectErrorToBeReported(new Error(e));
});
it('throws in case of unexpected response', async () => {
@@ -97,7 +104,7 @@ describe('buildClient', () => {
const e = 'Failed to check provisioning';
await expect(client.isObservabilityEnabled()).rejects.toThrow(e);
- expect(Sentry.captureException).toHaveBeenCalledWith(new Error(e));
+ expectErrorToBeReported(new Error(e));
});
});
@@ -120,7 +127,7 @@ describe('buildClient', () => {
const e = 'Request failed with status code 401';
await expect(client.enableObservability()).rejects.toThrow(e);
- expect(Sentry.captureException).toHaveBeenCalledWith(new Error(e));
+ expectErrorToBeReported(new Error(e));
});
});
@@ -156,14 +163,14 @@ describe('buildClient', () => {
axiosMock.onGet(tracingUrl).reply(200, { traces: [] });
await expect(client.fetchTrace('trace-1')).rejects.toThrow(FETCHING_TRACES_ERROR);
- expect(Sentry.captureException).toHaveBeenCalledWith(new Error(FETCHING_TRACES_ERROR));
+ expectErrorToBeReported(new Error(FETCHING_TRACES_ERROR));
});
it('rejects if traces are invalid', async () => {
axiosMock.onGet(tracingUrl).reply(200, { traces: 'invalid' });
await expect(client.fetchTraces()).rejects.toThrow(FETCHING_TRACES_ERROR);
- expect(Sentry.captureException).toHaveBeenCalledWith(new Error(FETCHING_TRACES_ERROR));
+ expectErrorToBeReported(new Error(FETCHING_TRACES_ERROR));
});
});
@@ -196,14 +203,14 @@ describe('buildClient', () => {
axiosMock.onGet(tracingUrl).reply(200, {});
await expect(client.fetchTraces()).rejects.toThrow(FETCHING_TRACES_ERROR);
- expect(Sentry.captureException).toHaveBeenCalledWith(new Error(FETCHING_TRACES_ERROR));
+ expectErrorToBeReported(new Error(FETCHING_TRACES_ERROR));
});
it('rejects if traces are invalid', async () => {
axiosMock.onGet(tracingUrl).reply(200, { traces: 'invalid' });
await expect(client.fetchTraces()).rejects.toThrow(FETCHING_TRACES_ERROR);
- expect(Sentry.captureException).toHaveBeenCalledWith(new Error(FETCHING_TRACES_ERROR));
+ expectErrorToBeReported(new Error(FETCHING_TRACES_ERROR));
});
describe('query filter', () => {
@@ -348,7 +355,7 @@ describe('buildClient', () => {
const e = 'failed to fetch services. invalid response';
await expect(client.fetchServices()).rejects.toThrow(e);
- expect(Sentry.captureException).toHaveBeenCalledWith(new Error(e));
+ expectErrorToBeReported(new Error(e));
});
});
@@ -375,7 +382,7 @@ describe('buildClient', () => {
it('rejects if serviceName is missing', async () => {
const e = 'fetchOperations() - serviceName is required.';
await expect(client.fetchOperations()).rejects.toThrow(e);
- expect(Sentry.captureException).toHaveBeenCalledWith(new Error(e));
+ expectErrorToBeReported(new Error(e));
});
it('rejects if operationUrl does not contain $SERVICE_NAME$', async () => {
@@ -387,7 +394,7 @@ describe('buildClient', () => {
});
const e = 'fetchOperations() - operationsUrl must contain $SERVICE_NAME$';
await expect(client.fetchOperations(serviceName)).rejects.toThrow(e);
- expect(Sentry.captureException).toHaveBeenCalledWith(new Error(e));
+ expectErrorToBeReported(new Error(e));
});
it('rejects if operations are missing', async () => {
@@ -395,7 +402,7 @@ describe('buildClient', () => {
const e = 'failed to fetch operations. invalid response';
await expect(client.fetchOperations(serviceName)).rejects.toThrow(e);
- expect(Sentry.captureException).toHaveBeenCalledWith(new Error(e));
+ expectErrorToBeReported(new Error(e));
});
});
});
diff --git a/spec/frontend/observability/observability_container_spec.js b/spec/frontend/observability/observability_container_spec.js
index 16b1c7b254e..1f5194a1bd8 100644
--- a/spec/frontend/observability/observability_container_spec.js
+++ b/spec/frontend/observability/observability_container_spec.js
@@ -3,10 +3,13 @@ import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import ObservabilityContainer from '~/observability/components/observability_container.vue';
import ObservabilityLoader from '~/observability/components/loader/index.vue';
import { CONTENT_STATE } from '~/observability/components/loader/constants';
-
import { buildClient } from '~/observability/client';
+import * as Sentry from '~/sentry/sentry_browser_wrapper';
+import { logError } from '~/lib/logger';
jest.mock('~/observability/client');
+jest.mock('~/sentry/sentry_browser_wrapper');
+jest.mock('~/lib/logger');
describe('ObservabilityContainer', () => {
let wrapper;
@@ -49,6 +52,8 @@ describe('ObservabilityContainer', () => {
data: {
type: 'AUTH_COMPLETION',
status,
+ message: 'test-message',
+ statusCode: 'test-code',
},
origin: origin ?? new URL(OAUTH_URL).origin,
}),
@@ -130,6 +135,12 @@ describe('ObservabilityContainer', () => {
it('does not emit observability-client-ready', () => {
expect(wrapper.emitted('observability-client-ready')).toBeUndefined();
});
+
+ it('reports the error', () => {
+ const e = new Error('GOB auth failed with error: test-message - status: test-code');
+ expect(Sentry.captureException).toHaveBeenCalledWith(e);
+ expect(logError).toHaveBeenCalledWith(e);
+ });
});
it('handles oauth message only once', async () => {
diff --git a/spec/lib/gitlab/project_template_spec.rb b/spec/lib/gitlab/project_template_spec.rb
index 998fff12e94..07cdbf97091 100644
--- a/spec/lib/gitlab/project_template_spec.rb
+++ b/spec/lib/gitlab/project_template_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::ProjectTemplate do
+RSpec.describe Gitlab::ProjectTemplate, feature_category: :source_code_management do
include ProjectTemplateTestHelper
describe '.all' do
diff --git a/spec/lib/gitlab/redis/multi_store_spec.rb b/spec/lib/gitlab/redis/multi_store_spec.rb
index 1745a745ec3..66860e8a443 100644
--- a/spec/lib/gitlab/redis/multi_store_spec.rb
+++ b/spec/lib/gitlab/redis/multi_store_spec.rb
@@ -56,7 +56,6 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
context 'when primary_store is not a ::Redis instance' do
before do
allow(primary_store).to receive(:is_a?).with(::Redis).and_return(false)
- allow(primary_store).to receive(:is_a?).with(::Redis::Namespace).and_return(false)
end
it 'fails with exception' do
@@ -65,21 +64,9 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
end
end
- context 'when primary_store is a ::Redis::Namespace instance' do
- before do
- allow(primary_store).to receive(:is_a?).with(::Redis).and_return(false)
- allow(primary_store).to receive(:is_a?).with(::Redis::Namespace).and_return(true)
- end
-
- it 'fails with exception' do
- expect { described_class.new(primary_store, secondary_store, instance_name) }.not_to raise_error
- end
- end
-
context 'when secondary_store is not a ::Redis instance' do
before do
allow(secondary_store).to receive(:is_a?).with(::Redis).and_return(false)
- allow(secondary_store).to receive(:is_a?).with(::Redis::Namespace).and_return(false)
end
it 'fails with exception' do
@@ -88,17 +75,6 @@ RSpec.describe Gitlab::Redis::MultiStore, feature_category: :redis do
end
end
- context 'when secondary_store is a ::Redis::Namespace instance' do
- before do
- allow(secondary_store).to receive(:is_a?).with(::Redis).and_return(false)
- allow(secondary_store).to receive(:is_a?).with(::Redis::Namespace).and_return(true)
- end
-
- it 'fails with exception' do
- expect { described_class.new(primary_store, secondary_store, instance_name) }.not_to raise_error
- end
- end
-
# rubocop:disable RSpec/MultipleMemoizedHelpers
context 'with READ redis commands' do
subject do
diff --git a/spec/models/ci/catalog/resource_spec.rb b/spec/models/ci/catalog/resource_spec.rb
index cb9152cfd74..9df6c9d663d 100644
--- a/spec/models/ci/catalog/resource_spec.rb
+++ b/spec/models/ci/catalog/resource_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe Ci::Catalog::Resource, feature_category: :pipeline_composition do
let_it_be_with_reload(:project) { create(:project, name: 'A') }
let_it_be(:project_2) { build(:project, name: 'Z') }
- let_it_be(:project_3) { build(:project, name: 'L') }
+ let_it_be(:project_3) { build(:project, name: 'L', description: 'Z') }
let_it_be_with_reload(:resource) { create(:ci_catalog_resource, project: project, latest_released_at: tomorrow) }
let_it_be(:resource_2) { create(:ci_catalog_resource, project: project_2, latest_released_at: today) }
let_it_be(:resource_3) { create(:ci_catalog_resource, project: project_3, latest_released_at: nil) }
@@ -36,6 +36,14 @@ RSpec.describe Ci::Catalog::Resource, feature_category: :pipeline_composition do
end
end
+ describe '.search' do
+ it 'returns catalog resources whose name or description match the search term' do
+ resources = described_class.search('Z')
+
+ expect(resources).to contain_exactly(resource_2, resource_3)
+ end
+ end
+
describe '.order_by_created_at_desc' do
it 'returns catalog resources sorted by descending created at' do
ordered_resources = described_class.order_by_created_at_desc
diff --git a/spec/support/helpers/project_template_test_helper.rb b/spec/support/helpers/project_template_test_helper.rb
index 35e40faeea7..a02cd491bca 100644
--- a/spec/support/helpers/project_template_test_helper.rb
+++ b/spec/support/helpers/project_template_test_helper.rb
@@ -10,6 +10,7 @@ module ProjectTemplateTestHelper
serverless_framework tencent_serverless_framework
jsonnet cluster_management kotlin_native_linux
pelican bridgetown typo3_distribution laravel
+ astro_tailwind
]
end
end
diff --git a/vendor/project_templates/astro_tailwind.tar.gz b/vendor/project_templates/astro_tailwind.tar.gz
new file mode 100644
index 00000000000..4724b01d3f6
--- /dev/null
+++ b/vendor/project_templates/astro_tailwind.tar.gz
Binary files differ