Commit 678f3ddd authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge pull request #7305 from asedge/annotated_tags

Annotated tags
parents 69d149e0 468b2e8e
...@@ -15,6 +15,7 @@ v 7.3.0 ...@@ -15,6 +15,7 @@ v 7.3.0
- API: filter issues by labels (Julien Bianchi) - API: filter issues by labels (Julien Bianchi)
- Add system hook for ssh key changes - Add system hook for ssh key changes
- Add blob permalink link (Ciro Santilli) - Add blob permalink link (Ciro Santilli)
- Create annotated tags through UI and API (Sean Edge)
v 7.2.0 v 7.2.0
- Explore page - Explore page
......
...@@ -14,7 +14,8 @@ class Projects::TagsController < Projects::ApplicationController ...@@ -14,7 +14,8 @@ class Projects::TagsController < Projects::ApplicationController
def create def create
result = CreateTagService.new.execute(@project, params[:tag_name], result = CreateTagService.new.execute(@project, params[:tag_name],
params[:ref], current_user) params[:ref], params[:message],
current_user)
if result[:status] == :success if result[:status] == :success
@tag = result[:tag] @tag = result[:tag]
redirect_to project_tags_path(@project) redirect_to project_tags_path(@project)
......
...@@ -64,10 +64,10 @@ class Repository ...@@ -64,10 +64,10 @@ class Repository
gitlab_shell.add_branch(path_with_namespace, branch_name, ref) gitlab_shell.add_branch(path_with_namespace, branch_name, ref)
end end
def add_tag(tag_name, ref) def add_tag(tag_name, ref, message = nil)
Rails.cache.delete(cache_key(:tag_names)) Rails.cache.delete(cache_key(:tag_names))
gitlab_shell.add_tag(path_with_namespace, tag_name, ref) gitlab_shell.add_tag(path_with_namespace, tag_name, ref, message)
end end
def rm_branch(branch_name) def rm_branch(branch_name)
......
class CreateTagService class CreateTagService
def execute(project, tag_name, ref, current_user) def execute(project, tag_name, ref, message, current_user)
valid_tag = Gitlab::GitRefValidator.validate(tag_name) valid_tag = Gitlab::GitRefValidator.validate(tag_name)
if valid_tag == false if valid_tag == false
return error('Tag name invalid') return error('Tag name invalid')
...@@ -11,7 +11,11 @@ class CreateTagService ...@@ -11,7 +11,11 @@ class CreateTagService
return error('Tag already exists') return error('Tag already exists')
end end
repository.add_tag(tag_name, ref) if message
message.gsub!(/^\s+|\s+$/, '')
end
repository.add_tag(tag_name, ref, message)
new_tag = repository.find_tag(tag_name) new_tag = repository.find_tag(tag_name)
if new_tag if new_tag
......
...@@ -15,6 +15,11 @@ ...@@ -15,6 +15,11 @@
.col-sm-10 .col-sm-10
= text_field_tag :ref, params[:ref], placeholder: 'master', required: true, tabindex: 2, class: 'form-control' = text_field_tag :ref, params[:ref], placeholder: 'master', required: true, tabindex: 2, class: 'form-control'
.light Branch name or commit SHA .light Branch name or commit SHA
.form-group
= label_tag :message, 'Message', class: 'control-label'
.col-sm-10
= text_field_tag :message, nil, placeholder: 'Enter message.', required: false, tabindex: 3, class: 'form-control'
.light (Optional) Entering a message will create an annotated tag.
.form-actions .form-actions
= submit_tag 'Create tag', class: 'btn btn-create', tabindex: 3 = submit_tag 'Create tag', class: 'btn btn-create', tabindex: 3
= link_to 'Cancel', project_tags_path(@project), class: 'btn btn-cancel' = link_to 'Cancel', project_tags_path(@project), class: 'btn btn-cancel'
......
...@@ -50,6 +50,7 @@ Parameters: ...@@ -50,6 +50,7 @@ Parameters:
- `id` (required) - The ID of a project - `id` (required) - The ID of a project
- `tag_name` (required) - The name of a tag - `tag_name` (required) - The name of a tag
- `ref` (required) - Create tag using commit SHA, another tag name, or branch name. - `ref` (required) - Create tag using commit SHA, another tag name, or branch name.
- `message` (optional) - Creates annotated tag.
```json ```json
[ [
......
...@@ -32,12 +32,15 @@ module API ...@@ -32,12 +32,15 @@ module API
# id (required) - The ID of a project # id (required) - The ID of a project
# tag_name (required) - The name of the tag # tag_name (required) - The name of the tag
# ref (required) - Create tag from commit sha or branch # ref (required) - Create tag from commit sha or branch
# message (optional) - Specifying a message creates an annotated tag.
# Example Request: # Example Request:
# POST /projects/:id/repository/tags # POST /projects/:id/repository/tags
post ':id/repository/tags' do post ':id/repository/tags' do
authorize_push_project authorize_push_project
message = params[:message] || nil
result = CreateTagService.new.execute(user_project, params[:tag_name], result = CreateTagService.new.execute(user_project, params[:tag_name],
params[:ref], current_user) params[:ref], message,
current_user)
if result[:status] == :success if result[:status] == :success
present result[:tag], present result[:tag],
with: Entities::RepoObject, with: Entities::RepoObject,
......
...@@ -107,12 +107,17 @@ module Gitlab ...@@ -107,12 +107,17 @@ module Gitlab
# path - project path with namespace # path - project path with namespace
# tag_name - new tag name # tag_name - new tag name
# ref - HEAD for new tag # ref - HEAD for new tag
# message - optional message for tag (annotated tag)
# #
# Ex. # Ex.
# add_tag("gitlab/gitlab-ci", "v4.0", "master") # add_tag("gitlab/gitlab-ci", "v4.0", "master")
# add_tag("gitlab/gitlab-ci", "v4.0", "master", "message")
# #
def add_tag(path, tag_name, ref) def add_tag(path, tag_name, ref, message = nil)
system "#{gitlab_shell_path}/bin/gitlab-projects", "create-tag", "#{path}.git", tag_name, ref cmd = %W(#{gitlab_shell_path}/bin/gitlab-projects create-tag #{path}.git
#{tag_name} #{ref})
cmd << message unless message.nil? || message.empty?
system *cmd
end end
# Remove repository tag # Remove repository tag
......
...@@ -23,12 +23,29 @@ describe API::API, api: true do ...@@ -23,12 +23,29 @@ describe API::API, api: true do
end end
describe 'POST /projects/:id/repository/tags' do describe 'POST /projects/:id/repository/tags' do
it 'should create a new tag' do context 'lightweight tags' do
post api("/projects/#{project.id}/repository/tags", user), it 'should create a new tag' do
tag_name: 'v2.0.0', post api("/projects/#{project.id}/repository/tags", user),
ref: 'master' tag_name: 'v1.0.0',
response.status.should == 201 ref: 'master'
json_response['name'].should == 'v2.0.0'
response.status.should == 201
json_response['name'].should == 'v1.0.0'
end
end
context 'annotated tag' do
it 'should create a new annotated tag' do
post api("/projects/#{project.id}/repository/tags", user),
tag_name: 'v1.0.0',
ref: 'master',
message: 'tag message'
response.status.should == 201
json_response['name'].should == 'v1.0.0'
# The message is not part of the JSON response.
# Additional changes to the gitlab_git gem may be required.
# json_response['message'].should == 'tag message'
end
end end
it 'should deny for user without push access' do it 'should deny for user without push access' 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