Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[API] Add repoGetTag #16166

Merged
merged 12 commits into from
Jun 23, 2021
16 changes: 15 additions & 1 deletion integrations/api_repo_tags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func TestAPIRepoTags(t *testing.T) {
assert.Equal(t, setting.AppURL+"user2/repo1/archive/v1.1.zip", tags[0].ZipballURL)
assert.Equal(t, setting.AppURL+"user2/repo1/archive/v1.1.tar.gz", tags[0].TarballURL)

newTag := createNewTagUsingAPI(t, session, token, user.Name, repoName, "awesome-tag", "", "nice!\nand some text")
newTag := createNewTagUsingAPI(t, session, token, user.Name, repoName, "gitea/22", "", "nice!\nand some text")
resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &tags)
assert.Len(t, tags, 2)
Expand All @@ -51,6 +51,20 @@ func TestAPIRepoTags(t *testing.T) {
assert.EqualValues(t, newTag.Commit.SHA, tag.Commit.SHA)
}
}

// get created tag
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/tags/%s?token=%s", user.Name, repoName, newTag.Name, token)
6543 marked this conversation as resolved.
Show resolved Hide resolved
resp = session.MakeRequest(t, req, http.StatusOK)
var tag *api.Tag
DecodeJSON(t, resp, &tag)
assert.EqualValues(t, newTag, tag)

// delete tag
delReq := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/tags/%s?token=%s", user.Name, repoName, newTag.Name, token)
resp = session.MakeRequest(t, delReq, http.StatusNoContent)

// check if it's gone
resp = session.MakeRequest(t, req, http.StatusNotFound)
}

