From ab0cd2a8bf54209e5e1b9594752d5158d3cf5faa Mon Sep 17 00:00:00 2001
From: Grzegorz Bizon <grzesiek.bizon@gmail.com>
Date: Wed, 21 Mar 2018 09:33:14 +0100
Subject: [PATCH] Introduce pipeline build seeds

---
 app/models/ci/pipeline.rb                     | 17 +++++++++
 lib/gitlab/ci/pipeline/seed/build.rb          | 28 +++++++++++++++
 lib/gitlab/ci/pipeline/seed/stage.rb          | 35 +++++++------------
 .../lib/gitlab/ci/pipeline/seed/stage_spec.rb |  4 +--
 spec/lib/gitlab/ci/yaml_processor_spec.rb     |  8 ++---
 5 files changed, 63 insertions(+), 29 deletions(-)
 create mode 100644 lib/gitlab/ci/pipeline/seed/build.rb

diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index f2edcdd61fd..2e8d7f9dbfe 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -6,6 +6,7 @@ module Ci
     include AfterCommitQueue
     include Presentable
     include Gitlab::OptimisticLocking
+    include Gitlab::Utils::StrongMemoize
 
     belongs_to :project, inverse_of: :pipelines
     belongs_to :user
@@ -472,6 +473,22 @@ module Ci
       end
     end
 
+    # TODO specs
+    #
+    def protected_ref?
+      strong_memoize(:protected_ref) do
+        project.protected_for?(ref)
+      end
+    end
+
+    # TODO specs
+    #
+    def legacy_trigger
+      strong_memoize(:legacy_trigger) do
+        trigger_requests.first
+      end
+    end
+
     def predefined_variables
       Gitlab::Ci::Variables::Collection.new
         .append(key: 'CI_PIPELINE_ID', value: id.to_s)
diff --git a/lib/gitlab/ci/pipeline/seed/build.rb b/lib/gitlab/ci/pipeline/seed/build.rb
new file mode 100644
index 00000000000..f5dbb3a1c40
--- /dev/null
+++ b/lib/gitlab/ci/pipeline/seed/build.rb
@@ -0,0 +1,28 @@
+module Gitlab
+  module Ci
+    module Pipeline
+      module Seed
+        class Build < Seed::Base
+          def initialize(pipeline, attributes)
+            @pipeline = pipeline
+            @attributes = attributes
+          end
+
+          # TODO find a different solution
+          #
+          def user=(current_user)
+            @attributes.merge!(user: current_user)
+          end
+
+          def attributes
+            @attributes.merge(project: @pipeline.project,
+                              ref: @pipeline.ref,
+                              tag: @pipeline.tag,
+                              trigger_request: @pipeline.legacy_trigger,
+                              protected: @pipeline.protected_ref?)
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/ci/pipeline/seed/stage.rb b/lib/gitlab/ci/pipeline/seed/stage.rb
index 32631a30e8f..3665794f354 100644
--- a/lib/gitlab/ci/pipeline/seed/stage.rb
+++ b/lib/gitlab/ci/pipeline/seed/stage.rb
@@ -3,43 +3,35 @@ module Gitlab
     module Pipeline
       module Seed
         class Stage < Seed::Base
-          include ::Gitlab::Utils::StrongMemoize
-
           attr_reader :pipeline
 
           delegate :project, to: :pipeline
           delegate :size, to: :@builds
 
-          def initialize(pipeline, stage, builds)
+          def initialize(pipeline, name, builds)
             @pipeline = pipeline
-            @stage = stage            # stage name
-            @builds = builds.to_a.dup # builds array of hashes
+            @name = name
+
+            @builds = builds.map do |attributes|
+              Seed::Build.new(pipeline, attributes)
+            end
           end
 
           def user=(current_user)
-            @builds.map! do |attributes|
-              attributes.merge(user: current_user)
-            end
+            @builds.each { |seed| seed.user = current_user }
           end
 
-          def stage_attributes
-            { name: @stage, project: project }
+          def attributes
+            { name: @name, project: project }
           end
 
+          # TODO decouple from Seed::Build
           def builds_attributes
-            trigger = pipeline.trigger_requests.first
-
-            @builds.map do |attributes|
-              attributes.merge(project: project,
-                               ref: pipeline.ref,
-                               tag: pipeline.tag,
-                               trigger_request: trigger,
-                               protected: protected_ref?)
-            end
+            @builds.map(&:attributes)
           end
 
           def create!
-            pipeline.stages.build(stage_attributes).tap do |stage|
+            pipeline.stages.build(attributes).tap do |stage|
               builds_attributes.each do |build_attributes|
                 stage.builds.build(build_attributes).tap do |build|
                   build.pipeline = pipeline
@@ -57,9 +49,6 @@ module Gitlab
           private
 
           def protected_ref?
-            strong_memoize(:protected_ref) do
-              project.protected_for?(pipeline.ref)
-            end
           end
         end
       end
diff --git a/spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb
index d4a72b7c62c..30142e356a5 100644
--- a/spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb
@@ -19,8 +19,8 @@ describe Gitlab::Ci::Pipeline::Seed::Stage do
 
   describe '#stage_attributes' do
     it 'returns hash attributes of a stage' do
-      expect(subject.stage_attributes).to be_a Hash
-      expect(subject.stage_attributes).to include(:name, :project)
+      expect(subject.attributes).to be_a Hash
+      expect(subject.attributes).to include(:name, :project)
     end
   end
 
diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb
index 1d852e2b3b2..e67b51b52b9 100644
--- a/spec/lib/gitlab/ci/yaml_processor_spec.rb
+++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb
@@ -119,8 +119,8 @@ module Gitlab
             seeds = subject.stage_seeds(pipeline)
 
             expect(seeds.size).to eq 2
-            expect(seeds.first.stage_attributes[:name]).to eq 'test'
-            expect(seeds.second.stage_attributes[:name]).to eq 'deploy'
+            expect(seeds.first.attributes[:name]).to eq 'test'
+            expect(seeds.second.attributes[:name]).to eq 'deploy'
             expect(seeds.first.builds_attributes.dig(0, :name)).to eq 'rspec'
             expect(seeds.first.builds_attributes.dig(1, :name)).to eq 'spinach'
             expect(seeds.second.builds_attributes.dig(0, :name)).to eq 'production'
@@ -141,7 +141,7 @@ module Gitlab
             seeds = subject.stage_seeds(pipeline)
 
             expect(seeds.size).to eq 1
-            expect(seeds.first.stage_attributes[:name]).to eq 'test'
+            expect(seeds.first.attributes[:name]).to eq 'test'
             expect(seeds.first.builds_attributes.dig(0, :name)).to eq 'spinach'
           end
         end
@@ -160,7 +160,7 @@ module Gitlab
             seeds = subject.stage_seeds(pipeline)
 
             expect(seeds.size).to eq 1
-            expect(seeds.first.stage_attributes[:name]).to eq 'test'
+            expect(seeds.first.attributes[:name]).to eq 'test'
             expect(seeds.first.builds_attributes.dig(0, :name)).to eq 'spinach'
           end
         end
-- 
2.30.9