From 36d1ded2d2a4f61fb74ad4fb174d1711d3e72890 Mon Sep 17 00:00:00 2001 From: Leaminn Ma <lma@gitlab.com> Date: Thu, 20 Jul 2023 11:44:36 +0000 Subject: [PATCH] Create catalog_resource_versions table Added migration and model for new table 'catalog_resource_versions' which will contain the versions (i.e. 'releases') of catalog resources that have valid CI components. Changelog: added --- app/models/ci/catalog/resource.rb | 1 + app/models/ci/catalog/resources/version.rb | 21 +++++++++++ app/models/project.rb | 2 + app/models/release.rb | 2 + db/docs/catalog_resource_versions.yml | 8 ++++ ...211305_create_catalog_resource_versions.rb | 13 +++++++ ...release_fk_to_catalog_resource_versions.rb | 15 ++++++++ ...project_fk_to_catalog_resource_versions.rb | 15 ++++++++ ...esource_fk_to_catalog_resource_versions.rb | 16 ++++++++ db/schema_migrations/20230626211305 | 1 + db/schema_migrations/20230626215602 | 1 + db/schema_migrations/20230626215614 | 1 + db/schema_migrations/20230626215638 | 1 + db/structure.sql | 37 +++++++++++++++++++ spec/lib/gitlab/import_export/all_models.yml | 7 ++++ spec/models/ci/catalog/resource_spec.rb | 1 + .../ci/catalog/resources/version_spec.rb | 15 ++++++++ spec/models/project_spec.rb | 1 + spec/models/release_spec.rb | 1 + 19 files changed, 159 insertions(+) create mode 100644 app/models/ci/catalog/resources/version.rb create mode 100644 db/docs/catalog_resource_versions.yml create mode 100644 db/migrate/20230626211305_create_catalog_resource_versions.rb create mode 100644 db/migrate/20230626215602_add_release_fk_to_catalog_resource_versions.rb create mode 100644 db/migrate/20230626215614_add_project_fk_to_catalog_resource_versions.rb create mode 100644 db/migrate/20230626215638_add_catalog_resource_fk_to_catalog_resource_versions.rb create mode 100644 db/schema_migrations/20230626211305 create mode 100644 db/schema_migrations/20230626215602 create mode 100644 db/schema_migrations/20230626215614 create mode 100644 db/schema_migrations/20230626215638 create mode 100644 spec/models/ci/catalog/resources/version_spec.rb diff --git a/app/models/ci/catalog/resource.rb b/app/models/ci/catalog/resource.rb index 38603ddfe59a4..442851f577780 100644 --- a/app/models/ci/catalog/resource.rb +++ b/app/models/ci/catalog/resource.rb @@ -11,6 +11,7 @@ class Resource < ::ApplicationRecord self.table_name = 'catalog_resources' belongs_to :project + has_many :versions, class_name: 'Ci::Catalog::Resources::Version', inverse_of: :catalog_resource scope :for_projects, ->(project_ids) { where(project_id: project_ids) } scope :order_by_created_at_desc, -> { reorder(created_at: :desc) } diff --git a/app/models/ci/catalog/resources/version.rb b/app/models/ci/catalog/resources/version.rb new file mode 100644 index 0000000000000..bef1b6e64cb49 --- /dev/null +++ b/app/models/ci/catalog/resources/version.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Ci + module Catalog + module Resources + # This class represents a CI/CD Catalog resource version. + # Only versions which contain valid CI components are included in this table. + class Version < ::ApplicationRecord + self.table_name = 'catalog_resource_versions' + + belongs_to :release, inverse_of: :catalog_resource_version + belongs_to :catalog_resource, class_name: 'Ci::Catalog::Resource', inverse_of: :versions + belongs_to :project, inverse_of: :catalog_resource_versions + + validates :release, :catalog_resource, :project, presence: true + end + end + end +end + +Ci::Catalog::Resources::Version.prepend_mod_with('Ci::Catalog::Resources::Version') diff --git a/app/models/project.rb b/app/models/project.rb index cd107fb8c35ff..f8c38c1587d06 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -170,6 +170,8 @@ class Project < ApplicationRecord alias_attribute :parent_id, :namespace_id has_one :catalog_resource, class_name: 'Ci::Catalog::Resource', inverse_of: :project + has_many :catalog_resource_versions, class_name: 'Ci::Catalog::Resources::Version', inverse_of: :project + has_one :last_event, -> { order 'events.created_at DESC' }, class_name: 'Event' has_many :boards diff --git a/app/models/release.rb b/app/models/release.rb index f0ba56390ab75..6830f6e848040 100644 --- a/app/models/release.rb +++ b/app/models/release.rb @@ -20,6 +20,8 @@ class Release < ApplicationRecord has_many :milestones, through: :milestone_releases has_many :evidences, inverse_of: :release, class_name: 'Releases::Evidence' + has_one :catalog_resource_version, class_name: 'Ci::Catalog::Resources::Version', inverse_of: :release + accepts_nested_attributes_for :links, allow_destroy: true before_create :set_released_at diff --git a/db/docs/catalog_resource_versions.yml b/db/docs/catalog_resource_versions.yml new file mode 100644 index 0000000000000..f01dcd8a2d663 --- /dev/null +++ b/db/docs/catalog_resource_versions.yml @@ -0,0 +1,8 @@ +--- +table_name: catalog_resource_versions +feature_categories: +- pipeline_composition +description: Catalog resource versions that contain valid CI components. +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/124668 +milestone: '16.2' +gitlab_schema: gitlab_main diff --git a/db/migrate/20230626211305_create_catalog_resource_versions.rb b/db/migrate/20230626211305_create_catalog_resource_versions.rb new file mode 100644 index 0000000000000..9a9aa615ea54a --- /dev/null +++ b/db/migrate/20230626211305_create_catalog_resource_versions.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class CreateCatalogResourceVersions < Gitlab::Database::Migration[2.1] + def change + create_table :catalog_resource_versions do |t| + t.bigint :release_id, null: false, index: { unique: true } + t.bigint :catalog_resource_id, null: false, index: true + t.bigint :project_id, null: false, index: true + + t.datetime_with_timezone :created_at, null: false + end + end +end diff --git a/db/migrate/20230626215602_add_release_fk_to_catalog_resource_versions.rb b/db/migrate/20230626215602_add_release_fk_to_catalog_resource_versions.rb new file mode 100644 index 0000000000000..43dda42f09ef9 --- /dev/null +++ b/db/migrate/20230626215602_add_release_fk_to_catalog_resource_versions.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class AddReleaseFkToCatalogResourceVersions < Gitlab::Database::Migration[2.1] + disable_ddl_transaction! + + def up + add_concurrent_foreign_key :catalog_resource_versions, :releases, column: :release_id, on_delete: :cascade + end + + def down + with_lock_retries do + remove_foreign_key :catalog_resource_versions, column: :release_id + end + end +end diff --git a/db/migrate/20230626215614_add_project_fk_to_catalog_resource_versions.rb b/db/migrate/20230626215614_add_project_fk_to_catalog_resource_versions.rb new file mode 100644 index 0000000000000..115b13700ad5e --- /dev/null +++ b/db/migrate/20230626215614_add_project_fk_to_catalog_resource_versions.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class AddProjectFkToCatalogResourceVersions < Gitlab::Database::Migration[2.1] + disable_ddl_transaction! + + def up + add_concurrent_foreign_key :catalog_resource_versions, :projects, column: :project_id, on_delete: :cascade + end + + def down + with_lock_retries do + remove_foreign_key :catalog_resource_versions, column: :project_id + end + end +end diff --git a/db/migrate/20230626215638_add_catalog_resource_fk_to_catalog_resource_versions.rb b/db/migrate/20230626215638_add_catalog_resource_fk_to_catalog_resource_versions.rb new file mode 100644 index 0000000000000..844fb96cf870b --- /dev/null +++ b/db/migrate/20230626215638_add_catalog_resource_fk_to_catalog_resource_versions.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class AddCatalogResourceFkToCatalogResourceVersions < Gitlab::Database::Migration[2.1] + disable_ddl_transaction! + + def up + add_concurrent_foreign_key :catalog_resource_versions, :catalog_resources, + column: :catalog_resource_id, on_delete: :cascade + end + + def down + with_lock_retries do + remove_foreign_key :catalog_resource_versions, column: :catalog_resource_id + end + end +end diff --git a/db/schema_migrations/20230626211305 b/db/schema_migrations/20230626211305 new file mode 100644 index 0000000000000..bb9cf36e48dff --- /dev/null +++ b/db/schema_migrations/20230626211305 @@ -0,0 +1 @@ +f4e628f28e4d2ad11bcbee48aed5146a0dfdf2745911db3f63de2dca455e69a5 \ No newline at end of file diff --git a/db/schema_migrations/20230626215602 b/db/schema_migrations/20230626215602 new file mode 100644 index 0000000000000..fb64b8c7f66ff --- /dev/null +++ b/db/schema_migrations/20230626215602 @@ -0,0 +1 @@ +6a4ecb8e9f8855cb44b425e16cc89c9146fd4709b5daf322747c3034f11c4cf2 \ No newline at end of file diff --git a/db/schema_migrations/20230626215614 b/db/schema_migrations/20230626215614 new file mode 100644 index 0000000000000..479153c6451ed --- /dev/null +++ b/db/schema_migrations/20230626215614 @@ -0,0 +1 @@ +5c8dbf1b5ad9d41014330eeb07a7daed135a0e9a579d2c15c1f9f0cba83f0bcd \ No newline at end of file diff --git a/db/schema_migrations/20230626215638 b/db/schema_migrations/20230626215638 new file mode 100644 index 0000000000000..b93870e7d7e7b --- /dev/null +++ b/db/schema_migrations/20230626215638 @@ -0,0 +1 @@ +e72aae56b010d9c04fb6a8cc799ae39a817eb4a755f162d2a1157d6d5a8a3131 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index b69f0da4a549c..7da785a45d772 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -12934,6 +12934,23 @@ CREATE SEQUENCE bulk_imports_id_seq ALTER SEQUENCE bulk_imports_id_seq OWNED BY bulk_imports.id; +CREATE TABLE catalog_resource_versions ( + id bigint NOT NULL, + release_id bigint NOT NULL, + catalog_resource_id bigint NOT NULL, + project_id bigint NOT NULL, + created_at timestamp with time zone NOT NULL +); + +CREATE SEQUENCE catalog_resource_versions_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE catalog_resource_versions_id_seq OWNED BY catalog_resource_versions.id; + CREATE TABLE catalog_resources ( id bigint NOT NULL, project_id bigint NOT NULL, @@ -25137,6 +25154,8 @@ ALTER TABLE ONLY bulk_import_trackers ALTER COLUMN id SET DEFAULT nextval('bulk_ ALTER TABLE ONLY bulk_imports ALTER COLUMN id SET DEFAULT nextval('bulk_imports_id_seq'::regclass); +ALTER TABLE ONLY catalog_resource_versions ALTER COLUMN id SET DEFAULT nextval('catalog_resource_versions_id_seq'::regclass); + ALTER TABLE ONLY catalog_resources ALTER COLUMN id SET DEFAULT nextval('catalog_resources_id_seq'::regclass); ALTER TABLE ONLY chat_names ALTER COLUMN id SET DEFAULT nextval('chat_names_id_seq'::regclass); @@ -26963,6 +26982,9 @@ ALTER TABLE ONLY bulk_import_trackers ALTER TABLE ONLY bulk_imports ADD CONSTRAINT bulk_imports_pkey PRIMARY KEY (id); +ALTER TABLE ONLY catalog_resource_versions + ADD CONSTRAINT catalog_resource_versions_pkey PRIMARY KEY (id); + ALTER TABLE ONLY catalog_resources ADD CONSTRAINT catalog_resources_pkey PRIMARY KEY (id); @@ -30392,6 +30414,12 @@ CREATE INDEX index_bulk_import_failures_on_correlation_id_value ON bulk_import_f CREATE INDEX index_bulk_imports_on_user_id ON bulk_imports USING btree (user_id); +CREATE INDEX index_catalog_resource_versions_on_catalog_resource_id ON catalog_resource_versions USING btree (catalog_resource_id); + +CREATE INDEX index_catalog_resource_versions_on_project_id ON catalog_resource_versions USING btree (project_id); + +CREATE UNIQUE INDEX index_catalog_resource_versions_on_release_id ON catalog_resource_versions USING btree (release_id); + CREATE UNIQUE INDEX index_catalog_resources_on_project_id ON catalog_resources USING btree (project_id); CREATE INDEX index_chat_names_on_team_id_and_chat_id ON chat_names USING btree (team_id, chat_id); @@ -35410,6 +35438,9 @@ ALTER TABLE ONLY vulnerabilities ALTER TABLE ONLY vulnerabilities ADD CONSTRAINT fk_131d289c65 FOREIGN KEY (milestone_id) REFERENCES milestones(id) ON DELETE SET NULL; +ALTER TABLE ONLY catalog_resource_versions + ADD CONSTRAINT fk_15376d917e FOREIGN KEY (release_id) REFERENCES releases(id) ON DELETE CASCADE; + ALTER TABLE ONLY sbom_occurrences ADD CONSTRAINT fk_157506c0e2 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; @@ -35815,6 +35846,9 @@ ALTER TABLE ONLY scan_result_policies ALTER TABLE ONLY vulnerabilities ADD CONSTRAINT fk_7ac31eacb9 FOREIGN KEY (updated_by_id) REFERENCES users(id) ON DELETE SET NULL; +ALTER TABLE ONLY catalog_resource_versions + ADD CONSTRAINT fk_7ad8849db4 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; + ALTER TABLE ONLY issue_customer_relations_contacts ADD CONSTRAINT fk_7b92f835bb FOREIGN KEY (contact_id) REFERENCES customer_relations_contacts(id) ON DELETE CASCADE; @@ -36052,6 +36086,9 @@ ALTER TABLE ONLY issues ALTER TABLE ONLY protected_tag_create_access_levels ADD CONSTRAINT fk_b4eb82fe3c FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE; +ALTER TABLE ONLY catalog_resource_versions + ADD CONSTRAINT fk_b670eae96b FOREIGN KEY (catalog_resource_id) REFERENCES catalog_resources(id) ON DELETE CASCADE; + ALTER TABLE ONLY bulk_import_entities ADD CONSTRAINT fk_b69fa2b2df FOREIGN KEY (bulk_import_id) REFERENCES bulk_imports(id) ON DELETE CASCADE; diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 981802ad09d2f..7dc969f274a91 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -162,6 +162,7 @@ releases: - milestone_releases - milestones - evidences +- catalog_resource_version links: - release project_members: @@ -516,6 +517,7 @@ container_repositories: - name project: - catalog_resource +- catalog_resource_versions - external_status_checks - base_tags - project_topics @@ -1039,6 +1041,11 @@ iterations_cadence: - iterations catalog_resource: - project + - catalog_resource_versions +catalog_resource_versions: + - project + - release + - catalog_resource approval_rules: - users - groups diff --git a/spec/models/ci/catalog/resource_spec.rb b/spec/models/ci/catalog/resource_spec.rb index 45d49d65b0242..7af3369ae7b61 100644 --- a/spec/models/ci/catalog/resource_spec.rb +++ b/spec/models/ci/catalog/resource_spec.rb @@ -15,6 +15,7 @@ let_it_be(:release3) { create(:release, project: project, released_at: Time.zone.now) } it { is_expected.to belong_to(:project) } + it { is_expected.to have_many(:versions).class_name('Ci::Catalog::Resources::Version') } it { is_expected.to delegate_method(:avatar_path).to(:project) } it { is_expected.to delegate_method(:description).to(:project) } diff --git a/spec/models/ci/catalog/resources/version_spec.rb b/spec/models/ci/catalog/resources/version_spec.rb new file mode 100644 index 0000000000000..f6abb112820d8 --- /dev/null +++ b/spec/models/ci/catalog/resources/version_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Ci::Catalog::Resources::Version, type: :model, feature_category: :pipeline_composition do + it { is_expected.to belong_to(:release) } + it { is_expected.to belong_to(:catalog_resource).class_name('Ci::Catalog::Resource') } + it { is_expected.to belong_to(:project) } + + describe 'validations' do + it { is_expected.to validate_presence_of(:release) } + it { is_expected.to validate_presence_of(:catalog_resource) } + it { is_expected.to validate_presence_of(:project) } + end +end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 1a7a0688abe98..302fe4098b27b 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -46,6 +46,7 @@ it { is_expected.to have_one(:design_management_repository).class_name('DesignManagement::Repository').inverse_of(:project) } it { is_expected.to have_one(:slack_integration) } it { is_expected.to have_one(:catalog_resource) } + it { is_expected.to have_many(:catalog_resource_versions).class_name('Ci::Catalog::Resources::Version') } it { is_expected.to have_one(:microsoft_teams_integration) } it { is_expected.to have_one(:mattermost_integration) } it { is_expected.to have_one(:hangouts_chat_integration) } diff --git a/spec/models/release_spec.rb b/spec/models/release_spec.rb index 446ef4180d25e..164cef95cb6cd 100644 --- a/spec/models/release_spec.rb +++ b/spec/models/release_spec.rb @@ -17,6 +17,7 @@ it { is_expected.to have_many(:milestones) } it { is_expected.to have_many(:milestone_releases) } it { is_expected.to have_many(:evidences).class_name('Releases::Evidence') } + it { is_expected.to have_one(:catalog_resource_version).class_name('Ci::Catalog::Resources::Version') } end describe 'validation' do -- GitLab