diff options
Diffstat (limited to 'app/models/ci/pipeline.rb')
-rw-r--r-- | app/models/ci/pipeline.rb | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 5db1635f64d..497e1a4d74a 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -31,6 +31,7 @@ module Ci belongs_to :pipeline_schedule, class_name: 'Ci::PipelineSchedule' belongs_to :merge_request, class_name: 'MergeRequest' belongs_to :external_pull_request + belongs_to :ci_ref, class_name: 'Ci::Ref', foreign_key: :ci_ref_id, inverse_of: :pipelines has_internal_id :iid, scope: :project, presence: false, track_if: -> { !importing? }, ensure_if: -> { !importing? }, init: ->(s) do s&.project&.all_pipelines&.maximum(:iid) || s&.project&.all_pipelines&.count @@ -40,11 +41,15 @@ module Ci has_many :statuses, class_name: 'CommitStatus', 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 :processables, class_name: 'Ci::Processable', 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 :job_artifacts, through: :builds has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id # rubocop:disable Cop/ActiveRecordDependent has_many :variables, class_name: 'Ci::PipelineVariable' has_many :deployments, through: :builds has_many :environments, -> { distinct }, through: :deployments + has_many :latest_builds, -> { latest }, foreign_key: :commit_id, inverse_of: :pipeline, class_name: 'Ci::Build' + has_many :downloadable_artifacts, -> { not_expired.downloadable }, through: :latest_builds, source: :job_artifacts # Merge requests for which the current pipeline is running against # the merge request's latest commit. @@ -56,7 +61,6 @@ module Ci has_many :cancelable_statuses, -> { cancelable }, foreign_key: :commit_id, class_name: 'CommitStatus' has_many :manual_actions, -> { latest.manual_actions.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Build' has_many :scheduled_actions, -> { latest.scheduled_actions.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Build' - has_many :artifacts, -> { latest.with_artifacts_not_expired.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Build' has_many :auto_canceled_pipelines, class_name: 'Ci::Pipeline', foreign_key: 'auto_canceled_by_id' has_many :auto_canceled_jobs, class_name: 'CommitStatus', foreign_key: 'auto_canceled_by_id' @@ -64,13 +68,6 @@ module Ci has_one :source_pipeline, class_name: 'Ci::Sources::Pipeline', inverse_of: :pipeline - has_one :ref_status, ->(pipeline) { - # We use .read_attribute to save 1 extra unneeded query to load the :project. - unscope(:where) - .where(project_id: pipeline.read_attribute(:project_id), ref: pipeline.ref, tag: pipeline.tag) - # Sadly :inverse_of is not supported (yet) by Rails for composite PKs. - }, class_name: 'Ci::Ref', inverse_of: :pipelines - has_one :chat_data, class_name: 'Ci::PipelineChatData' has_many :triggered_pipelines, through: :sourced_pipelines, source: :pipeline @@ -163,11 +160,11 @@ module Ci # Create a separate worker for each new operation before_transition [:created, :waiting_for_resource, :preparing, :pending] => :running do |pipeline| - pipeline.started_at = Time.now + pipeline.started_at = Time.current end before_transition any => [:success, :failed, :canceled] do |pipeline| - pipeline.finished_at = Time.now + pipeline.finished_at = Time.current pipeline.update_duration end @@ -235,12 +232,10 @@ module Ci end after_transition any => [:success, :failed] do |pipeline| + ref_status = pipeline.ci_ref&.update_status_by!(pipeline) + pipeline.run_after_commit do - if Feature.enabled?(:ci_pipeline_fixed_notifications) - PipelineUpdateCiRefStatusWorker.perform_async(pipeline.id) - else - PipelineNotificationWorker.perform_async(pipeline.id) - end + PipelineNotificationWorker.perform_async(pipeline.id, ref_status: ref_status) end end @@ -260,6 +255,7 @@ module Ci scope :for_sha_or_source_sha, -> (sha) { for_sha(sha).or(for_source_sha(sha)) } scope :for_ref, -> (ref) { where(ref: ref) } scope :for_id, -> (id) { where(id: id) } + scope :for_iid, -> (iid) { where(iid: iid) } scope :created_after, -> (time) { where('ci_pipelines.created_at > ?', time) } scope :with_reports, -> (reports_scope) do @@ -397,11 +393,11 @@ module Ci end def ordered_stages - if Feature.enabled?(:ci_atomic_processing, project, default_enabled: false) + if ::Gitlab::Ci::Features.atomic_processing?(project) # The `Ci::Stage` contains all up-to date data # as atomic processing updates all data in-bulk stages - elsif Feature.enabled?(:ci_pipeline_persisted_stages, default_enabled: true) && complete? + elsif complete? # The `Ci::Stage` contains up-to date data only for `completed` pipelines # this is due to asynchronous processing of pipeline, and stages possibly # not updated inline with processing of pipeline @@ -445,7 +441,7 @@ module Ci end def legacy_stages - if Feature.enabled?(:ci_composite_status, project, default_enabled: false) + if ::Gitlab::Ci::Features.composite_status?(project) legacy_stages_using_composite_status else legacy_stages_using_sql @@ -798,13 +794,17 @@ module Ci @latest_builds_with_artifacts ||= builds.latest.with_artifacts_not_expired.to_a end + def latest_report_builds(reports_scope = ::Ci::JobArtifact.with_reports) + builds.latest.with_reports(reports_scope) + end + def has_reports?(reports_scope) - complete? && builds.latest.with_reports(reports_scope).exists? + complete? && latest_report_builds(reports_scope).exists? end def test_reports Gitlab::Ci::Reports::TestReports.new.tap do |test_reports| - builds.latest.with_reports(Ci::JobArtifact.test_reports).preload(:project).find_each do |build| + latest_report_builds(Ci::JobArtifact.test_reports).preload(:project).find_each do |build| build.collect_test_reports!(test_reports) end end @@ -826,7 +826,7 @@ module Ci def coverage_reports Gitlab::Ci::Reports::CoverageReports.new.tap do |coverage_reports| - builds.latest.with_reports(Ci::JobArtifact.coverage_reports).each do |build| + latest_report_builds(Ci::JobArtifact.coverage_reports).each do |build| build.collect_coverage_reports!(coverage_reports) end end @@ -834,7 +834,7 @@ module Ci def terraform_reports ::Gitlab::Ci::Reports::TerraformReports.new.tap do |terraform_reports| - builds.latest.with_reports(::Ci::JobArtifact.terraform_reports).each do |build| + latest_report_builds(::Ci::JobArtifact.terraform_reports).each do |build| build.collect_terraform_reports!(terraform_reports) end end @@ -969,6 +969,12 @@ module Ci processables.populate_scheduling_type! end + def ensure_ci_ref! + return unless Gitlab::Ci::Features.pipeline_fixed_notifications? + + self.ci_ref = Ci::Ref.ensure_for(self) + end + private def pipeline_data |