Skip to content
Snippets Groups Projects
Commit cbde1583 authored by Kyle Edwards's avatar Kyle Edwards Committed by euko
Browse files

Add ci_job_annotations table

Changelog: added
Issue: #38337
parent 0dc5bd16
No related branches found
No related tags found
2 merge requests!119439Draft: Prevent file variable content expansion in downstream pipeline,!117319Add ci_job_annotations table
Showing
with 213 additions and 1 deletion
......@@ -48,6 +48,7 @@ class Build < Ci::Processable
# Details: https://gitlab.com/gitlab-org/gitlab/-/issues/24644#note_689472685
has_many :job_artifacts, class_name: 'Ci::JobArtifact', foreign_key: :job_id, dependent: :destroy, inverse_of: :job # rubocop:disable Cop/ActiveRecordDependent
has_many :job_variables, class_name: 'Ci::JobVariable', foreign_key: :job_id, inverse_of: :job
has_many :job_annotations, class_name: 'Ci::JobAnnotation', foreign_key: :job_id, inverse_of: :job
has_many :sourced_pipelines, class_name: 'Ci::Sources::Pipeline', foreign_key: :source_job_id, inverse_of: :build
has_many :pages_deployments, foreign_key: :ci_build_id, inverse_of: :ci_build
......
# frozen_string_literal: true
module Ci
class JobAnnotation < Ci::ApplicationRecord
include Ci::Partitionable
self.table_name = :p_ci_job_annotations
self.primary_key = :id
belongs_to :job, class_name: 'Ci::Build', inverse_of: :job_annotations
partitionable scope: :job, partitioned: true
validates :data, json_schema: { filename: 'ci_job_annotation_data' }
validates :name, presence: true,
length: { maximum: 255 },
uniqueness: { scope: [:job_id, :partition_id] }
end
end
......@@ -31,6 +31,7 @@ module Testing
Ci::BuildTraceChunk
Ci::BuildTraceMetadata
Ci::BuildPendingState
Ci::JobAnnotation
Ci::JobArtifact
Ci::JobVariable
Ci::Pipeline
......
{
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Build annotation",
"type": "array",
"items": {
"anyOf": [
{
"type": "object",
"properties": {
"external_link": {
"$ref": "./ci_job_external_link_data.json"
}
},
"additionalProperties": false
}
]
},
"maxItems": 1000
}
{
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Build annotation external link",
"properties": {
"label": {
"type": "string"
},
"url": {
"type": "string"
}
},
"additionalProperties": false
}
......@@ -6,7 +6,8 @@
WebHookLog,
LooseForeignKeys::DeletedRecord,
Gitlab::Database::BackgroundMigration::BatchedJobTransitionLog,
Ci::RunnerManagerBuild
Ci::RunnerManagerBuild,
Ci::JobAnnotation
])
if Gitlab.ee?
......
---
table_name: p_ci_job_annotations
classes:
- Ci::JobAnnotation
feature_categories:
- build_artifacts
description: Stores user provided annotations for jobs. Currently storing extra information for a given job feed by API.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/117319
gitlab_schema: gitlab_ci
# frozen_string_literal: true
class AddCiJobAnnotationsTable < Gitlab::Database::Migration[2.1]
enable_lock_retries!
def change
options = {
primary_key: [:id, :partition_id],
options: 'PARTITION BY LIST (partition_id)',
if_not_exists: true
}
create_table(:p_ci_job_annotations, **options) do |t|
t.bigserial :id, null: false
t.bigint :partition_id, null: false
t.bigint :job_id, null: false
t.text :name, null: false, limit: 255
t.jsonb :data, default: [], null: false
end
end
end
# frozen_string_literal: true
class AddIndexOnCiJobAnnotations < Gitlab::Database::Migration[2.1]
include Gitlab::Database::PartitioningMigrationHelpers
disable_ddl_transaction!
INDEX_NAME = 'index_p_ci_job_annotations_on_partition_id_job_id_name'
def up
add_concurrent_partitioned_index(
:p_ci_job_annotations,
[:partition_id, :job_id, :name],
name: INDEX_NAME,
unique: true
)
end
def down
remove_concurrent_partitioned_index_by_name :p_ci_job_annotations, INDEX_NAME
end
end
# frozen_string_literal: true
class AddCheckConstraintsToCiJobAnnotations < Gitlab::Database::Migration[2.1]
disable_ddl_transaction!
def up
add_check_constraint(
:p_ci_job_annotations,
"(jsonb_typeof(data) = 'array')",
'data_is_array'
)
end
def down
remove_check_constraint :p_ci_job_annotations, 'data_is_array'
end
end
# frozen_string_literal: true
class CreateCiJobAnnotationsPartitions < Gitlab::Database::Migration[2.1]
enable_lock_retries!
def up
connection.execute(<<~SQL)
CREATE TABLE IF NOT EXISTS gitlab_partitions_dynamic.ci_job_annotations_100
PARTITION OF p_ci_job_annotations
FOR VALUES IN (100);
SQL
end
def down
connection.execute(<<~SQL)
DROP TABLE IF EXISTS gitlab_partitions_dynamic.ci_job_annotations_100;
SQL
end
end
# frozen_string_literal: true
class AddCiJobAnnotationsForeignKey < Gitlab::Database::Migration[2.1]
include Gitlab::Database::PartitioningMigrationHelpers
disable_ddl_transaction!
def up
add_concurrent_partitioned_foreign_key(
:p_ci_job_annotations, :p_ci_builds,
column: [:partition_id, :job_id],
target_column: [:partition_id, :id],
on_update: :cascade,
on_delete: :cascade,
reverse_lock_order: true
)
end
def down
remove_foreign_key_if_exists :p_ci_job_annotations, :p_ci_builds
end
end
b806f1e1cd7aed2400b8cdfae6abaa0a71ea4ac3e3280fb7b188104356b14eef
\ No newline at end of file
ba5e05f3be87f4e7176eadb1f560fd7da45ab5a44d2928c811316a6ddef2c798
\ No newline at end of file
78c1ea40259ac9f6d4087d24ce5f3b4be13009a93c8fab88594bcd64859c7ec5
\ No newline at end of file
8b9382a9d76f6decebb19a8268c58bd3ee2bb9a83b2d79e541e47987211e41f7
\ No newline at end of file
28a1bb5c35d928096f8a6165747934f1d76d9ebcc5fa6891ffc66de6f7413bfe
\ No newline at end of file
......@@ -564,6 +564,17 @@ CREATE TABLE batched_background_migration_job_transition_logs (
)
PARTITION BY RANGE (created_at);
 
