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:
Diffstat (limited to 'app/models/ci')
-rw-r--r--app/models/ci/build.rb7
-rw-r--r--app/models/ci/build_metadata.rb11
-rw-r--r--app/models/ci/catalog/resource.rb5
-rw-r--r--app/models/ci/catalog/resources/version.rb9
-rw-r--r--app/models/ci/pipeline.rb48
-rw-r--r--app/models/ci/stage.rb44
6 files changed, 94 insertions, 30 deletions
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 0bb93a68470..284495a1d97 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -19,7 +19,12 @@ module Ci
belongs_to :runner
belongs_to :trigger_request
belongs_to :erased_by, class_name: 'User'
- belongs_to :pipeline, class_name: 'Ci::Pipeline', foreign_key: :commit_id, inverse_of: :builds
+ belongs_to :pipeline,
+ ->(build) { in_partition(build) },
+ class_name: 'Ci::Pipeline',
+ foreign_key: :commit_id,
+ partition_foreign_key: :partition_id,
+ inverse_of: :builds
RUNNER_FEATURES = {
upload_multiple_artifacts: -> (build) { build.publishes_artifacts_reports? },
diff --git a/app/models/ci/build_metadata.rb b/app/models/ci/build_metadata.rb
index 555565ff621..4194be7c0af 100644
--- a/app/models/ci/build_metadata.rb
+++ b/app/models/ci/build_metadata.rb
@@ -14,9 +14,14 @@ module Ci
self.table_name = 'p_ci_builds_metadata'
self.primary_key = 'id'
+ query_constraints :id, :partition_id
partitionable scope: :build, partitioned: true
- belongs_to :build, class_name: 'CommitStatus'
+ belongs_to :build, # rubocop: disable Rails/InverseOf -- this relation is not present on CommitStatus
+ ->(metadata) { in_partition(metadata) },
+ partition_foreign_key: :partition_id,
+ class_name: 'CommitStatus'
+
belongs_to :project
before_create :set_build_project
@@ -42,6 +47,10 @@ module Ci
job_timeout_source: 4
}
+ def self.use_partition_id_filter?
+ Ci::Pipeline.use_partition_id_filter?
+ end
+
def update_timeout_state
timeout = timeout_with_highest_precedence
diff --git a/app/models/ci/catalog/resource.rb b/app/models/ci/catalog/resource.rb
index 3ead852e834..8bfef225e05 100644
--- a/app/models/ci/catalog/resource.rb
+++ b/app/models/ci/catalog/resource.rb
@@ -50,6 +50,11 @@ module Ci
save!
end
+ # Triggered in Ci::Catalog::Resources::Version and Release model callbacks.
+ def update_latest_released_at!
+ update!(latest_released_at: versions.latest&.released_at)
+ end
+
private
# These columns are denormalized from the `projects` table. We first sync these
diff --git a/app/models/ci/catalog/resources/version.rb b/app/models/ci/catalog/resources/version.rb
index bd0ebc77a6d..ab4d5c52526 100644
--- a/app/models/ci/catalog/resources/version.rb
+++ b/app/models/ci/catalog/resources/version.rb
@@ -28,6 +28,9 @@ module Ci
delegate :name, :description, :tag, :sha, :released_at, :author_id, to: :release
+ after_destroy :update_catalog_resource
+ after_save :update_catalog_resource
+
class << self
# In the future, we should support semantic versioning.
# See https://gitlab.com/gitlab-org/gitlab/-/issues/427286
@@ -110,6 +113,12 @@ module Ci
end
end
end
+
+ private
+
+ def update_catalog_resource
+ catalog_resource.update_latest_released_at!
+ end
end
end
end
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 54aa3d78cf3..faa79f8f49c 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -80,31 +80,31 @@ module Ci
# Ci:Job models. With that epic, we aim to replace `statuses` with `jobs`.
#
# DEPRECATED:
- has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id, inverse_of: :pipeline
- has_many :processables, class_name: 'Ci::Processable', foreign_key: :commit_id, inverse_of: :pipeline
- has_many :latest_statuses_ordered_by_stage, -> { latest.order(:stage_idx, :stage) }, class_name: 'CommitStatus', foreign_key: :commit_id, inverse_of: :pipeline
- has_many :latest_statuses, -> { latest }, class_name: 'CommitStatus', foreign_key: :commit_id, inverse_of: :pipeline
- has_many :statuses_order_id_desc, -> { order_id_desc }, class_name: 'CommitStatus', foreign_key: :commit_id,
- inverse_of: :pipeline
- has_many :bridges, class_name: 'Ci::Bridge', foreign_key: :commit_id, inverse_of: :pipeline
- has_many :builds, foreign_key: :commit_id, inverse_of: :pipeline
- has_many :generic_commit_statuses, foreign_key: :commit_id, inverse_of: :pipeline, class_name: 'GenericCommitStatus'
+ has_many :statuses, ->(pipeline) { in_partition(pipeline) }, class_name: 'CommitStatus', foreign_key: :commit_id, inverse_of: :pipeline, partition_foreign_key: :partition_id
+ has_many :processables, ->(pipeline) { in_partition(pipeline) }, class_name: 'Ci::Processable', foreign_key: :commit_id, inverse_of: :pipeline, partition_foreign_key: :partition_id
+ has_many :latest_statuses_ordered_by_stage, -> (pipeline) { latest.in_partition(pipeline).order(:stage_idx, :stage) }, class_name: 'CommitStatus', foreign_key: :commit_id, inverse_of: :pipeline, partition_foreign_key: :partition_id
+ has_many :latest_statuses, ->(pipeline) { latest.in_partition(pipeline) }, class_name: 'CommitStatus', foreign_key: :commit_id, inverse_of: :pipeline, partition_foreign_key: :partition_id
+ has_many :statuses_order_id_desc, ->(pipeline) { in_partition(pipeline).order_id_desc }, class_name: 'CommitStatus', foreign_key: :commit_id,
+ inverse_of: :pipeline, partition_foreign_key: :partition_id
+ has_many :bridges, ->(pipeline) { in_partition(pipeline) }, class_name: 'Ci::Bridge', foreign_key: :commit_id, inverse_of: :pipeline, partition_foreign_key: :partition_id
+ has_many :builds, ->(pipeline) { in_partition(pipeline) }, foreign_key: :commit_id, inverse_of: :pipeline, partition_foreign_key: :partition_id
+ has_many :generic_commit_statuses, ->(pipeline) { in_partition(pipeline) }, foreign_key: :commit_id, inverse_of: :pipeline, class_name: 'GenericCommitStatus', partition_foreign_key: :partition_id
#
# NEW:
- has_many :all_jobs, class_name: 'CommitStatus', foreign_key: :commit_id, inverse_of: :pipeline
- has_many :current_jobs, -> { latest }, class_name: 'CommitStatus', foreign_key: :commit_id, inverse_of: :pipeline
- has_many :all_processable_jobs, class_name: 'Ci::Processable', foreign_key: :commit_id, inverse_of: :pipeline
- has_many :current_processable_jobs, -> { latest }, class_name: 'Ci::Processable', foreign_key: :commit_id, inverse_of: :pipeline
+ has_many :all_jobs, ->(pipeline) { in_partition(pipeline) }, class_name: 'CommitStatus', foreign_key: :commit_id, inverse_of: :pipeline, partition_foreign_key: :partition_id
+ has_many :current_jobs, ->(pipeline) { latest.in_partition(pipeline) }, class_name: 'CommitStatus', foreign_key: :commit_id, inverse_of: :pipeline, partition_foreign_key: :partition_id
+ has_many :all_processable_jobs, ->(pipeline) { in_partition(pipeline) }, class_name: 'Ci::Processable', foreign_key: :commit_id, inverse_of: :pipeline, partition_foreign_key: :partition_id
+ has_many :current_processable_jobs, ->(pipeline) { latest.in_partition(pipeline) }, class_name: 'Ci::Processable', foreign_key: :commit_id, inverse_of: :pipeline, partition_foreign_key: :partition_id
has_many :job_artifacts, through: :builds
has_many :build_trace_chunks, class_name: 'Ci::BuildTraceChunk', through: :builds, source: :trace_chunks
has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id, inverse_of: :pipeline # rubocop:disable Cop/ActiveRecordDependent
has_many :variables, class_name: 'Ci::PipelineVariable'
- has_many :latest_builds, -> { latest.with_project_and_metadata }, foreign_key: :commit_id, inverse_of: :pipeline, class_name: 'Ci::Build'
+ has_many :latest_builds, ->(pipeline) { in_partition(pipeline).latest.with_project_and_metadata }, foreign_key: :commit_id, inverse_of: :pipeline, class_name: 'Ci::Build'
has_many :downloadable_artifacts, -> do
not_expired.or(where_exists(Ci::Pipeline.artifacts_locked.where("#{Ci::Pipeline.quoted_table_name}.id = #{Ci::Build.quoted_table_name}.commit_id"))).downloadable.with_job
end, through: :latest_builds, source: :job_artifacts
- has_many :latest_successful_jobs, -> { latest.success.with_project_and_metadata }, foreign_key: :commit_id, inverse_of: :pipeline, class_name: 'Ci::Processable'
+ has_many :latest_successful_jobs, ->(pipeline) { in_partition(pipeline).latest.success.with_project_and_metadata }, foreign_key: :commit_id, inverse_of: :pipeline, class_name: 'Ci::Processable'
has_many :messages, class_name: 'Ci::PipelineMessage', inverse_of: :pipeline
@@ -113,14 +113,14 @@ module Ci
has_many :merge_requests_as_head_pipeline, foreign_key: :head_pipeline_id, class_name: 'MergeRequest',
inverse_of: :head_pipeline
- has_many :pending_builds, -> { pending }, foreign_key: :commit_id, class_name: 'Ci::Build', inverse_of: :pipeline
- has_many :failed_builds, -> { latest.failed }, foreign_key: :commit_id, class_name: 'Ci::Build',
+ has_many :pending_builds, ->(pipeline) { in_partition(pipeline).pending }, foreign_key: :commit_id, class_name: 'Ci::Build', inverse_of: :pipeline
+ has_many :failed_builds, ->(pipeline) { in_partition(pipeline).latest.failed }, foreign_key: :commit_id, class_name: 'Ci::Build',
inverse_of: :pipeline
- has_many :retryable_builds, -> { latest.failed_or_canceled.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Build', inverse_of: :pipeline
- has_many :cancelable_statuses, -> { cancelable }, foreign_key: :commit_id, class_name: 'CommitStatus',
+ has_many :retryable_builds, ->(pipeline) { in_partition(pipeline).latest.failed_or_canceled.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Build', inverse_of: :pipeline
+ has_many :cancelable_statuses, ->(pipeline) { in_partition(pipeline).cancelable }, foreign_key: :commit_id, class_name: 'CommitStatus',
inverse_of: :pipeline
- has_many :manual_actions, -> { latest.manual_actions.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Processable', inverse_of: :pipeline
- has_many :scheduled_actions, -> { latest.scheduled_actions.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Build', inverse_of: :pipeline
+ has_many :manual_actions, ->(pipeline) { in_partition(pipeline).latest.manual_actions.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Processable', inverse_of: :pipeline
+ has_many :scheduled_actions, ->(pipeline) { in_partition(pipeline).latest.scheduled_actions.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Build', inverse_of: :pipeline
has_many :auto_canceled_pipelines, class_name: 'Ci::Pipeline', foreign_key: :auto_canceled_by_id,
inverse_of: :auto_canceled_by
@@ -605,6 +605,12 @@ module Ci
::Gitlab::Ci::PipelineObjectHierarchy.new(relation, options: options)
end
+ def self.use_partition_id_filter?
+ ::Gitlab::SafeRequestStore.fetch(:ci_builds_partition_id_query_filter) do
+ ::Feature.enabled?(:ci_builds_partition_id_query_filter)
+ end
+ end
+
def uses_needs?
processables.where(scheduling_type: :dag).any?
end
diff --git a/app/models/ci/stage.rb b/app/models/ci/stage.rb
index 3d2df9a45ef..e413ed8a668 100644
--- a/app/models/ci/stage.rb
+++ b/app/models/ci/stage.rb
@@ -21,19 +21,45 @@ module Ci
belongs_to :project
belongs_to :pipeline
- has_many :statuses, class_name: 'CommitStatus', foreign_key: :stage_id, inverse_of: :ci_stage
- has_many :latest_statuses, -> { ordered.latest },
+ has_many :statuses,
+ ->(stage) { in_partition(stage) },
class_name: 'CommitStatus',
foreign_key: :stage_id,
+ partition_foreign_key: :partition_id,
inverse_of: :ci_stage
- has_many :retried_statuses, -> { ordered.retried },
+ has_many :latest_statuses,
+ ->(stage) { in_partition(stage).ordered.latest },
class_name: 'CommitStatus',
foreign_key: :stage_id,
+ partition_foreign_key: :partition_id,
+ inverse_of: :ci_stage
+ has_many :retried_statuses,
+ ->(stage) { in_partition(stage).ordered.retried },
+ class_name: 'CommitStatus',
+ foreign_key: :stage_id,
+ partition_foreign_key: :partition_id,
+ inverse_of: :ci_stage
+ has_many :processables,
+ ->(stage) { in_partition(stage) },
+ class_name: 'Ci::Processable',
+ foreign_key: :stage_id,
+ partition_foreign_key: :partition_id,
+ inverse_of: :ci_stage
+ has_many :builds,
+ ->(stage) { in_partition(stage) },
+ foreign_key: :stage_id,
+ partition_foreign_key: :partition_id,
+ inverse_of: :ci_stage
+ has_many :bridges,
+ ->(stage) { in_partition(stage) },
+ foreign_key: :stage_id,
+ partition_foreign_key: :partition_id,
+ inverse_of: :ci_stage
+ has_many :generic_commit_statuses,
+ ->(stage) { in_partition(stage) },
+ foreign_key: :stage_id,
+ partition_foreign_key: :partition_id,
inverse_of: :ci_stage
- has_many :processables, class_name: 'Ci::Processable', foreign_key: :stage_id, inverse_of: :ci_stage
- has_many :builds, foreign_key: :stage_id, inverse_of: :ci_stage
- has_many :bridges, foreign_key: :stage_id, inverse_of: :ci_stage
- has_many :generic_commit_statuses, foreign_key: :stage_id, inverse_of: :ci_stage
scope :ordered, -> { order(position: :asc) }
scope :in_pipelines, ->(pipelines) { where(pipeline: pipelines) }
@@ -107,6 +133,10 @@ module Ci
end
end
+ def self.use_partition_id_filter?
+ Ci::Pipeline.use_partition_id_filter?
+ end
+
def set_status(new_status)
retry_optimistic_lock(self, name: 'ci_stage_set_status') do
case new_status