diff --git a/app/models/ci/catalog/verified_namespace.rb b/app/models/ci/catalog/verified_namespace.rb new file mode 100644 index 0000000000000000000000000000000000000000..b5bb28c04cf68c62cc414d0dc86faec247389449 --- /dev/null +++ b/app/models/ci/catalog/verified_namespace.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Ci + module Catalog + class VerifiedNamespace < ::ApplicationRecord + self.table_name = 'catalog_verified_namespaces' + + belongs_to :namespace + + enum verification_level: { gitlab_maintained: 100, partner: 50, verified_creator: 10, unverified: 0 } + + validates :namespace_id, presence: true, uniqueness: true + end + end +end diff --git a/app/models/namespace.rb b/app/models/namespace.rb index 9020f90fd3c48e2b44b6e3174958b38b8cd52452..bb1f77680ff4c9e33198b7f70d9c04f37b7ad902 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -53,6 +53,8 @@ class Namespace < ApplicationRecord has_one :namespace_details, inverse_of: :namespace, class_name: 'Namespace::Detail', autosave: true has_one :namespace_statistics has_one :namespace_route, foreign_key: :namespace_id, autosave: false, inverse_of: :namespace, class_name: 'Route' + has_one :catalog_verified_namespace, class_name: 'Ci::Catalog::VerifiedNamespace', inverse_of: :namespace + has_many :namespace_members, foreign_key: :member_namespace_id, inverse_of: :member_namespace, class_name: 'Member' has_one :namespace_ldap_settings, inverse_of: :namespace, class_name: 'Namespaces::LdapSetting', autosave: true diff --git a/db/docs/catalog_verified_namespaces.yml b/db/docs/catalog_verified_namespaces.yml new file mode 100644 index 0000000000000000000000000000000000000000..f29985385f0c952ca0ee0843e459283df72b2204 --- /dev/null +++ b/db/docs/catalog_verified_namespaces.yml @@ -0,0 +1,10 @@ +--- +table_name: catalog_verified_namespaces +feature_categories: +- pipeline_composition +description: Verified namespaces in the CI catalog. +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/143003 +milestone: '16.9' +gitlab_schema: gitlab_main_cell +sharding_key: + namespace_id: namespaces diff --git a/db/migrate/20240131052824_create_catalog_verified_namespaces.rb b/db/migrate/20240131052824_create_catalog_verified_namespaces.rb new file mode 100644 index 0000000000000000000000000000000000000000..f4ea2680be1a2e015dab37a3d3dbcda10f90729f --- /dev/null +++ b/db/migrate/20240131052824_create_catalog_verified_namespaces.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class CreateCatalogVerifiedNamespaces < Gitlab::Database::Migration[2.2] + milestone '16.9' + + def change + create_table :catalog_verified_namespaces do |t| + t.references :namespace, index: { unique: true }, null: false, foreign_key: { on_delete: :cascade } + t.datetime_with_timezone :created_at, null: false + t.integer :verification_level, null: false, limit: 2, default: 0 + end + end +end diff --git a/db/schema_migrations/20240131052824 b/db/schema_migrations/20240131052824 new file mode 100644 index 0000000000000000000000000000000000000000..06a9ed151b673cebb6b091bd36335f4801fefcb4 --- /dev/null +++ b/db/schema_migrations/20240131052824 @@ -0,0 +1 @@ +8cd70cd24b3e578afdac5c3962335777fb6daa66fa84903b08e5c2e6edbb2b76 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index f46c5208840a65929a72bbe77fde9a4651c763a4..a1abb5092b7cff3580381d94b2349463ba2169a2 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -14069,6 +14069,22 @@ CREATE SEQUENCE catalog_resources_id_seq ALTER SEQUENCE catalog_resources_id_seq OWNED BY catalog_resources.id; +CREATE TABLE catalog_verified_namespaces ( + id bigint NOT NULL, + namespace_id bigint NOT NULL, + created_at timestamp with time zone NOT NULL, + verification_level smallint DEFAULT 0 NOT NULL +); + +CREATE SEQUENCE catalog_verified_namespaces_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE catalog_verified_namespaces_id_seq OWNED BY catalog_verified_namespaces.id; + CREATE TABLE chat_names ( id integer NOT NULL, user_id integer NOT NULL, @@ -27061,6 +27077,8 @@ ALTER TABLE ONLY catalog_resource_versions ALTER COLUMN id SET DEFAULT nextval(' ALTER TABLE ONLY catalog_resources ALTER COLUMN id SET DEFAULT nextval('catalog_resources_id_seq'::regclass); +ALTER TABLE ONLY catalog_verified_namespaces ALTER COLUMN id SET DEFAULT nextval('catalog_verified_namespaces_id_seq'::regclass); + ALTER TABLE ONLY chat_names ALTER COLUMN id SET DEFAULT nextval('chat_names_id_seq'::regclass); ALTER TABLE ONLY chat_teams ALTER COLUMN id SET DEFAULT nextval('chat_teams_id_seq'::regclass); @@ -29078,6 +29096,9 @@ ALTER TABLE ONLY catalog_resource_versions ALTER TABLE ONLY catalog_resources ADD CONSTRAINT catalog_resources_pkey PRIMARY KEY (id); +ALTER TABLE ONLY catalog_verified_namespaces + ADD CONSTRAINT catalog_verified_namespaces_pkey PRIMARY KEY (id); + ALTER TABLE ONLY chat_names ADD CONSTRAINT chat_names_pkey PRIMARY KEY (id); @@ -32896,6 +32917,8 @@ CREATE INDEX index_catalog_resources_on_search_vector ON catalog_resources USING CREATE INDEX index_catalog_resources_on_state ON catalog_resources USING btree (state); +CREATE UNIQUE INDEX index_catalog_verified_namespaces_on_namespace_id ON catalog_verified_namespaces USING btree (namespace_id); + CREATE INDEX index_chat_names_on_team_id_and_chat_id ON chat_names USING btree (team_id, chat_id); CREATE INDEX index_chat_names_on_user_id ON chat_names USING btree (user_id); @@ -39600,6 +39623,9 @@ ALTER TABLE ONLY vulnerability_user_mentions ALTER TABLE ONLY packages_debian_file_metadata ADD CONSTRAINT fk_rails_1ae85be112 FOREIGN KEY (package_file_id) REFERENCES packages_package_files(id) ON DELETE CASCADE; +ALTER TABLE ONLY catalog_verified_namespaces + ADD CONSTRAINT fk_rails_1b6bb852c0 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; + ALTER TABLE ONLY issuable_slas ADD CONSTRAINT fk_rails_1b8768cd63 FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE; diff --git a/spec/factories/ci/catalog/verified_namspaces.rb b/spec/factories/ci/catalog/verified_namspaces.rb new file mode 100644 index 0000000000000000000000000000000000000000..e5d554de142764199fa15700508cce8e3a58018c --- /dev/null +++ b/spec/factories/ci/catalog/verified_namspaces.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :catalog_verified_namespace, class: 'Ci::Catalog::VerifiedNamespace' do + namespace factory: :namespace + + trait :gitlab_maintained do + verification_level { :gitlab_maintained } + end + + trait :partner do + verification_level { :partner } + end + + trait :verified_creator do + verification_level { :verified_creator } + end + end +end diff --git a/spec/models/ci/catalog/verified_namespace_spec.rb b/spec/models/ci/catalog/verified_namespace_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..ac1d0dca9790a361724245ce821778f55c5f4e9f --- /dev/null +++ b/spec/models/ci/catalog/verified_namespace_spec.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Ci::Catalog::VerifiedNamespace, feature_category: :pipeline_composition do + context 'when gitlab maintained namespace is created' do + let_it_be(:gitlab_catalog_namespace) { create(:catalog_verified_namespace, :gitlab_maintained) } + + it 'sets verification level to gitlab maintained' do + expect(gitlab_catalog_namespace.verification_level).to eq('gitlab_maintained') + end + end + + context 'when partner namespace is created' do + let_it_be(:partner_catalog_namespace) { create(:catalog_verified_namespace, :partner) } + + it 'sets verification level to partner' do + expect(partner_catalog_namespace.verification_level).to eq('partner') + end + end + + context 'when verfied creator namespace is created' do + let_it_be(:verified_creator_catalog_namespace) { create(:catalog_verified_namespace, :verified_creator) } + + it 'sets verification level to verified_creator' do + expect(verified_creator_catalog_namespace.verification_level).to eq('verified_creator') + end + end + + it do + is_expected.to define_enum_for(:verification_level) + .with_values({ gitlab_maintained: 100, partner: 50, verified_creator: 10, unverified: 0 }) + end + + describe 'validations' do + let(:verified_namespace) { subject } + + it { is_expected.to validate_presence_of(:namespace_id) } + it { is_expected.to belong_to(:namespace) } + + it do + verified_namespace.namespace_id = create(:namespace).id + is_expected.to validate_uniqueness_of(:namespace_id) + end + end +end diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb index 67b8931f0c5220815e524a546176297af622215c..a28e8b42d67076c08c09b70a27bc9bf06d0e2ab2 100644 --- a/spec/models/namespace_spec.rb +++ b/spec/models/namespace_spec.rb @@ -25,6 +25,7 @@ it { is_expected.to have_one :namespace_settings } it { is_expected.to have_one :namespace_details } it { is_expected.to have_one(:namespace_statistics) } + it { is_expected.to have_one(:catalog_verified_namespace) } it { is_expected.to have_many :custom_emoji } it { is_expected.to have_one :package_setting_relation } it { is_expected.to have_one :onboarding_progress }