summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRémy Coutable <remy@rymai.me>2016-04-25 16:31:45 +0200
committerRémy Coutable <remy@rymai.me>2016-05-04 17:19:13 +0200
commit209f2f1e6fd861dd7bb6a73389400b4bb266d26d (patch)
tree6b945d01503fd1b52a7d8b73fe162f69144d257f
parent44f89eafc08a7967544429a3f930354a5f9bbbaf (diff)
downloadgitlab-ce-use-rugged-to-create-tag.tar.gz
Use a similar approach to branch creation for tag creationuse-rugged-to-create-tag
Signed-off-by: Rémy Coutable <remy@rymai.me>
-rw-r--r--app/models/repository.rb17
-rw-r--r--app/services/create_branch_service.rb5
-rw-r--r--app/services/create_tag_service.rb46
-rw-r--r--spec/models/repository_spec.rb34
-rw-r--r--spec/services/create_tag_service_spec.rb53
5 files changed, 102 insertions, 53 deletions
diff --git a/app/models/repository.rb b/app/models/repository.rb
index c4e38980a83..d5d70f41fd3 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -146,17 +146,20 @@ class Repository
find_branch(branch_name)
end
- def add_tag(user, tag_name, ref, message = nil)
- before_push_tag
+ def add_tag(user, tag_name, target, message = nil)
+ 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
- tag = rugged.tags.create(tag_name, ref, options)
- if tag.annotated?
- Gitlab::Git::Tag.new(tag_name, ref, tag.annotation.message)
- else
- Gitlab::Git::Tag.new(tag_name, ref)
+ GitHooksService.new.execute(user, path_to_repo, oldrev, target, ref) do
+ rugged.tags.create(tag_name, target, options)
end
+
+ find_tag(tag_name)
end
def rm_branch(user, branch_name)
diff --git a/app/services/create_branch_service.rb b/app/services/create_branch_service.rb
index 707c2f7ff85..9f4481a8153 100644
--- a/app/services/create_branch_service.rb
+++ b/app/services/create_branch_service.rb
@@ -43,9 +43,4 @@ class CreateBranchService < BaseService
out[:branch] = branch
out
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
diff --git a/app/services/create_tag_service.rb b/app/services/create_tag_service.rb
index 775f9db2a46..91ed0e354d0 100644
--- a/app/services/create_tag_service.rb
+++ b/app/services/create_tag_service.rb
@@ -1,46 +1,30 @@
require_relative 'base_service'
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)
- if valid_tag == false
- return error('Tag name invalid')
- end
+ return error('Tag name invalid') unless valid_tag
repository = project.repository
message.strip! if message
+
+ new_tag = nil
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
return error("Tag #{tag_name} already exists")
- rescue Rugged::ReferenceError
- return error("Target #{ref} is invalid")
+ rescue GitHooksService::PreReceiveError
+ return error('Tag creation was rejected by Git hook')
end
- push_data = create_push_data(project, current_user, new_tag)
-
- EventCreateService.new.push(project, current_user, push_data)
- project.execute_hooks(push_data.dup, :tag_push_hooks)
- project.execute_services(push_data.dup, :tag_push_hooks)
- CreateCommitBuildsService.new.execute(project, current_user, push_data)
-
- if release_description
- CreateReleaseService.new(@project, @current_user).
- execute(tag_name, release_description)
+ if new_tag
+ if release_description
+ CreateReleaseService.new(@project, @current_user).
+ execute(tag_name, release_description)
+ end
+ success.merge(tag: new_tag)
+ else
+ error("Target #{target} is invalid")
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
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 5cdf644a0e1..b3359a42237 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -858,16 +858,30 @@ describe Repository, models: true do
end
describe '#add_tag' do
- it 'adds a tag' do
- user = build_stubbed(:user)
- expect(repository).to receive(:before_push_tag)
- expect(repository.rugged.tags).to receive(:create).
- with('8.5', 'master',
- hash_including(message: 'foo',
- tagger: hash_including(name: user.name, email: user.email))).
- and_call_original
-
- repository.add_tag(user, '8.5', 'master', 'foo')
+ context 'with a valid target' do
+ let(:user) { build_stubbed(:user) }
+
+ it 'creates the tag using rugged' do
+ expect(repository.rugged.tags).to receive(:create).
+ with('8.5', repository.commit('master').id,
+ hash_including(message: 'foo',
+ tagger: hash_including(name: user.name, email: user.email))).
+ and_call_original
+
+ 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
diff --git a/spec/services/create_tag_service_spec.rb b/spec/services/create_tag_service_spec.rb
new file mode 100644
index 00000000000..91f9e663b66
--- /dev/null
+++ b/spec/services/create_tag_service_spec.rb
@@ -0,0 +1,53 @@
+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