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
def execute(source, ignore_skip_ci: false, save_on_errors: true, trigger_request: nil, schedule: nil, &block)
@pipeline = Ci::Pipeline.new
command = OpenStruct.new(source: source,
origin_ref: params[:ref],
checkout_sha: params[:checkout_sha],
after_sha: params[:after],
before_sha: params[:before],
trigger_request: trigger_request,
schedule: schedule,
ignore_skip_ci: ignore_skip_ci,
save_incompleted: save_on_errors,
seeds_block: block,
project: project,
current_user: current_user)
command = Gitlab::Ci::Pipeline::Chain::Command.new(
source: source,
origin_ref: params[:ref],
checkout_sha: params[:checkout_sha],
after_sha: params[:after],
before_sha: params[:before],
trigger_request: trigger_request,
schedule: schedule,
ignore_skip_ci: ignore_skip_ci,
save_incompleted: save_on_errors,
seeds_block: block,
project: project,
current_user: current_user)
sequence = Gitlab::Ci::Pipeline::Chain::Sequence
.new(pipeline, command, SEQUENCE)
......
......@@ -3,14 +3,13 @@ module Gitlab
module Pipeline
module Chain
class Base
attr_reader :pipeline, :project, :current_user
attr_reader :pipeline, :command
delegate :project, :current_user, to: :command
def initialize(pipeline, command)
@pipeline = pipeline
@command = command
@project = command.project
@current_user = command.current_user
end
def perform!
......
......@@ -6,15 +6,15 @@ module Gitlab
def perform!
@pipeline.assign_attributes(
source: @command.source,
project: @project,
ref: ref,
sha: sha,
before_sha: before_sha,
tag: tag_exists?,
project: @command.project,
ref: @command.ref,
sha: @command.sha,
before_sha: @command.before_sha,
tag: @command.tag_exists?,
trigger_requests: Array(@command.trigger_request),
user: @current_user,
user: @command.current_user,
pipeline_schedule: @command.schedule,
protected: protected_ref?
protected: @command.protected_ref?
)
@pipeline.set_config_source
......@@ -23,36 +23,6 @@ module Gitlab
def break?
false
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
......
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
module Pipeline
module Chain
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)
pipeline.errors.add(:base, message)
end
......
......@@ -14,7 +14,7 @@ module Gitlab
unless allowed_to_trigger_pipeline?
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
return error('Insufficient permissions to create a new pipeline')
end
......@@ -29,7 +29,7 @@ module Gitlab
if current_user
allowed_to_create?
else # legacy triggers don't have a corresponding user
!project.protected_for?(@pipeline.ref)
!@command.protected_ref?
end
end
......@@ -38,10 +38,10 @@ module Gitlab
access = Gitlab::UserAccess.new(current_user, project: project)
if branch_exists?
access.can_update_branch?(@pipeline.ref)
elsif tag_exists?
access.can_create_tag?(@pipeline.ref)
if @command.branch_exists?
access.can_update_branch?(@command.ref)
elsif @command.tag_exists?
access.can_create_tag?(@command.ref)
else
true # Allow it for now and we'll reject when we check ref existence
end
......
......@@ -7,14 +7,11 @@ module Gitlab
include Chain::Helpers
def perform!
unless branch_exists? || tag_exists?
unless @command.branch_exists? || @command.tag_exists?
return error('Reference not found')
end
## TODO, we check commit in the service, that is why
# there is no repository access here.
#
unless pipeline.sha
unless @command.sha
return error('Commit not found')
end
end
......
......@@ -6,15 +6,16 @@ describe Gitlab::Ci::Pipeline::Chain::Build do
let(:pipeline) { Ci::Pipeline.new }
let(:command) do
double('command', source: :push,
origin_ref: 'master',
checkout_sha: project.commit.id,
after_sha: nil,
before_sha: nil,
trigger_request: nil,
schedule: nil,
project: project,
current_user: user)
Gitlab::Ci::Pipeline::Chain::Command.new(
source: :push,
origin_ref: 'master',
checkout_sha: project.commit.id,
after_sha: nil,
before_sha: nil,
trigger_request: nil,
schedule: nil,
project: project,
current_user: user)
end
let(:step) { described_class.new(pipeline, command) }
......@@ -60,19 +61,20 @@ describe Gitlab::Ci::Pipeline::Chain::Build do
context 'when pipeline is running for a tag' do
let(:command) do
double('command', source: :push,
origin_ref: 'mytag',
checkout_sha: project.commit.id,
after_sha: nil,
before_sha: nil,
trigger_request: nil,
schedule: nil,
project: project,
current_user: user)
Gitlab::Ci::Pipeline::Chain::Command.new(
source: :push,
origin_ref: 'mytag',
checkout_sha: project.commit.id,
after_sha: nil,
before_sha: nil,
trigger_request: nil,
schedule: nil,
project: project,
current_user: user)
end
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!
end
......
......@@ -10,9 +10,9 @@ describe Gitlab::Ci::Pipeline::Chain::Create do
end
let(:command) do
double('command', project: project,
current_user: user,
seeds_block: nil)
Gitlab::Ci::Pipeline::Chain::Command.new(
project: project,
current_user: user,seeds_block: nil)
end
let(:step) { described_class.new(pipeline, command) }
......
......@@ -5,7 +5,7 @@ describe Gitlab::Ci::Pipeline::Chain::Sequence do
set(:user) { create(:user) }
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(:second_step) { spy('second step') }
let(:sequence) { [first_step, second_step] }
......
......@@ -6,10 +6,11 @@ describe Gitlab::Ci::Pipeline::Chain::Skip do
set(:pipeline) { create(:ci_pipeline, project: project) }
let(:command) do
double('command', project: project,
current_user: user,
ignore_skip_ci: false,
save_incompleted: true)
Gitlab::Ci::Pipeline::Chain::Command.new(
project: project,
current_user: user,
ignore_skip_ci: false,
save_incompleted: true)
end
let(:step) { described_class.new(pipeline, command) }
......
......@@ -5,11 +5,12 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Abilities do
set(:user) { create(:user) }
let(:pipeline) do
build_stubbed(:ci_pipeline, ref: ref, project: project)
build_stubbed(:ci_pipeline, project: project)
end
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
let(:step) { described_class.new(pipeline, command) }
......
......@@ -5,9 +5,10 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Config do
set(:user) { create(:user) }
let(:command) do
double('command', project: project,
current_user: user,
save_incompleted: true)
Gitlab::Ci::Pipeline::Chain::Command.new(
project: project,
current_user: user,
save_incompleted: true)
end
let!(:step) { described_class.new(pipeline, command) }
......
......@@ -3,10 +3,7 @@ require 'spec_helper'
describe Gitlab::Ci::Pipeline::Chain::Validate::Repository do
set(:project) { create(:project, :repository) }
set(:user) { create(:user) }
let(:command) do
double('command', project: project, current_user: user)
end
let(:pipeline) { build_stubbed(:ci_pipeline) }
let!(:step) { described_class.new(pipeline, command) }
......@@ -14,9 +11,10 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Repository do
step.perform!
end
context 'when pipeline ref and sha exists' do
let(:pipeline) do
build_stubbed(:ci_pipeline, ref: 'master', sha: '123', project: project)
context 'when ref and sha exists' do
let(:command) do
Gitlab::Ci::Pipeline::Chain::Command.new(
project: project, current_user: user, origin_ref: 'master', checkout_sha: project.commit.id)
end
it 'does not break the chain' do
......@@ -28,9 +26,10 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Repository do
end
end
context 'when pipeline ref does not exist' do
let(:pipeline) do
build_stubbed(:ci_pipeline, ref: 'something', project: project)
context 'when ref does not exist' do
let(:command) do
Gitlab::Ci::Pipeline::Chain::Command.new(
project: project, current_user: user, origin_ref: 'something')
end
it 'breaks the chain' do
......@@ -43,9 +42,10 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Repository do
end
end
context 'when pipeline does not have SHA set' do
let(:pipeline) do
build_stubbed(:ci_pipeline, ref: 'master', sha: nil, project: project)
context 'when does not have existing SHA set' do
let(:command) do
Gitlab::Ci::Pipeline::Chain::Command.new(
project: project, current_user: user, origin_ref: 'master', checkout_sha: 'something')
end
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