Commit 209f2f1e authored by Rémy Coutable's avatar Rémy Coutable

Use a similar approach to branch creation for tag creation

Signed-off-by: default avatarRémy Coutable <remy@rymai.me>
parent 44f89eaf
...@@ -146,17 +146,20 @@ class Repository ...@@ -146,17 +146,20 @@ class Repository
find_branch(branch_name) find_branch(branch_name)
end end
def add_tag(user, tag_name, ref, message = nil) def add_tag(user, tag_name, target, message = nil)
before_push_tag oldrev = Gitlab::Git::BLANK_SHA
ref = Gitlab::Git::TAG_REF_PREFIX + tag_name
target = commit(target).try(:id)
return false unless target
options = { message: message, tagger: user_to_committer(user) } if message options = { message: message, tagger: user_to_committer(user) } if message
tag = rugged.tags.create(tag_name, ref, options) GitHooksService.new.execute(user, path_to_repo, oldrev, target, ref) do
if tag.annotated? rugged.tags.create(tag_name, target, options)
Gitlab::Git::Tag.new(tag_name, ref, tag.annotation.message)
else
Gitlab::Git::Tag.new(tag_name, ref)
end end
find_tag(tag_name)
end end
def rm_branch(user, branch_name) def rm_branch(user, branch_name)
......
...@@ -43,9 +43,4 @@ class CreateBranchService < BaseService ...@@ -43,9 +43,4 @@ class CreateBranchService < BaseService
out[:branch] = branch out[:branch] = branch
out out
end end
def build_push_data(project, user, branch)
Gitlab::PushDataBuilder.
build(project, user, Gitlab::Git::BLANK_SHA, branch.target, "#{Gitlab::Git::BRANCH_REF_PREFIX}#{branch.name}", [])
end
end end
require_relative 'base_service' require_relative 'base_service'
class CreateTagService < BaseService class CreateTagService < BaseService
def execute(tag_name, ref, message, release_description = nil) def execute(tag_name, target, message, release_description = nil)
valid_tag = Gitlab::GitRefValidator.validate(tag_name) valid_tag = Gitlab::GitRefValidator.validate(tag_name)
if valid_tag == false return error('Tag name invalid') unless valid_tag
return error('Tag name invalid')
end
repository = project.repository repository = project.repository
message.strip! if message message.strip! if message
new_tag = nil
begin begin
new_tag = repository.add_tag(current_user, tag_name, ref, message) new_tag = repository.add_tag(current_user, tag_name, target, message)
rescue Rugged::TagError rescue Rugged::TagError
return error("Tag #{tag_name} already exists") return error("Tag #{tag_name} already exists")
rescue Rugged::ReferenceError rescue GitHooksService::PreReceiveError
return error("Target #{ref} is invalid") return error('Tag creation was rejected by Git hook')
end end
push_data = create_push_data(project, current_user, new_tag) if new_tag
if release_description
EventCreateService.new.push(project, current_user, push_data) CreateReleaseService.new(@project, @current_user).
project.execute_hooks(push_data.dup, :tag_push_hooks) execute(tag_name, release_description)
project.execute_services(push_data.dup, :tag_push_hooks) end
CreateCommitBuildsService.new.execute(project, current_user, push_data) success.merge(tag: new_tag)
else
if release_description error("Target #{target} is invalid")
CreateReleaseService.new(@project, @current_user).
execute(tag_name, release_description)
end end
success(new_tag)
end
def success(branch)
out = super()
out[:tag] = branch
out
end
def create_push_data(project, user, tag)
commits = [project.commit(tag.target)].compact
Gitlab::PushDataBuilder.
build(project, user, Gitlab::Git::BLANK_SHA, tag.target, "#{Gitlab::Git::TAG_REF_PREFIX}#{tag.name}", commits, tag.message)
end end
end end
...@@ -858,16 +858,30 @@ describe Repository, models: true do ...@@ -858,16 +858,30 @@ describe Repository, models: true do
end end
describe '#add_tag' do describe '#add_tag' do
it 'adds a tag' do context 'with a valid target' do
user = build_stubbed(:user) let(:user) { build_stubbed(:user) }
expect(repository).to receive(:before_push_tag)
expect(repository.rugged.tags).to receive(:create). it 'creates the tag using rugged' do
with('8.5', 'master', expect(repository.rugged.tags).to receive(:create).
hash_including(message: 'foo', with('8.5', repository.commit('master').id,
tagger: hash_including(name: user.name, email: user.email))). hash_including(message: 'foo',
and_call_original tagger: hash_including(name: user.name, email: user.email))).
and_call_original
repository.add_tag(user, '8.5', 'master', 'foo')
repository.add_tag(user, '8.5', 'master', 'foo')
end
it 'returns a Gitlab::Git::Tag object' do
tag = repository.add_tag(user, '8.5', 'master', 'foo')
expect(tag).to be_a(Gitlab::Git::Tag)
end
end
context 'with an invalid target' do
it 'returns false' do
expect(repository.add_tag(user, '8.5', 'bar', 'foo')).to be false
end
end end
end end
......
require 'spec_helper'
describe CreateTagService, services: true do
let(:project) { create(:project) }
let(:repository) { project.repository }
let(:user) { create(:user) }
let(:service) { described_class.new(project, user) }
describe '#execute' do
it 'creates the tag and returns success' do
response = service.execute('v42.42.42', 'master', 'Foo')
expect(response[:status]).to eq(:success)
expect(response[:tag]).to be_a Gitlab::Git::Tag
expect(response[:tag].name).to eq('v42.42.42')
end
context 'when target is invalid' do
it 'returns an error' do
response = service.execute('v1.1.0', 'foo', 'Foo')
expect(response).to eq(status: :error,
message: 'Target foo is invalid')
end
end
context 'when tag already exists' do
it 'returns an error' do
expect(repository).to receive(:add_tag).
with(user, 'v1.1.0', 'master', 'Foo').
and_raise(Rugged::TagError)
response = service.execute('v1.1.0', 'master', 'Foo')
expect(response).to eq(status: :error,
message: 'Tag v1.1.0 already exists')
end
end
context 'when pre-receive hook fails' do
it 'returns an error' do
expect(repository).to receive(:add_tag).
with(user, 'v1.1.0', 'master', 'Foo').
and_raise(GitHooksService::PreReceiveError)
response = service.execute('v1.1.0', 'master', 'Foo')
expect(response).to eq(status: :error,
message: 'Tag creation was rejected by Git hook')
end
end
end
end
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