func createNewTagUsingAPI(t *testing.T, session *TestSession, token string, ownerName, repoName, name, target, msg string) *api.Tag {
Expand Down
5 changes: 3 additions & 2 deletions routers/api/v1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -779,8 +779,9 @@ func Routes() *web.Route {
}, reqToken(), reqAdmin())
m.Group("/tags", func() {
m.Get("", repo.ListTags)
m.Get("/*", repo.GetTag)
m.Post("", reqRepoWriter(models.UnitTypeCode), bind(api.CreateTagOption{}), repo.CreateTag)
m.Delete("/{tag}", repo.DeleteTag)
m.Delete("/*", repo.DeleteTag)
}, reqRepoReader(models.UnitTypeCode), context.ReferencesGitRepo(true))
m.Group("/keys", func() {
m.Combo("").Get(repo.ListDeployKeys).
Expand Down Expand Up @@ -945,7 +946,7 @@ func Routes() *web.Route {
m.Get("/refs/*", repo.GetGitRefs)
m.Get("/trees/{sha}", context.RepoRefForAPI, repo.GetTree)
m.Get("/blobs/{sha}", context.RepoRefForAPI, repo.GetBlob)
m.Get("/tags/{sha}", context.RepoRefForAPI, repo.GetTag)
m.Get("/tags/{sha}", context.RepoRefForAPI, repo.GetAnnotatedTag)
}, reqRepoReader(models.UnitTypeCode))
m.Group("/contents", func() {
m.Get("", repo.GetContentsList)
Expand Down
103 changes: 71 additions & 32 deletions routers/api/v1/repo/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ func ListTags(ctx *context.APIContext) {
ctx.JSON(http.StatusOK, &apiTags)
}

// GetTag get the tag of a repository.
func GetTag(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/git/tags/{sha} repository GetTag
// GetAnnotatedTag get the tag of a repository.
func GetAnnotatedTag(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/git/tags/{sha} repository GetAnnotatedTag
// ---
// summary: Gets the tag object of an annotated tag (not lightweight tags)
// produces:
Expand Down Expand Up @@ -100,21 +100,21 @@ func GetTag(ctx *context.APIContext) {
}

if tag, err := ctx.Repo.GitRepo.GetAnnotatedTag(sha); err != nil {
ctx.Error(http.StatusBadRequest, "GetTag", err)
ctx.Error(http.StatusBadRequest, "GetAnnotatedTag", err)
} else {
commit, err := tag.Commit()
if err != nil {
ctx.Error(http.StatusBadRequest, "GetTag", err)
ctx.Error(http.StatusBadRequest, "GetAnnotatedTag", err)
}
ctx.JSON(http.StatusOK, convert.ToAnnotatedTag(ctx.Repo.Repository, tag, commit))
}
}

// DeleteTag delete a specific tag of in a repository by name
func DeleteTag(ctx *context.APIContext) {
// swagger:operation DELETE /repos/{owner}/{repo}/tags/{tag} repository repoDeleteTag
// GetTag get the tag of a repository
func GetTag(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/tags/{tag} repository repoGetTag
// ---
// summary: Delete a repository's tag by name
// summary: Get the tag of a repository by tag name
// produces:
// - application/json
// parameters:
Expand All @@ -130,37 +130,22 @@ func DeleteTag(ctx *context.APIContext) {
// required: true
// - name: tag
// in: path
// description: name of tag to delete
// description: name of tag
// type: string
// required: true
// responses:
// "204":
// "$ref": "#/responses/empty"
// "200":
6543 marked this conversation as resolved.
Show resolved Hide resolved
// "$ref": "#/responses/Tag"
// "404":
// "$ref": "#/responses/notFound"
// "409":
// "$ref": "#/responses/conflict"
tagName := ctx.Params("*")

tag, err := models.GetRelease(ctx.Repo.Repository.ID, ctx.Params("tag"))
tag, err := ctx.Repo.GitRepo.GetTag(tagName)
if err != nil {
if models.IsErrReleaseNotExist(err) {
ctx.NotFound()
return
}
ctx.Error(http.StatusInternalServerError, "GetRelease", err)
ctx.NotFound(tagName)
return
}

if !tag.IsTag {
ctx.Error(http.StatusConflict, "IsTag", errors.New("a tag attached to a release cannot be deleted directly"))
return
}

if err = releaseservice.DeleteReleaseByID(tag.ID, ctx.User, true); err != nil {
ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err)
}

ctx.Status(http.StatusNoContent)
ctx.JSON(http.StatusOK, convert.ToTag(ctx.Repo.Repository, tag))
}

// CreateTag create a new git tag in a repository
Expand All @@ -187,7 +172,7 @@ func CreateTag(ctx *context.APIContext) {
// "$ref": "#/definitions/CreateTagOption"
// responses:
// "200":
// "$ref": "#/responses/AnnotatedTag"
// "$ref": "#/responses/Tag"
// "404":
// "$ref": "#/responses/notFound"
// "409":
Expand Down Expand Up @@ -221,3 +206,57 @@ func CreateTag(ctx *context.APIContext) {
}
ctx.JSON(http.StatusCreated, convert.ToTag(ctx.Repo.Repository, tag))
}

// DeleteTag delete a specific tag of in a repository by name
func DeleteTag(ctx *context.APIContext) {
// swagger:operation DELETE /repos/{owner}/{repo}/tags/{tag} repository repoDeleteTag
// ---
// summary: Delete a repository's tag by name
// produces:
// - application/json
// parameters:
// - name: owner
// in: path
// description: owner of the repo
// type: string
// required: true
// - name: repo
// in: path
// description: name of the repo
// type: string
// required: true
// - name: tag
// in: path
// description: name of tag to delete
// type: string
// required: true
// responses:
// "204":
// "$ref": "#/responses/empty"
// "404":
// "$ref": "#/responses/notFound"
// "409":
// "$ref": "#/responses/conflict"
tagName := ctx.Params("*")

tag, err := models.GetRelease(ctx.Repo.Repository.ID, tagName)
if err != nil {
if models.IsErrReleaseNotExist(err) {
ctx.NotFound()
return
}
ctx.Error(http.StatusInternalServerError, "GetRelease", err)
return
}

if !tag.IsTag {
ctx.Error(http.StatusConflict, "IsTag", errors.New("a tag attached to a release cannot be deleted directly"))
return
}

if err = releaseservice.DeleteReleaseByID(tag.ID, ctx.User, true); err != nil {
ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err)
}

ctx.Status(http.StatusNoContent)
}
45 changes: 43 additions & 2 deletions templates/swagger/v1_json.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -3657,7 +3657,7 @@
"repository"
],
"summary": "Gets the tag object of an annotated tag (not lightweight tags)",
"operationId": "GetTag",
"operationId": "GetAnnotatedTag",
"parameters": [
{
"type": "string",
Expand Down Expand Up @@ -9117,7 +9117,7 @@
],
"responses": {
"200": {
"$ref": "#/responses/AnnotatedTag"
"$ref": "#/responses/Tag"
},
"404": {
"$ref": "#/responses/notFound"
Expand All @@ -9129,6 +9129,47 @@
}
},
"/repos/{owner}/{repo}/tags/{tag}": {
"get": {
"produces": [
"application/json"
],
"tags": [
"repository"
],
"summary": "Get the tag of a repository by tag name",
"operationId": "repoGetTag",
"parameters": [
{
"type": "string",
"description": "owner of the repo",
"name": "owner",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of the repo",
"name": "repo",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of tag",
"name": "tag",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"$ref": "#/responses/Tag"
},
"404": {
"$ref": "#/responses/notFound"
}
}
},
"delete": {
"produces": [
"application/json"
Expand Down