[API] Add repoGetTag (#16166)
* GetTag -> GetAnnotatedTag * API: Add repoGetTag * fix swagger docs * support "/" as tag name char Co-authored-by: techknowlogick <techknowlogick@gitea.io>
This commit is contained in:
		
							parent
							
								
									08f4b3f312
								
							
						
					
					
						commit
						eb324a9402
					
				
					 4 changed files with 132 additions and 37 deletions
				
			
		|  | @ -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.zip", tags[0].ZipballURL) | ||||||
| 	assert.Equal(t, setting.AppURL+"user2/repo1/archive/v1.1.tar.gz", tags[0].TarballURL) | 	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) | 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||||
| 	DecodeJSON(t, resp, &tags) | 	DecodeJSON(t, resp, &tags) | ||||||
| 	assert.Len(t, tags, 2) | 	assert.Len(t, tags, 2) | ||||||
|  | @ -51,6 +51,20 @@ func TestAPIRepoTags(t *testing.T) { | ||||||
| 			assert.EqualValues(t, newTag.Commit.SHA, tag.Commit.SHA) | 			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) | ||||||
|  | 	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 { | func createNewTagUsingAPI(t *testing.T, session *TestSession, token string, ownerName, repoName, name, target, msg string) *api.Tag { | ||||||
|  |  | ||||||
|  | @ -779,8 +779,9 @@ func Routes() *web.Route { | ||||||
| 				}, reqToken(), reqAdmin()) | 				}, reqToken(), reqAdmin()) | ||||||
| 				m.Group("/tags", func() { | 				m.Group("/tags", func() { | ||||||
| 					m.Get("", repo.ListTags) | 					m.Get("", repo.ListTags) | ||||||
|  | 					m.Get("/*", repo.GetTag) | ||||||
| 					m.Post("", reqRepoWriter(models.UnitTypeCode), bind(api.CreateTagOption{}), repo.CreateTag) | 					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)) | 				}, reqRepoReader(models.UnitTypeCode), context.ReferencesGitRepo(true)) | ||||||
| 				m.Group("/keys", func() { | 				m.Group("/keys", func() { | ||||||
| 					m.Combo("").Get(repo.ListDeployKeys). | 					m.Combo("").Get(repo.ListDeployKeys). | ||||||
|  | @ -945,7 +946,7 @@ func Routes() *web.Route { | ||||||
| 					m.Get("/refs/*", repo.GetGitRefs) | 					m.Get("/refs/*", repo.GetGitRefs) | ||||||
| 					m.Get("/trees/{sha}", context.RepoRefForAPI, repo.GetTree) | 					m.Get("/trees/{sha}", context.RepoRefForAPI, repo.GetTree) | ||||||
| 					m.Get("/blobs/{sha}", context.RepoRefForAPI, repo.GetBlob) | 					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)) | 				}, reqRepoReader(models.UnitTypeCode)) | ||||||
| 				m.Group("/contents", func() { | 				m.Group("/contents", func() { | ||||||
| 					m.Get("", repo.GetContentsList) | 					m.Get("", repo.GetContentsList) | ||||||
|  |  | ||||||
|  | @ -64,9 +64,9 @@ func ListTags(ctx *context.APIContext) { | ||||||
| 	ctx.JSON(http.StatusOK, &apiTags) | 	ctx.JSON(http.StatusOK, &apiTags) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetTag get the tag of a repository.
 | // GetAnnotatedTag get the tag of a repository.
 | ||||||
| func GetTag(ctx *context.APIContext) { | func GetAnnotatedTag(ctx *context.APIContext) { | ||||||
| 	// swagger:operation GET /repos/{owner}/{repo}/git/tags/{sha} repository GetTag
 | 	// swagger:operation GET /repos/{owner}/{repo}/git/tags/{sha} repository GetAnnotatedTag
 | ||||||
| 	// ---
 | 	// ---
 | ||||||
| 	// summary: Gets the tag object of an annotated tag (not lightweight tags)
 | 	// summary: Gets the tag object of an annotated tag (not lightweight tags)
 | ||||||
| 	// produces:
 | 	// produces:
 | ||||||
|  | @ -100,21 +100,21 @@ func GetTag(ctx *context.APIContext) { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if tag, err := ctx.Repo.GitRepo.GetAnnotatedTag(sha); err != nil { | 	if tag, err := ctx.Repo.GitRepo.GetAnnotatedTag(sha); err != nil { | ||||||
| 		ctx.Error(http.StatusBadRequest, "GetTag", err) | 		ctx.Error(http.StatusBadRequest, "GetAnnotatedTag", err) | ||||||
| 	} else { | 	} else { | ||||||
| 		commit, err := tag.Commit() | 		commit, err := tag.Commit() | ||||||
| 		if err != nil { | 		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)) | 		ctx.JSON(http.StatusOK, convert.ToAnnotatedTag(ctx.Repo.Repository, tag, commit)) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // DeleteTag delete a specific tag of in a repository by name
 | // GetTag get the tag of a repository
 | ||||||
| func DeleteTag(ctx *context.APIContext) { | func GetTag(ctx *context.APIContext) { | ||||||
| 	// swagger:operation DELETE /repos/{owner}/{repo}/tags/{tag} repository repoDeleteTag
 | 	// 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:
 | 	// produces:
 | ||||||
| 	// - application/json
 | 	// - application/json
 | ||||||
| 	// parameters:
 | 	// parameters:
 | ||||||
|  | @ -130,37 +130,22 @@ func DeleteTag(ctx *context.APIContext) { | ||||||
| 	//   required: true
 | 	//   required: true
 | ||||||
| 	// - name: tag
 | 	// - name: tag
 | ||||||
| 	//   in: path
 | 	//   in: path
 | ||||||
| 	//   description: name of tag to delete
 | 	//   description: name of tag
 | ||||||
| 	//   type: string
 | 	//   type: string
 | ||||||
| 	//   required: true
 | 	//   required: true
 | ||||||
| 	// responses:
 | 	// responses:
 | ||||||
| 	//   "204":
 | 	//   "200":
 | ||||||
| 	//     "$ref": "#/responses/empty"
 | 	//     "$ref": "#/responses/Tag"
 | ||||||
| 	//   "404":
 | 	//   "404":
 | ||||||
| 	//     "$ref": "#/responses/notFound"
 | 	//     "$ref": "#/responses/notFound"
 | ||||||
| 	//   "409":
 | 	tagName := ctx.Params("*") | ||||||
| 	//     "$ref": "#/responses/conflict"
 |  | ||||||
| 
 | 
 | ||||||
| 	tag, err := models.GetRelease(ctx.Repo.Repository.ID, ctx.Params("tag")) | 	tag, err := ctx.Repo.GitRepo.GetTag(tagName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if models.IsErrReleaseNotExist(err) { | 		ctx.NotFound(tagName) | ||||||
| 			ctx.NotFound() |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		ctx.Error(http.StatusInternalServerError, "GetRelease", err) |  | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 	ctx.JSON(http.StatusOK, convert.ToTag(ctx.Repo.Repository, tag)) | ||||||
| 	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) |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // CreateTag create a new git tag in a repository
 | // CreateTag create a new git tag in a repository
 | ||||||
|  | @ -187,7 +172,7 @@ func CreateTag(ctx *context.APIContext) { | ||||||
| 	//     "$ref": "#/definitions/CreateTagOption"
 | 	//     "$ref": "#/definitions/CreateTagOption"
 | ||||||
| 	// responses:
 | 	// responses:
 | ||||||
| 	//   "200":
 | 	//   "200":
 | ||||||
| 	//     "$ref": "#/responses/AnnotatedTag"
 | 	//     "$ref": "#/responses/Tag"
 | ||||||
| 	//   "404":
 | 	//   "404":
 | ||||||
| 	//     "$ref": "#/responses/notFound"
 | 	//     "$ref": "#/responses/notFound"
 | ||||||
| 	//   "409":
 | 	//   "409":
 | ||||||
|  | @ -221,3 +206,57 @@ func CreateTag(ctx *context.APIContext) { | ||||||
| 	} | 	} | ||||||
| 	ctx.JSON(http.StatusCreated, convert.ToTag(ctx.Repo.Repository, tag)) | 	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) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -3657,7 +3657,7 @@ | ||||||
|           "repository" |           "repository" | ||||||
|         ], |         ], | ||||||
|         "summary": "Gets the tag object of an annotated tag (not lightweight tags)", |         "summary": "Gets the tag object of an annotated tag (not lightweight tags)", | ||||||
|         "operationId": "GetTag", |         "operationId": "GetAnnotatedTag", | ||||||
|         "parameters": [ |         "parameters": [ | ||||||
|           { |           { | ||||||
|             "type": "string", |             "type": "string", | ||||||
|  | @ -9117,7 +9117,7 @@ | ||||||
|         ], |         ], | ||||||
|         "responses": { |         "responses": { | ||||||
|           "200": { |           "200": { | ||||||
|             "$ref": "#/responses/AnnotatedTag" |             "$ref": "#/responses/Tag" | ||||||
|           }, |           }, | ||||||
|           "404": { |           "404": { | ||||||
|             "$ref": "#/responses/notFound" |             "$ref": "#/responses/notFound" | ||||||
|  | @ -9129,6 +9129,47 @@ | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "/repos/{owner}/{repo}/tags/{tag}": { |     "/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": { |       "delete": { | ||||||
|         "produces": [ |         "produces": [ | ||||||
|           "application/json" |           "application/json" | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue