Commit ad3be46b authored by Kamil Trzcinski's avatar Kamil Trzcinski

Implement and use Gitlab::Ci::Pipeline::Chain::Command

parent b30e0e06
...@@ -12,18 +12,19 @@ module Ci ...@@ -12,18 +12,19 @@ module Ci
def execute(source, ignore_skip_ci: false, save_on_errors: true, trigger_request: nil, schedule: nil, &block) def execute(source, ignore_skip_ci: false, save_on_errors: true, trigger_request: nil, schedule: nil, &block)
@pipeline = Ci::Pipeline.new @pipeline = Ci::Pipeline.new
command = OpenStruct.new(source: source, command = Gitlab::Ci::Pipeline::Chain::Command.new(
origin_ref: params[:ref], source: source,
checkout_sha: params[:checkout_sha], origin_ref: params[:ref],
after_sha: params[:after], checkout_sha: params[:checkout_sha],
before_sha: params[:before], after_sha: params[:after],
trigger_request: trigger_request, before_sha: params[:before],
schedule: schedule, trigger_request: trigger_request,
ignore_skip_ci: ignore_skip_ci, schedule: schedule,
save_incompleted: save_on_errors, ignore_skip_ci: ignore_skip_ci,
seeds_block: block, save_incompleted: save_on_errors,
project: project, seeds_block: block,
current_user: current_user) project: project,
current_user: current_user)
sequence = Gitlab::Ci::Pipeline::Chain::Sequence sequence = Gitlab::Ci::Pipeline::Chain::Sequence
.new(pipeline, command, SEQUENCE) .new(pipeline, command, SEQUENCE)
......
...@@ -3,14 +3,13 @@ module Gitlab ...@@ -3,14 +3,13 @@ module Gitlab
module Pipeline module Pipeline
module Chain module Chain
class Base class Base
attr_reader :pipeline, :project, :current_user attr_reader :pipeline, :command
delegate :project, :current_user, to: :command
def initialize(pipeline, command) def initialize(pipeline, command)
@pipeline = pipeline @pipeline = pipeline
@command = command @command = command
@project = command.project
@current_user = command.current_user
end end
def perform! def perform!
......
...@@ -6,15 +6,15 @@ module Gitlab ...@@ -6,15 +6,15 @@ module Gitlab
def perform! def perform!
@pipeline.assign_attributes( @pipeline.assign_attributes(
source: @command.source, source: @command.source,
project: @project, project: @command.project,
ref: ref, ref: @command.ref,
sha: sha, sha: @command.sha,
before_sha: before_sha, before_sha: @command.before_sha,
tag: tag_exists?, tag: @command.tag_exists?,
trigger_requests: Array(@command.trigger_request), trigger_requests: Array(@command.trigger_request),
user: @current_user, user: @command.current_user,
pipeline_schedule: @command.schedule, pipeline_schedule: @command.schedule,
protected: protected_ref? protected: @command.protected_ref?
) )
@pipeline.set_config_source @pipeline.set_config_source
...@@ -23,36 +23,6 @@ module Gitlab ...@@ -23,36 +23,6 @@ module Gitlab
def break? def break?
false false
end end
private
def ref
@ref ||= Gitlab::Git.ref_name(origin_ref)
end
def sha
@project.commit(origin_sha || origin_ref).try(:id)
end
def origin_ref
@command.origin_ref
end
def origin_sha
@command.checkout_sha || @command.after_sha
end
def before_sha
@command.checkout_sha || @command.before_sha || Gitlab::Git::BLANK_SHA
end
def protected_ref?
@project.protected_for?(ref)
end
def tag_exists?
project.repository.tag_exists?(ref)
end
end end
end end
end end
......
module Gitlab
module Ci
module Pipeline
module Chain
Command = Struct.new(
:source, :project, :current_user,
:origin_ref, :checkout_sha, :after_sha, :before_sha,
:trigger_request, :schedule,
:ignore_skip_ci, :save_incompleted,
:seeds_block
) do
include Gitlab::Utils::StrongMemoize
def initialize(**params)
params.each do |key, value|
self[key] = value
end
end
def branch_exists?
strong_memoize(:is_branch) do
project.repository.branch_exists?(ref)
end
end
def tag_exists?
strong_memoize(:is_tag) do
project.repository.tag_exists?(ref)
end
end
def ref
strong_memoize(:ref) do
Gitlab::Git.ref_name(origin_ref)
end
end
def sha
strong_memoize(:sha) do
project.commit(origin_sha || origin_ref).try(:id)
end
end
def origin_sha
checkout_sha || after_sha
end
def before_sha
checkout_sha || before_sha || Gitlab::Git::BLANK_SHA
end
def protected_ref?
strong_memoize(:protected_ref) do
project.protected_for?(ref)
end
end
def error(message)
pipeline.errors.add(:base, message)
end
end
end
end
end
end
...@@ -3,24 +3,6 @@ module Gitlab ...@@ -3,24 +3,6 @@ module Gitlab
module Pipeline module Pipeline
module Chain module Chain
module Helpers module Helpers
include Gitlab::Utils::StrongMemoize
def branch_exists?
strong_memoize(:is_branch) do
raise ArgumentError unless pipeline.ref
project.repository.branch_exists?(pipeline.ref)
end
end
def tag_exists?
strong_memoize(:is_tag) do
raise ArgumentError unless pipeline.ref
project.repository.tag_exists?(pipeline.ref)
end
end
def error(message) def error(message)
pipeline.errors.add(:base, message) pipeline.errors.add(:base, message)
end end
......
...@@ -14,7 +14,7 @@ module Gitlab ...@@ -14,7 +14,7 @@ module Gitlab
unless allowed_to_trigger_pipeline? unless allowed_to_trigger_pipeline?
if can?(current_user, :create_pipeline, project) if can?(current_user, :create_pipeline, project)
return error("Insufficient permissions for protected ref '#{pipeline.ref}'") return error("Insufficient permissions for protected ref '#{command.ref}'")
else else
return error('Insufficient permissions to create a new pipeline') return error('Insufficient permissions to create a new pipeline')
end end
...@@ -29,7 +29,7 @@ module Gitlab ...@@ -29,7 +29,7 @@ module Gitlab
if current_user if current_user
allowed_to_create? allowed_to_create?
else # legacy triggers don't have a corresponding user else # legacy triggers don't have a corresponding user
!project.protected_for?(@pipeline.ref) !@command.protected_ref?
end end
end end
...@@ -38,10 +38,10 @@ module Gitlab ...@@ -38,10 +38,10 @@ module Gitlab
access = Gitlab::UserAccess.new(current_user, project: project) access = Gitlab::UserAccess.new(current_user, project: project)
if branch_exists? if @command.branch_exists?
access.can_update_branch?(@pipeline.ref) access.can_update_branch?(@command.ref)
elsif tag_exists? elsif @command.tag_exists?
access.can_create_tag?(@pipeline.ref) access.can_create_tag?(@command.ref)
else else
true # Allow it for now and we'll reject when we check ref existence true # Allow it for now and we'll reject when we check ref existence
end end
......
...@@ -7,14 +7,11 @@ module Gitlab ...@@ -7,14 +7,11 @@ module Gitlab
include Chain::Helpers include Chain::Helpers
def perform! def perform!
unless branch_exists? || tag_exists? unless @command.branch_exists? || @command.tag_exists?
return error('Reference not found') return error('Reference not found')
end end
## TODO, we check commit in the service, that is why unless @command.sha
# there is no repository access here.
#
unless pipeline.sha
return error('Commit not found') return error('Commit not found')
end end
end end
......
...@@ -6,15 +6,16 @@ describe Gitlab::Ci::Pipeline::Chain::Build do ...@@ -6,15 +6,16 @@ describe Gitlab::Ci::Pipeline::Chain::Build do
let(:pipeline) { Ci::Pipeline.new } let(:pipeline) { Ci::Pipeline.new }
let(:command) do let(:command) do
double('command', source: :push, Gitlab::Ci::Pipeline::Chain::Command.new(
origin_ref: 'master', source: :push,
checkout_sha: project.commit.id, origin_ref: 'master',
after_sha: nil, checkout_sha: project.commit.id,
before_sha: nil, after_sha: nil,
trigger_request: nil, before_sha: nil,
schedule: nil, trigger_request: nil,
project: project, schedule: nil,
current_user: user) project: project,
current_user: user)
end end
let(:step) { described_class.new(pipeline, command) } let(:step) { described_class.new(pipeline, command) }
...@@ -60,19 +61,20 @@ describe Gitlab::Ci::Pipeline::Chain::Build do ...@@ -60,19 +61,20 @@ describe Gitlab::Ci::Pipeline::Chain::Build do
context 'when pipeline is running for a tag' do context 'when pipeline is running for a tag' do
let(:command) do let(:command) do
double('command', source: :push, Gitlab::Ci::Pipeline::Chain::Command.new(
origin_ref: 'mytag', source: :push,
checkout_sha: project.commit.id, origin_ref: 'mytag',
after_sha: nil, checkout_sha: project.commit.id,
before_sha: nil, after_sha: nil,
trigger_request: nil, before_sha: nil,
schedule: nil, trigger_request: nil,
project: project, schedule: nil,
current_user: user) project: project,
current_user: user)
end end
before do before do
allow(step).to receive(:tag_exists?).and_return(true) allow_any_instance_of(Repository).to receive(:tag_exists?).with('mytag').and_return(true)
step.perform! step.perform!
end end
......
...@@ -10,9 +10,9 @@ describe Gitlab::Ci::Pipeline::Chain::Create do ...@@ -10,9 +10,9 @@ describe Gitlab::Ci::Pipeline::Chain::Create do
end end
let(:command) do let(:command) do
double('command', project: project, Gitlab::Ci::Pipeline::Chain::Command.new(
current_user: user, project: project,
seeds_block: nil) current_user: user,seeds_block: nil)
end end
let(:step) { described_class.new(pipeline, command) } let(:step) { described_class.new(pipeline, command) }
......
...@@ -5,7 +5,7 @@ describe Gitlab::Ci::Pipeline::Chain::Sequence do ...@@ -5,7 +5,7 @@ describe Gitlab::Ci::Pipeline::Chain::Sequence do
set(:user) { create(:user) } set(:user) { create(:user) }
let(:pipeline) { build_stubbed(:ci_pipeline) } let(:pipeline) { build_stubbed(:ci_pipeline) }
let(:command) { double('command' ) } let(:command) { Gitlab::Ci::Pipeline::Chain::Command.new }
let(:first_step) { spy('first step') } let(:first_step) { spy('first step') }
let(:second_step) { spy('second step') } let(:second_step) { spy('second step') }
let(:sequence) { [first_step, second_step] } let(:sequence) { [first_step, second_step] }
......
...@@ -6,10 +6,11 @@ describe Gitlab::Ci::Pipeline::Chain::Skip do ...@@ -6,10 +6,11 @@ describe Gitlab::Ci::Pipeline::Chain::Skip do
set(:pipeline) { create(:ci_pipeline, project: project) } set(:pipeline) { create(:ci_pipeline, project: project) }
let(:command) do let(:command) do
double('command', project: project, Gitlab::Ci::Pipeline::Chain::Command.new(
current_user: user, project: project,
ignore_skip_ci: false, current_user: user,
save_incompleted: true) ignore_skip_ci: false,
save_incompleted: true)
end end
let(:step) { described_class.new(pipeline, command) } let(:step) { described_class.new(pipeline, command) }
......
...@@ -5,11 +5,12 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Abilities do ...@@ -5,11 +5,12 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Abilities do
set(:user) { create(:user) } set(:user) { create(:user) }
let(:pipeline) do let(:pipeline) do
build_stubbed(:ci_pipeline, ref: ref, project: project) build_stubbed(:ci_pipeline, project: project)
end end
let(:command) do let(:command) do
double('command', project: project, current_user: user) Gitlab::Ci::Pipeline::Chain::Command.new(
project: project, current_user: user, origin_ref: ref)
end end
let(:step) { described_class.new(pipeline, command) } let(:step) { described_class.new(pipeline, command) }
......
...@@ -5,9 +5,10 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Config do ...@@ -5,9 +5,10 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Config do
set(:user) { create(:user) } set(:user) { create(:user) }
let(:command) do let(:command) do
double('command', project: project, Gitlab::Ci::Pipeline::Chain::Command.new(
current_user: user, project: project,
save_incompleted: true) current_user: user,
save_incompleted: true)
end end
let!(:step) { described_class.new(pipeline, command) } let!(:step) { described_class.new(pipeline, command) }
......
...@@ -3,10 +3,7 @@ require 'spec_helper' ...@@ -3,10 +3,7 @@ require 'spec_helper'
describe Gitlab::Ci::Pipeline::Chain::Validate::Repository do describe Gitlab::Ci::Pipeline::Chain::Validate::Repository do
set(:project) { create(:project, :repository) } set(:project) { create(:project, :repository) }
set(:user) { create(:user) } set(:user) { create(:user) }
let(:pipeline) { build_stubbed(:ci_pipeline) }
let(:command) do
double('command', project: project, current_user: user)
end
let!(:step) { described_class.new(pipeline, command) } let!(:step) { described_class.new(pipeline, command) }
...@@ -14,9 +11,10 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Repository do ...@@ -14,9 +11,10 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Repository do
step.perform! step.perform!
end end
context 'when pipeline ref and sha exists' do context 'when ref and sha exists' do
let(:pipeline) do let(:command) do
build_stubbed(:ci_pipeline, ref: 'master', sha: '123', project: project) Gitlab::Ci::Pipeline::Chain::Command.new(
project: project, current_user: user, origin_ref: 'master', checkout_sha: project.commit.id)
end end
it 'does not break the chain' do it 'does not break the chain' do
...@@ -28,9 +26,10 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Repository do ...@@ -28,9 +26,10 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Repository do
end end
end end
context 'when pipeline ref does not exist' do context 'when ref does not exist' do
let(:pipeline) do let(:command) do
build_stubbed(:ci_pipeline, ref: 'something', project: project) Gitlab::Ci::Pipeline::Chain::Command.new(
project: project, current_user: user, origin_ref: 'something')
end end
it 'breaks the chain' do it 'breaks the chain' do
...@@ -43,9 +42,10 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Repository do ...@@ -43,9 +42,10 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Repository do
end end
end end
context 'when pipeline does not have SHA set' do context 'when does not have existing SHA set' do
let(:pipeline) do let(:command) do
build_stubbed(:ci_pipeline, ref: 'master', sha: nil, project: project) Gitlab::Ci::Pipeline::Chain::Command.new(
project: project, current_user: user, origin_ref: 'master', checkout_sha: 'something')
end end
it 'breaks the chain' do it 'breaks the chain' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment