diff options
Diffstat (limited to 'app/models/ci/pipeline.rb')
-rw-r--r-- | app/models/ci/pipeline.rb | 98 |
1 files changed, 76 insertions, 22 deletions
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 7762328d274..47eba685afe 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -19,6 +19,8 @@ module Ci PROJECT_ROUTE_AND_NAMESPACE_ROUTE = { project: [:project_feature, :route, { namespace: :route }] }.freeze + CONFIG_EXTENSION = '.gitlab-ci.yml' + DEFAULT_CONFIG_PATH = CONFIG_EXTENSION BridgeStatusError = Class.new(StandardError) @@ -104,15 +106,15 @@ module Ci after_create :keep_around_commits, unless: :importing? - # We use `Ci::PipelineEnums.sources` here so that EE can more easily extend + # We use `Enums::Ci::Pipeline.sources` here so that EE can more easily extend # this `Hash` with new values. - enum_with_nil source: ::Ci::PipelineEnums.sources + enum_with_nil source: Enums::Ci::Pipeline.sources - enum_with_nil config_source: ::Ci::PipelineEnums.config_sources + enum_with_nil config_source: Enums::Ci::Pipeline.config_sources - # We use `Ci::PipelineEnums.failure_reasons` here so that EE can more easily + # We use `Enums::Ci::Pipeline.failure_reasons` here so that EE can more easily # extend this `Hash` with new values. - enum failure_reason: ::Ci::PipelineEnums.failure_reasons + enum failure_reason: Enums::Ci::Pipeline.failure_reasons enum locked: { unlocked: 0, artifacts_locked: 1 } @@ -229,7 +231,12 @@ module Ci end after_transition any => ::Ci::Pipeline.completed_statuses do |pipeline| - next unless pipeline.bridge_triggered? + pipeline.run_after_commit do + ::Ci::Pipelines::CreateArtifactWorker.perform_async(pipeline.id) + end + end + + after_transition any => ::Ci::Pipeline.completed_statuses do |pipeline| next unless pipeline.bridge_waiting? pipeline.run_after_commit do @@ -254,7 +261,7 @@ module Ci scope :internal, -> { where(source: internal_sources) } scope :no_child, -> { where.not(source: :parent_pipeline) } - scope :ci_sources, -> { where(config_source: ::Ci::PipelineEnums.ci_config_sources_values) } + scope :ci_sources, -> { where(source: Enums::Ci::Pipeline.ci_sources.values) } scope :for_user, -> (user) { where(user: user) } scope :for_sha, -> (sha) { where(sha: sha) } scope :for_source_sha, -> (source_sha) { where(source_sha: source_sha) } @@ -483,6 +490,12 @@ module Ci end end + def git_commit_timestamp + strong_memoize(:git_commit_timestamp) do + commit.try(:timestamp) + end + end + def before_sha super || Gitlab::Git::BLANK_SHA end @@ -539,12 +552,6 @@ module Ci end # rubocop: enable CodeReuse/ServiceClass - def mark_as_processable_after_stage(stage_idx) - builds.skipped.after_stage(stage_idx).find_each do |build| - Gitlab::OptimisticLocking.retry_lock(build, &:process) - end - end - def lazy_ref_commit return unless ::Gitlab::Ci::Features.pipeline_latest? @@ -647,7 +654,7 @@ module Ci def config_path return unless repository_source? || unknown_source? - project.ci_config_path.presence || '.gitlab-ci.yml' + project.ci_config_path_or_default end def has_yaml_errors? @@ -669,8 +676,10 @@ module Ci messages.select(&:error?) end - def warning_messages - messages.select(&:warning?) + def warning_messages(limit: nil) + messages.select(&:warning?).tap do |warnings| + break warnings.take(limit) if limit + end end # Manually set the notes for a Ci::Pipeline @@ -766,6 +775,7 @@ module Ci variables.append(key: 'CI_COMMIT_TITLE', value: git_commit_full_title.to_s) variables.append(key: 'CI_COMMIT_DESCRIPTION', value: git_commit_description.to_s) variables.append(key: 'CI_COMMIT_REF_PROTECTED', value: (!!protected_ref?).to_s) + variables.append(key: 'CI_COMMIT_TIMESTAMP', value: git_commit_timestamp.to_s) # legacy variables variables.append(key: 'CI_BUILD_REF', value: sha) @@ -810,11 +820,17 @@ module Ci all_merge_requests.order(id: :desc) end - # If pipeline is a child of another pipeline, include the parent - # and the siblings, otherwise return only itself and children. def same_family_pipeline_ids - parent = parent_pipeline || self - [parent.id] + parent.child_pipelines.pluck(:id) + if ::Gitlab::Ci::Features.child_of_child_pipeline_enabled?(project) + ::Gitlab::Ci::PipelineObjectHierarchy.new( + base_and_ancestors(same_project: true), options: { same_project: true } + ).base_and_descendants.select(:id) + else + # If pipeline is a child of another pipeline, include the parent + # and the siblings, otherwise return only itself and children. + parent = parent_pipeline || self + [parent.id] + parent.child_pipelines.pluck(:id) + end end def bridge_triggered? @@ -858,12 +874,26 @@ module Ci builds.latest.with_reports(reports_scope) end + def builds_with_coverage + builds.with_coverage + end + def has_reports?(reports_scope) complete? && latest_report_builds(reports_scope).exists? end + def has_coverage_reports? + pipeline_artifacts&.has_code_coverage? + end + + def can_generate_coverage_reports? + has_reports?(Ci::JobArtifact.coverage_reports) + end + def test_report_summary - Gitlab::Ci::Reports::TestReportSummary.new(latest_builds_report_results) + strong_memoize(:test_report_summary) do + Gitlab::Ci::Reports::TestReportSummary.new(latest_builds_report_results) + end end def test_reports @@ -1008,7 +1038,11 @@ module Ci end def cacheable? - Ci::PipelineEnums.ci_config_sources.key?(config_source.to_sym) + !dangling? + end + + def dangling? + Enums::Ci::Pipeline.dangling_sources.key?(source.to_sym) end def source_ref_path @@ -1029,6 +1063,26 @@ module Ci self.ci_ref = Ci::Ref.ensure_for(self) end + def base_and_ancestors(same_project: false) + # Without using `unscoped`, caller scope is also included into the query. + # Using `unscoped` here will be redundant after Rails 6.1 + ::Gitlab::Ci::PipelineObjectHierarchy + .new(self.class.unscoped.where(id: id), options: { same_project: same_project }) + .base_and_ancestors + end + + # We need `base_and_ancestors` in a specific order to "break" when needed. + # If we use `find_each`, then the order is broken. + # rubocop:disable Rails/FindEach + def reset_ancestor_bridges! + base_and_ancestors.includes(:source_bridge).each do |pipeline| + break unless pipeline.bridge_waiting? + + pipeline.source_bridge.pending! + end + end + # rubocop:enable Rails/FindEach + private def add_message(severity, content) |