Skip to content

Commit 0b2aa4a

Browse files
6543techknowlogick
authored andcommitted
[API] Add repoGetTag (go-gitea#16166)
* GetTag -> GetAnnotatedTag * API: Add repoGetTag * fix swagger docs * support "/" as tag name char Co-authored-by: techknowlogick <techknowlogick@gitea.io>
1 parent 475e30c commit 0b2aa4a

File tree

4 files changed

+132
-37
lines changed

4 files changed

+132
-37
lines changed

integrations/api_repo_tags_test.go

+15-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func TestAPIRepoTags(t *testing.T) {
3939
assert.Equal(t, setting.AppURL+"user2/repo1/archive/v1.1.zip", tags[0].ZipballURL)
4040
assert.Equal(t, setting.AppURL+"user2/repo1/archive/v1.1.tar.gz", tags[0].TarballURL)
4141

42-
newTag := createNewTagUsingAPI(t, session, token, user.Name, repoName, "awesome-tag", "", "nice!\nand some text")
42+
newTag := createNewTagUsingAPI(t, session, token, user.Name, repoName, "gitea/22", "", "nice!\nand some text")
4343
resp = session.MakeRequest(t, req, http.StatusOK)
4444
DecodeJSON(t, resp, &tags)
4545
assert.Len(t, tags, 2)
@@ -51,6 +51,20 @@ func TestAPIRepoTags(t *testing.T) {
5151
assert.EqualValues(t, newTag.Commit.SHA, tag.Commit.SHA)
5252
}
5353
}
54+
55+
// get created tag
56+
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/tags/%s?token=%s", user.Name, repoName, newTag.Name, token)
57+
resp = session.MakeRequest(t, req, http.StatusOK)
58+
var tag *api.Tag
59+
DecodeJSON(t, resp, &tag)
60+
assert.EqualValues(t, newTag, tag)
61+
62+
// delete tag
63+
delReq := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/tags/%s?token=%s", user.Name, repoName, newTag.Name, token)
64+
resp = session.MakeRequest(t, delReq, http.StatusNoContent)
65+
66+
// check if it's gone
67+
resp = session.MakeRequest(t, req, http.StatusNotFound)
5468
}
5569

