Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
0a0c5aaca5
commit
b21334799a
1
Gemfile
1
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
|
||||
|
|
|
|||
|
|
@ -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"},
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) }
|
||||
|
|
|
|||
|
|
@ -111,6 +111,10 @@ module Releases
|
|||
|
||||
# overridden in EE
|
||||
def project_group_id; end
|
||||
|
||||
def audit(release, action:)
|
||||
# overridden in EE
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
fd51e236973eaf1d4a2719eaa34dbd7955c2d73e37adf244472c8c69fc486fdf
|
||||
|
|
@ -0,0 +1 @@
|
|||
7dc72ca807126bb992c22879a6d989f282e442ff2c6e15b046e6f3d0f464237f
|
||||
|
|
@ -0,0 +1 @@
|
|||
4de438a35ae2cbeee4cec03961cf7b5dddfcce2454a1e3ce08985e28b7065a0d
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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!
|
||||
|
|
|
|||
|
|
@ -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 ""
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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 () => {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue