diff options
Diffstat (limited to 'lib/gitlab/ci/pipeline')
-rw-r--r-- | lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/chain/command.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/chain/limit/deployments.rb | 39 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/chain/populate.rb | 4 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/chain/seed.rb | 26 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/quota/deployments.rb | 50 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/seed/build.rb | 22 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/seed/environment.rb | 4 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/seed/pipeline.rb | 51 |
9 files changed, 172 insertions, 28 deletions
diff --git a/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb b/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb index a864c843dd8..2ca51930c19 100644 --- a/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb +++ b/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb @@ -35,7 +35,7 @@ module Gitlab # rubocop: enable CodeReuse/ActiveRecord def pipelines - if ::Feature.enabled?(:ci_auto_cancel_all_pipelines, project, default_enabled: false) + if ::Feature.enabled?(:ci_auto_cancel_all_pipelines, project, default_enabled: true) project.all_pipelines.ci_and_parent_sources else project.ci_pipelines diff --git a/lib/gitlab/ci/pipeline/chain/command.rb b/lib/gitlab/ci/pipeline/chain/command.rb index 06096a33f27..d05be54267c 100644 --- a/lib/gitlab/ci/pipeline/chain/command.rb +++ b/lib/gitlab/ci/pipeline/chain/command.rb @@ -12,7 +12,7 @@ module Gitlab :seeds_block, :variables_attributes, :push_options, :chat_data, :allow_mirror_update, :bridge, :content, :dry_run, # These attributes are set by Chains during processing: - :config_content, :yaml_processor_result, :stage_seeds + :config_content, :yaml_processor_result, :pipeline_seed ) do include Gitlab::Utils::StrongMemoize diff --git a/lib/gitlab/ci/pipeline/chain/limit/deployments.rb b/lib/gitlab/ci/pipeline/chain/limit/deployments.rb new file mode 100644 index 00000000000..d684eedcaac --- /dev/null +++ b/lib/gitlab/ci/pipeline/chain/limit/deployments.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +module Gitlab + module Ci + module Pipeline + module Chain + module Limit + class Deployments < Chain::Base + extend ::Gitlab::Utils::Override + include ::Gitlab::Ci::Pipeline::Chain::Helpers + + attr_reader :limit + private :limit + + def initialize(*) + super + + @limit = ::Gitlab::Ci::Pipeline::Quota::Deployments + .new(project.namespace, pipeline, command) + end + + override :perform! + def perform! + return unless limit.exceeded? + + limit.log_error!(project_id: project.id, plan: project.actual_plan_name) + error(limit.message, drop_reason: :deployments_limit_exceeded) + end + + override :break? + def break? + limit.exceeded? + end + end + end + end + end + end +end diff --git a/lib/gitlab/ci/pipeline/chain/populate.rb b/lib/gitlab/ci/pipeline/chain/populate.rb index f9ae37aa273..654e24be8e1 100644 --- a/lib/gitlab/ci/pipeline/chain/populate.rb +++ b/lib/gitlab/ci/pipeline/chain/populate.rb @@ -10,12 +10,12 @@ module Gitlab PopulateError = Class.new(StandardError) def perform! - raise ArgumentError, 'missing stage seeds' unless @command.stage_seeds + raise ArgumentError, 'missing pipeline seed' unless @command.pipeline_seed ## # Populate pipeline with all stages, and stages with builds. # - pipeline.stages = @command.stage_seeds.map(&:to_resource) + pipeline.stages = @command.pipeline_seed.stages if stage_names.empty? return error('No stages / jobs for this pipeline.') diff --git a/lib/gitlab/ci/pipeline/chain/seed.rb b/lib/gitlab/ci/pipeline/chain/seed.rb index ba86b08d209..083f0bec1df 100644 --- a/lib/gitlab/ci/pipeline/chain/seed.rb +++ b/lib/gitlab/ci/pipeline/chain/seed.rb @@ -29,11 +29,11 @@ module Gitlab ## # Gather all runtime build/stage errors # - if stage_seeds_errors - return error(stage_seeds_errors.join("\n"), config_error: true) + if pipeline_seed.errors + return error(pipeline_seed.errors.join("\n"), config_error: true) end - @command.stage_seeds = stage_seeds + @command.pipeline_seed = pipeline_seed end def break? @@ -42,24 +42,12 @@ module Gitlab private - def stage_seeds_errors - stage_seeds.flat_map(&:errors).compact.presence - end - - def stage_seeds - strong_memoize(:stage_seeds) do - seeds = stages_attributes.inject([]) do |previous_stages, attributes| - seed = Gitlab::Ci::Pipeline::Seed::Stage.new(pipeline, attributes, previous_stages) - previous_stages + [seed] - end - - seeds.select(&:included?) + def pipeline_seed + strong_memoize(:pipeline_seed) do + stages_attributes = @command.yaml_processor_result.stages_attributes + Gitlab::Ci::Pipeline::Seed::Pipeline.new(pipeline, stages_attributes) end end - - def stages_attributes - @command.yaml_processor_result.stages_attributes - end end end end diff --git a/lib/gitlab/ci/pipeline/quota/deployments.rb b/lib/gitlab/ci/pipeline/quota/deployments.rb new file mode 100644 index 00000000000..ed32d0d3d49 --- /dev/null +++ b/lib/gitlab/ci/pipeline/quota/deployments.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module Gitlab + module Ci + module Pipeline + module Quota + class Deployments < ::Gitlab::Ci::Limit + include ::Gitlab::Utils::StrongMemoize + include ActionView::Helpers::TextHelper + + def initialize(namespace, pipeline, command) + @namespace = namespace + @pipeline = pipeline + @command = command + end + + def enabled? + limit > 0 + end + + def exceeded? + return false unless enabled? + + pipeline_deployment_count > limit + end + + def message + return unless exceeded? + + "Pipeline has too many deployments! Requested #{pipeline_deployment_count}, but the limit is #{limit}." + end + + private + + def pipeline_deployment_count + strong_memoize(:pipeline_deployment_count) do + @command.pipeline_seed.deployments_count + end + end + + def limit + strong_memoize(:limit) do + @namespace.actual_limits.ci_pipeline_deployments + end + end + end + end + end + end +end diff --git a/lib/gitlab/ci/pipeline/seed/build.rb b/lib/gitlab/ci/pipeline/seed/build.rb index 91dbcc616ea..2271915a72b 100644 --- a/lib/gitlab/ci/pipeline/seed/build.rb +++ b/lib/gitlab/ci/pipeline/seed/build.rb @@ -60,6 +60,7 @@ module Gitlab @seed_attributes .deep_merge(pipeline_attributes) .deep_merge(rules_attributes) + .deep_merge(allow_failure_criteria_attributes) .deep_merge(cache_attributes) end @@ -154,9 +155,15 @@ module Gitlab end def rules_attributes - return {} unless @using_rules + strong_memoize(:rules_attributes) do + next {} unless @using_rules - rules_result.build_attributes + if ::Gitlab::Ci::Features.rules_variables_enabled?(@pipeline.project) + rules_result.build_attributes(@seed_attributes) + else + rules_result.build_attributes + end + end end def rules_result @@ -176,6 +183,17 @@ module Gitlab @cache.build_attributes end end + + # If a job uses `allow_failure:exit_codes` and `rules:allow_failure` + # we need to prevent the exit codes from being persisted because they + # would break the behavior defined by `rules:allow_failure`. + def allow_failure_criteria_attributes + return {} unless ::Gitlab::Ci::Features.allow_failure_with_exit_codes_enabled? + return {} if rules_attributes[:allow_failure].nil? + return {} unless @seed_attributes.dig(:options, :allow_failure_criteria) + + { options: { allow_failure_criteria: nil } } + end end end end diff --git a/lib/gitlab/ci/pipeline/seed/environment.rb b/lib/gitlab/ci/pipeline/seed/environment.rb index b20dc383419..5dff0788ec9 100644 --- a/lib/gitlab/ci/pipeline/seed/environment.rb +++ b/lib/gitlab/ci/pipeline/seed/environment.rb @@ -24,9 +24,7 @@ module Gitlab end def auto_stop_in - if Feature.enabled?(:environment_auto_stop_start_on_create) - job.environment_auto_stop_in - end + job.environment_auto_stop_in end def expanded_environment_name diff --git a/lib/gitlab/ci/pipeline/seed/pipeline.rb b/lib/gitlab/ci/pipeline/seed/pipeline.rb new file mode 100644 index 00000000000..da9d853cf68 --- /dev/null +++ b/lib/gitlab/ci/pipeline/seed/pipeline.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module Gitlab + module Ci + module Pipeline + module Seed + class Pipeline + include Gitlab::Utils::StrongMemoize + + def initialize(pipeline, stages_attributes) + @pipeline = pipeline + @stages_attributes = stages_attributes + end + + def errors + stage_seeds.flat_map(&:errors).compact.presence + end + + def stages + stage_seeds.map(&:to_resource) + end + + def size + stage_seeds.sum(&:size) + end + + def deployments_count + stage_seeds.sum do |stage_seed| + stage_seed.seeds.count do |build_seed| + build_seed.attributes[:environment].present? + end + end + end + + private + + def stage_seeds + strong_memoize(:stage_seeds) do + seeds = @stages_attributes.inject([]) do |previous_stages, attributes| + seed = Gitlab::Ci::Pipeline::Seed::Stage.new(@pipeline, attributes, previous_stages) + previous_stages + [seed] + end + + seeds.select(&:included?) + end + end + end + end + end + end +end |