5670
func createNewTagUsingAPI(t *testing.T, session *TestSession, token string, ownerName, repoName, name, target, msg string) *api.Tag {

routers/api/v1/api.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -783,8 +783,9 @@ func Routes() *web.Route {
783783
}, reqToken(), reqAdmin())
784784
m.Group("/tags", func() {
785785
m.Get("", repo.ListTags)
786+
m.Get("/*", repo.GetTag)
786787
m.Post("", reqRepoWriter(models.UnitTypeCode), bind(api.CreateTagOption{}), repo.CreateTag)
787-
m.Delete("/{tag}", repo.DeleteTag)
788+
m.Delete("/*", repo.DeleteTag)
788789
}, reqRepoReader(models.UnitTypeCode), context.ReferencesGitRepo(true))
789790
m.Group("/keys", func() {
790791
m.Combo("").Get(repo.ListDeployKeys).
@@ -949,7 +950,7 @@ func Routes() *web.Route {
949950
m.Get("/refs/*", repo.GetGitRefs)
950951
m.Get("/trees/{sha}", context.RepoRefForAPI, repo.GetTree)
951952
m.Get("/blobs/{sha}", context.RepoRefForAPI, repo.GetBlob)
952-
m.Get("/tags/{sha}", context.RepoRefForAPI, repo.GetTag)
953+
m.Get("/tags/{sha}", context.RepoRefForAPI, repo.GetAnnotatedTag)
953954
}, reqRepoReader(models.UnitTypeCode))
954955
m.Group("/contents", func() {
955956
m.Get("", repo.GetContentsList)

routers/api/v1/repo/tag.go

+71-32
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ func ListTags(ctx *context.APIContext) {
6464
ctx.JSON(http.StatusOK, &apiTags)
6565
}
6666

67-
// GetTag get the tag of a repository.
68-
func GetTag(ctx *context.APIContext) {
69-
// swagger:operation GET /repos/{owner}/{repo}/git/tags/{sha} repository GetTag
67+
// GetAnnotatedTag get the tag of a repository.
68+
func GetAnnotatedTag(ctx *context.APIContext) {
69+
// swagger:operation GET /repos/{owner}/{repo}/git/tags/{sha} repository GetAnnotatedTag
7070
// ---
7171
// summary: Gets the tag object of an annotated tag (not lightweight tags)
7272
// produces:
@@ -100,21 +100,21 @@ func GetTag(ctx *context.APIContext) {
100100
}
101101

102102
if tag, err := ctx.Repo.GitRepo.GetAnnotatedTag(sha); err != nil {
103-
ctx.Error(http.StatusBadRequest, "GetTag", err)
103+
ctx.Error(http.StatusBadRequest, "GetAnnotatedTag", err)
104104
} else {
105105
commit, err := tag.Commit()
106106
if err != nil {
107-
ctx.Error(http.StatusBadRequest, "GetTag", err)
107+
ctx.Error(http.StatusBadRequest, "GetAnnotatedTag", err)
108108
}
109109
ctx.JSON(http.StatusOK, convert.ToAnnotatedTag(ctx.Repo.Repository, tag, commit))
110110
}
111111
}
112112

113-
// DeleteTag delete a specific tag of in a repository by name
114-
func DeleteTag(ctx *context.APIContext) {
115-
// swagger:operation DELETE /repos/{owner}/{repo}/tags/{tag} repository repoDeleteTag
113+
// GetTag get the tag of a repository
114+
func GetTag(ctx *context.APIContext) {
115+
// swagger:operation GET /repos/{owner}/{repo}/tags/{tag} repository repoGetTag
116116
// ---
117-
// summary: Delete a repository's tag by name
117+
// summary: Get the tag of a repository by tag name
118118
// produces:
119119
// - application/json
120120
// parameters:
@@ -130,37 +130,22 @@ func DeleteTag(ctx *context.APIContext) {
130130
// required: true
131131
// - name: tag
132132
// in: path
133-
// description: name of tag to delete
133+
// description: name of tag
134134
// type: string
135135
// required: true
136136
// responses:
137-
// "204":
138-
// "$ref": "#/responses/empty"
137+
// "200":
138+
// "$ref": "#/responses/Tag"
139139
// "404":
140140
// "$ref": "#/responses/notFound"
141-
// "409":
142-
// "$ref": "#/responses/conflict"
141+
tagName := ctx.Params("*")
143142

144-
tag, err := models.GetRelease(ctx.Repo.Repository.ID, ctx.Params("tag"))
143+
tag, err := ctx.Repo.GitRepo.GetTag(tagName)
145144
if err != nil {
146-
if models.IsErrReleaseNotExist(err) {
147-
ctx.NotFound()
148-
return
149-
}
150-
ctx.Error(http.StatusInternalServerError, "GetRelease", err)
145+
ctx.NotFound(tagName)
151146
return
152147
}
153-
154-
if !tag.IsTag {
155-
ctx.Error(http.StatusConflict, "IsTag", errors.New("a tag attached to a release cannot be deleted directly"))
156-
return
157-
}
158-
159-
if err = releaseservice.DeleteReleaseByID(tag.ID, ctx.User, true); err != nil {
160-
ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err)
161-
}
162-
163-
ctx.Status(http.StatusNoContent)
148+
ctx.JSON(http.StatusOK, convert.ToTag(ctx.Repo.Repository, tag))
164149
}
165150

166151
// CreateTag create a new git tag in a repository
@@ -187,7 +172,7 @@ func CreateTag(ctx *context.APIContext) {
187172
// "$ref": "#/definitions/CreateTagOption"
188173
// responses:
189174
// "200":
190-
// "$ref": "#/responses/AnnotatedTag"
175+
// "$ref": "#/responses/Tag"
191176
// "404":
192177
// "$ref": "#/responses/notFound"
193178
// "409":
@@ -221,3 +206,57 @@ func CreateTag(ctx *context.APIContext) {
221206
}
222207
ctx.JSON(http.StatusCreated, convert.ToTag(ctx.Repo.Repository, tag))
223208
}
209+
210+
// DeleteTag delete a specific tag of in a repository by name
211+
func DeleteTag(ctx *context.APIContext) {
212+
// swagger:operation DELETE /repos/{owner}/{repo}/tags/{tag} repository repoDeleteTag
213+
// ---
214+
// summary: Delete a repository's tag by name
215+
// produces:
216+
// - application/json
217+
// parameters:
218+
// - name: owner
219+
// in: path
220+
// description: owner of the repo
221+
// type: string
222+
// required: true
223+
// - name: repo
224+
// in: path
225+
// description: name of the repo
226+
// type: string
227+
// required: true
228+
// - name: tag
229+
// in: path
230+
// description: name of tag to delete
231+
// type: string
232+
// required: true
233+
// responses:
234+
// "204":
235+
// "$ref": "#/responses/empty"
236+
// "404":
237+
// "$ref": "#/responses/notFound"
238+
// "409":
239+
// "$ref": "#/responses/conflict"
240+
tagName := ctx.Params("*")
241+
242+
tag, err := models.GetRelease(ctx.Repo.Repository.ID, tagName)
243+
if err != nil {
244+
if models.IsErrReleaseNotExist(err) {
245+
ctx.NotFound()
246+
return
247+
}
248+
ctx.Error(http.StatusInternalServerError, "GetRelease", err)
249+
return
250+
}
251+
252+
if !tag.IsTag {
253+
ctx.Error(http.StatusConflict, "IsTag", errors.New("a tag attached to a release cannot be deleted directly"))
254+
return
255+
}
256+
257+
if err = releaseservice.DeleteReleaseByID(tag.ID, ctx.User, true); err != nil {
258+
ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err)
259+
}
260+
261+
ctx.Status(http.StatusNoContent)
262+
}

templates/swagger/v1_json.tmpl

+43-2
Original file line numberDiff line numberDiff line change
@@ -3657,7 +3657,7 @@
36573657
"repository"
36583658
],
36593659
"summary": "Gets the tag object of an annotated tag (not lightweight tags)",
3660-
"operationId": "GetTag",
3660+
"operationId": "GetAnnotatedTag",
36613661
"parameters": [
36623662
{
36633663
"type": "string",
@@ -9117,7 +9117,7 @@
91179117
],
91189118
"responses": {
91199119
"200": {
9120-
"$ref": "#/responses/AnnotatedTag"
9120+
"$ref": "#/responses/Tag"
91219121
},
91229122
"404": {
91239123
"$ref": "#/responses/notFound"
@@ -9129,6 +9129,47 @@
91299129
}
91309130
},
91319131
"/repos/{owner}/{repo}/tags/{tag}": {
9132+
"get": {
9133+
"produces": [
9134+
"application/json"
9135+
],
9136+
"tags": [
9137+
"repository"
9138+
],
9139+
"summary": "Get the tag of a repository by tag name",
9140+
"operationId": "repoGetTag",
9141+
"parameters": [
9142+
{
9143+
"type": "string",
9144+
"description": "owner of the repo",
9145+
"name": "owner",
9146+
"in": "path",
9147+
"required": true
9148+
},
9149+
{
9150+
"type": "string",
9151+
"description": "name of the repo",
9152+
"name": "repo",
9153+
"in": "path",
9154+
"required": true
9155+
},
9156+
{
9157+
"type": "string",
9158+
"description": "name of tag",
9159+
"name": "tag",
9160+
"in": "path",
9161+
"required": true
9162+
}
9163+
],
9164+
"responses": {
9165+
"200": {
9166+
"$ref": "#/responses/Tag"
9167+
},
9168+
"404": {
9169+
"$ref": "#/responses/notFound"
9170+
}
9171+
}
9172+
},
91329173
"delete": {
91339174
"produces": [
91349175
"application/json"

0 commit comments

Comments
 (0)