summaryrefslogtreecommitdiff
path: root/app/models
diff options
context:
space:
mode:
authorKamil TrzciƄski <ayufan@ayufan.eu>2019-08-01 14:26:49 +0000
committerSean McGivern <sean@gitlab.com>2019-08-01 14:26:49 +0000
commite7ee84aad4237eaa16f2aba75b4d2c7860625c9d (patch)
tree786c239cdf6568289f9b2df4dd1d85290c246b36 /app/models
parent2cf9769d12bb93c7a55432f8c8c08e89e6735461 (diff)
downloadgitlab-ce-e7ee84aad4237eaa16f2aba75b4d2c7860625c9d.tar.gz
Add support for DAG
This implements the support for `needs:` keyword as part of GitLab CI. That makes some of the jobs to be run out of order.
Diffstat (limited to 'app/models')
-rw-r--r--app/models/ci/build.rb18
-rw-r--r--app/models/ci/build_need.rb14
-rw-r--r--app/models/ci/pipeline.rb4
-rw-r--r--app/models/commit_status.rb8
-rw-r--r--app/models/concerns/ci/metadatable.rb1
5 files changed, 39 insertions, 6 deletions
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 07813e03f3a..dd2bfc42af9 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -38,6 +38,7 @@ module Ci
has_one :deployment, as: :deployable, class_name: 'Deployment'
has_many :trace_sections, class_name: 'Ci::BuildTraceSection'
has_many :trace_chunks, class_name: 'Ci::BuildTraceChunk', foreign_key: :build_id
+ has_many :needs, class_name: 'Ci::BuildNeed', foreign_key: :build_id, inverse_of: :build
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
@@ -50,6 +51,7 @@ module Ci
accepts_nested_attributes_for :runner_session
accepts_nested_attributes_for :job_variables
+ accepts_nested_attributes_for :needs
delegate :url, to: :runner_session, prefix: true, allow_nil: true
delegate :terminal_specification, to: :runner_session, allow_nil: true
@@ -713,11 +715,21 @@ module Ci
depended_jobs = depends_on_builds
- return depended_jobs unless options[:dependencies].present?
+ # find all jobs that are dependent on
+ if options[:dependencies].present?
+ depended_jobs = depended_jobs.select do |job|
+ options[:dependencies].include?(job.name)
+ end
+ end
- depended_jobs.select do |job|
- options[:dependencies].include?(job.name)
+ # find all jobs that are needed by this one
+ if options[:needs].present?
+ depended_jobs = depended_jobs.select do |job|
+ options[:needs].include?(job.name)
+ end
end
+
+ depended_jobs
end
def empty_dependencies?
diff --git a/app/models/ci/build_need.rb b/app/models/ci/build_need.rb
new file mode 100644
index 00000000000..6531dfd332f
--- /dev/null
+++ b/app/models/ci/build_need.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module Ci
+ class BuildNeed < ApplicationRecord
+ extend Gitlab::Ci::Model
+
+ belongs_to :build, class_name: "Ci::Build", foreign_key: :build_id, inverse_of: :needs
+
+ validates :build, presence: true
+ validates :name, presence: true, length: { maximum: 128 }
+
+ scope :scoped_build, -> { where('ci_builds.id=ci_build_needs.build_id') }
+ end
+end
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 1c76f401690..3515f0b83ee 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -611,8 +611,8 @@ module Ci
end
# rubocop: disable CodeReuse/ServiceClass
- def process!
- Ci::ProcessPipelineService.new(project, user).execute(self)
+ def process!(trigger_build_name = nil)
+ Ci::ProcessPipelineService.new(project, user).execute(self, trigger_build_name)
end
# rubocop: enable CodeReuse/ServiceClass
diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb
index be6f3e9c5b0..d7eb78db5b8 100644
--- a/app/models/commit_status.rb
+++ b/app/models/commit_status.rb
@@ -43,6 +43,12 @@ class CommitStatus < ApplicationRecord
scope :after_stage, -> (index) { where('stage_idx > ?', index) }
scope :processables, -> { where(type: %w[Ci::Build Ci::Bridge]) }
+ scope :with_needs, -> (names = nil) do
+ needs = Ci::BuildNeed.scoped_build.select(1)
+ needs = needs.where(name: names) if names
+ where('EXISTS (?)', needs).preload(:needs)
+ end
+
# We use `CommitStatusEnums.failure_reasons` here so that EE can more easily
# extend this `Hash` with new values.
enum_with_nil failure_reason: ::CommitStatusEnums.failure_reasons
@@ -116,7 +122,7 @@ class CommitStatus < ApplicationRecord
commit_status.run_after_commit do
if pipeline_id
if complete? || manual?
- PipelineProcessWorker.perform_async(pipeline_id)
+ BuildProcessWorker.perform_async(id)
else
PipelineUpdateWorker.perform_async(pipeline_id)
end
diff --git a/app/models/concerns/ci/metadatable.rb b/app/models/concerns/ci/metadatable.rb
index 9eed9492b37..304cc71e9dc 100644
--- a/app/models/concerns/ci/metadatable.rb
+++ b/app/models/concerns/ci/metadatable.rb
@@ -29,6 +29,7 @@ module Ci
def degenerate!
self.class.transaction do
self.update!(options: nil, yaml_variables: nil)
+ self.needs.all.delete_all
self.metadata&.destroy
end
end