CREATE TABLE p_ci_job_annotations (
id bigint NOT NULL,
partition_id bigint NOT NULL,
job_id bigint NOT NULL,
name text NOT NULL,
data jsonb DEFAULT '[]'::jsonb NOT NULL,
CONSTRAINT check_bac9224e45 CHECK ((char_length(name) <= 255)),
CONSTRAINT data_is_array CHECK ((jsonb_typeof(data) = 'array'::text))
)
PARTITION BY LIST (partition_id);
CREATE TABLE p_ci_runner_machine_builds (
partition_id bigint NOT NULL,
build_id bigint NOT NULL,
......@@ -19324,6 +19335,15 @@ CREATE SEQUENCE organizations_id_seq
 
ALTER SEQUENCE organizations_id_seq OWNED BY organizations.id;
 
CREATE SEQUENCE p_ci_job_annotations_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE p_ci_job_annotations_id_seq OWNED BY p_ci_job_annotations.id;
CREATE TABLE packages_build_infos (
id bigint NOT NULL,
package_id integer NOT NULL,
......@@ -25616,6 +25636,8 @@ ALTER TABLE ONLY p_ci_builds ALTER COLUMN id SET DEFAULT nextval('ci_builds_id_s
 
ALTER TABLE ONLY p_ci_builds_metadata ALTER COLUMN id SET DEFAULT nextval('ci_builds_metadata_id_seq'::regclass);
 
ALTER TABLE ONLY p_ci_job_annotations ALTER COLUMN id SET DEFAULT nextval('p_ci_job_annotations_id_seq'::regclass);
ALTER TABLE ONLY packages_build_infos ALTER COLUMN id SET DEFAULT nextval('packages_build_infos_id_seq'::regclass);
 
ALTER TABLE ONLY packages_composer_cache_files ALTER COLUMN id SET DEFAULT nextval('packages_composer_cache_files_id_seq'::regclass);
......@@ -27864,6 +27886,9 @@ ALTER TABLE ONLY operations_user_lists
ALTER TABLE ONLY organizations
ADD CONSTRAINT organizations_pkey PRIMARY KEY (id);
 
ALTER TABLE ONLY p_ci_job_annotations
ADD CONSTRAINT p_ci_job_annotations_pkey PRIMARY KEY (id, partition_id);
ALTER TABLE ONLY p_ci_runner_machine_builds
ADD CONSTRAINT p_ci_runner_machine_builds_pkey PRIMARY KEY (build_id, partition_id);
 
......@@ -32111,6 +32136,8 @@ CREATE UNIQUE INDEX index_ops_strategies_user_lists_on_strategy_id_and_user_list
 
CREATE UNIQUE INDEX index_organizations_on_unique_name_per_group ON customer_relations_organizations USING btree (group_id, lower(name), id);
 
CREATE UNIQUE INDEX index_p_ci_job_annotations_on_partition_id_job_id_name ON ONLY p_ci_job_annotations USING btree (partition_id, job_id, name);
CREATE INDEX index_p_ci_runner_machine_builds_on_runner_machine_id ON ONLY p_ci_runner_machine_builds USING btree (runner_machine_id);
 
CREATE INDEX index_packages_build_infos_on_pipeline_id ON packages_build_infos USING btree (pipeline_id);
......@@ -37750,6 +37777,9 @@ ALTER TABLE ONLY alert_management_alert_assignees
ALTER TABLE ONLY geo_hashed_storage_attachments_events
ADD CONSTRAINT fk_rails_d496b088e9 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
ALTER TABLE p_ci_job_annotations
ADD CONSTRAINT fk_rails_d4d0c0fa0f FOREIGN KEY (partition_id, job_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
ALTER TABLE ONLY packages_rpm_repository_files
ADD CONSTRAINT fk_rails_d545cfaed2 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
# frozen_string_literal: true
FactoryBot.define do
factory :ci_job_annotation, class: 'Ci::JobAnnotation' do
sequence(:name) { |n| "annotation_#{n}" }
job factory: :ci_build
trait :external_link do
data { [{ external_link: { label: 'Example URL', url: 'https://example.com/' } }] }
end
end
end
......@@ -424,6 +424,7 @@ builds:
- dast_site_profile
- dast_scanner_profiles_build
- dast_scanner_profile
- job_annotations
bridges:
- user
- pipeline
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment