diff --git a/CHANGELOG b/CHANGELOG index d1500ab7d3a044ca349708846200ae8c0688c1a4..c60fd2f2ca8432e9c7969a1b7e7f3c019e092570 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -26,6 +26,7 @@ v 8.4.0 (unreleased) - Properly set task-list class on single item task lists - Add file finder feature in tree view (Kyungchul Shin) - Ajax filter by message for commits page + - API: Add support for deleting a tag via the API (Robert Schilling) v 8.3.3 (unreleased) - Get "Merge when build succeeds" to work when commits were pushed to MR target branch while builds were running diff --git a/doc/api/tags.md b/doc/api/tags.md index 085d387e824240c39f3aec0410c385dd4a80321d..17d12e9cc62a3b7bd1301d150dbf018842d7105f 100644 --- a/doc/api/tags.md +++ b/doc/api/tags.md @@ -83,6 +83,26 @@ it will contain the annotation. It returns 200 if the operation succeed. In case of an error, 405 with an explaining error message is returned. +## Delete a tag + +Deletes a tag of a repository with given name. On success, this API method +returns 200 with the name of the deleted tag. If the tag does not exist, the +API returns 404. + +``` +DELETE /projects/:id/repository/tags/:tag_name +``` + +Parameters: + +- `id` (required) - The ID of a project +- `tag_name` (required) - The name of a tag + +```json +{ + "tag_name": "v4.3.0" +} +``` ## Create a new release diff --git a/lib/api/tags.rb b/lib/api/tags.rb index 47621f443e6c088ffd66ff804c497353314d8a28..2d8a9e51bb9f5af253d50a8c8eba503c13a7069b 100644 --- a/lib/api/tags.rb +++ b/lib/api/tags.rb @@ -40,6 +40,27 @@ module API end end + # Delete tag + # + # Parameters: + # id (required) - The ID of a project + # tag_name (required) - The name of the tag + # Example Request: + # DELETE /projects/:id/repository/tags/:tag + delete ":id/repository/tags/:tag_name", requirements: { tag_name: /.*/ } do + authorize_push_project + result = DeleteTagService.new(user_project, current_user). + execute(params[:tag_name]) + + if result[:status] == :success + { + tag_name: params[:tag_name] + } + else + render_api_error!(result[:message], result[:return_code]) + end + end + # Add release notes to tag # # Parameters: diff --git a/spec/requests/api/tags_spec.rb b/spec/requests/api/tags_spec.rb index 17f2643fd45f25ad1f7076ba363f1ae76699dbd1..f966e38cd3e0d17a564478955f7a42c4f8e58534 100644 --- a/spec/requests/api/tags_spec.rb +++ b/spec/requests/api/tags_spec.rb @@ -65,6 +65,27 @@ describe API::API, api: true do end end + describe 'DELETE /projects/:id/repository/tags/:tag_name' do + let(:tag_name) { project.repository.tag_names.sort.reverse.first } + + before do + allow_any_instance_of(Repository).to receive(:rm_tag).and_return(true) + end + + context 'delete tag' do + it 'should delete an existing tag' do + delete api("/projects/#{project.id}/repository/tags/#{tag_name}", user) + expect(response.status).to eq(200) + expect(json_response['tag_name']).to eq(tag_name) + end + + it 'should raise 404 if the tag does not exist' do + delete api("/projects/#{project.id}/repository/tags/foobar", user) + expect(response.status).to eq(404) + end + end + end + context 'annotated tag' do it 'should create a new annotated tag' do # Identity must be set in .gitconfig to create annotated tag.