mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-26 12:27:06 +00:00 
			
		
		
		
	Add API to list tags (#5850)
* Add API to list tags * update dependency gitea sdk vendor * fix swagger generation * fix swagger * add tests * update code.gitea.io/git vendor
This commit is contained in:
		
							
								
								
									
										4
									
								
								Gopkg.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								Gopkg.lock
									
									
									
										generated
									
									
									
								
							| @@ -3,11 +3,11 @@ | |||||||
|  |  | ||||||
| [[projects]] | [[projects]] | ||||||
|   branch = "master" |   branch = "master" | ||||||
|   digest = "1:537ed734fb4869453583d9ce24d93bf68c88287082778efe55ae749970a1012a" |   digest = "1:0a001725d6e1b35faccf15cbc4f782b67a0d77f4bbf56e51a4b244f92e7c60ca" | ||||||
|   name = "code.gitea.io/git" |   name = "code.gitea.io/git" | ||||||
|   packages = ["."] |   packages = ["."] | ||||||
|   pruneopts = "NUT" |   pruneopts = "NUT" | ||||||
|   revision = "fbe468c7a634991285eaa1f93e73431e3edfc471" |   revision = "0aea7f12d36ed49bcac560b61301cff88e478e5c" | ||||||
|  |  | ||||||
| [[projects]] | [[projects]] | ||||||
|   branch = "master" |   branch = "master" | ||||||
|   | |||||||
							
								
								
									
										38
									
								
								integrations/api_repo_tags_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								integrations/api_repo_tags_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | // Copyright 2018 The Gitea Authors. All rights reserved. | ||||||
|  | // Use of this source code is governed by a MIT-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | package integrations | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"net/http" | ||||||
|  | 	"path" | ||||||
|  | 	"testing" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/gitea/models" | ||||||
|  | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	api "code.gitea.io/sdk/gitea" | ||||||
|  |  | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestAPIReposGetTags(t *testing.T) { | ||||||
|  | 	prepareTestEnv(t) | ||||||
|  | 	user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) | ||||||
|  | 	// Login as User2. | ||||||
|  | 	session := loginUser(t, user.Name) | ||||||
|  | 	token := getTokenForLoggedInUser(t, session) | ||||||
|  |  | ||||||
|  | 	req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/tags?token="+token, user.Name) | ||||||
|  | 	resp := session.MakeRequest(t, req, http.StatusOK) | ||||||
|  |  | ||||||
|  | 	var tags []*api.Tag | ||||||
|  | 	DecodeJSON(t, resp, &tags) | ||||||
|  |  | ||||||
|  | 	assert.EqualValues(t, 1, len(tags)) | ||||||
|  | 	assert.Equal(t, "v1.1", tags[0].Name) | ||||||
|  | 	assert.Equal(t, "65f1bf27bc3bf70f64657658635e66094edbcb4d", tags[0].Commit.SHA) | ||||||
|  | 	assert.Equal(t, path.Join(setting.AppSubURL, "/user2/repo1/commit/65f1bf27bc3bf70f64657658635e66094edbcb4d"), tags[0].Commit.URL) | ||||||
|  | 	assert.Equal(t, path.Join(setting.AppSubURL, "/user2/repo1/archive/v1.1.zip"), tags[0].ZipballURL) | ||||||
|  | 	assert.Equal(t, path.Join(setting.AppSubURL, "/user2/repo1/archive/v1.1.tar.gz"), tags[0].TarballURL) | ||||||
|  | } | ||||||
							
								
								
									
										24
									
								
								models/repo_tag.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								models/repo_tag.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | // Copyright 2019 The Gitea Authors. All rights reserved. | ||||||
|  | // Use of this source code is governed by a MIT-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | package models | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"code.gitea.io/git" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // GetTagsByPath returns repo tags by it's path | ||||||
|  | func GetTagsByPath(path string) ([]*git.Tag, error) { | ||||||
|  | 	gitRepo, err := git.OpenRepository(path) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return gitRepo.GetTagInfos() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetTags return repo's tags | ||||||
|  | func (repo *Repository) GetTags() ([]*git.Tag, error) { | ||||||
|  | 	return GetTagsByPath(repo.RepoPath()) | ||||||
|  | } | ||||||
| @@ -513,6 +513,9 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||||
| 					m.Get("", repo.ListBranches) | 					m.Get("", repo.ListBranches) | ||||||
| 					m.Get("/*", context.RepoRefByType(context.RepoRefBranch), repo.GetBranch) | 					m.Get("/*", context.RepoRefByType(context.RepoRefBranch), repo.GetBranch) | ||||||
| 				}, reqRepoReader(models.UnitTypeCode)) | 				}, reqRepoReader(models.UnitTypeCode)) | ||||||
|  | 				m.Group("/tags", func() { | ||||||
|  | 					m.Get("", repo.ListTags) | ||||||
|  | 				}, reqRepoReader(models.UnitTypeCode)) | ||||||
| 				m.Group("/keys", func() { | 				m.Group("/keys", func() { | ||||||
| 					m.Combo("").Get(repo.ListDeployKeys). | 					m.Combo("").Get(repo.ListDeployKeys). | ||||||
| 						Post(bind(api.CreateKeyOption{}), repo.CreateDeployKey) | 						Post(bind(api.CreateKeyOption{}), repo.CreateDeployKey) | ||||||
|   | |||||||
| @@ -34,6 +34,22 @@ func ToBranch(repo *models.Repository, b *models.Branch, c *git.Commit) *api.Bra | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // ToTag convert a tag to an api.Tag | ||||||
|  | func ToTag(repo *models.Repository, t *git.Tag) *api.Tag { | ||||||
|  | 	return &api.Tag{ | ||||||
|  | 		Name: t.Name, | ||||||
|  | 		Commit: struct { | ||||||
|  | 			SHA string `json:"sha"` | ||||||
|  | 			URL string `json:"url"` | ||||||
|  | 		}{ | ||||||
|  | 			SHA: t.ID.String(), | ||||||
|  | 			URL: util.URLJoin(repo.Link(), "commit", t.ID.String()), | ||||||
|  | 		}, | ||||||
|  | 		ZipballURL: util.URLJoin(repo.Link(), "archive", t.Name+".zip"), | ||||||
|  | 		TarballURL: util.URLJoin(repo.Link(), "archive", t.Name+".tar.gz"), | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| // ToCommit convert a commit to api.PayloadCommit | // ToCommit convert a commit to api.PayloadCommit | ||||||
| func ToCommit(repo *models.Repository, c *git.Commit) *api.PayloadCommit { | func ToCommit(repo *models.Repository, c *git.Commit) *api.PayloadCommit { | ||||||
| 	authorUsername := "" | 	authorUsername := "" | ||||||
|   | |||||||
							
								
								
									
										47
									
								
								routers/api/v1/repo/tag.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								routers/api/v1/repo/tag.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | |||||||
|  | // Copyright 2019 The Gitea Authors. All rights reserved. | ||||||
|  | // Use of this source code is governed by a MIT-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | package repo | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"code.gitea.io/gitea/modules/context" | ||||||
|  | 	"code.gitea.io/gitea/routers/api/v1/convert" | ||||||
|  |  | ||||||
|  | 	api "code.gitea.io/sdk/gitea" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // ListTags list all the tags of a repository | ||||||
|  | func ListTags(ctx *context.APIContext) { | ||||||
|  | 	// swagger:operation GET /repos/{owner}/{repo}/tags repository repoListTags | ||||||
|  | 	// --- | ||||||
|  | 	// summary: List a repository's tags | ||||||
|  | 	// 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 | ||||||
|  | 	// responses: | ||||||
|  | 	//   "200": | ||||||
|  | 	//     "$ref": "#/responses/TagList" | ||||||
|  | 	tags, err := ctx.Repo.Repository.GetTags() | ||||||
|  | 	if err != nil { | ||||||
|  | 		ctx.Error(500, "GetTags", err) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	apiTags := make([]*api.Tag, len(tags)) | ||||||
|  | 	for i := range tags { | ||||||
|  | 		apiTags[i] = convert.ToTag(ctx.Repo.Repository, tags[i]) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	ctx.JSON(200, &apiTags) | ||||||
|  | } | ||||||
| @@ -36,6 +36,13 @@ type swaggerResponseBranchList struct { | |||||||
| 	Body []api.Branch `json:"body"` | 	Body []api.Branch `json:"body"` | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // TagList | ||||||
|  | // swagger:response TagList | ||||||
|  | type swaggerReponseTagList struct { | ||||||
|  | 	// in:body | ||||||
|  | 	Body []api.Tag `json:"body"` | ||||||
|  | } | ||||||
|  |  | ||||||
| // Reference | // Reference | ||||||
| // swagger:response Reference | // swagger:response Reference | ||||||
| type swaggerResponseReference struct { | type swaggerResponseReference struct { | ||||||
|   | |||||||
| @@ -4681,6 +4681,39 @@ | |||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "/repos/{owner}/{repo}/tags": { | ||||||
|  |       "get": { | ||||||
|  |         "produces": [ | ||||||
|  |           "application/json" | ||||||
|  |         ], | ||||||
|  |         "tags": [ | ||||||
|  |           "repository" | ||||||
|  |         ], | ||||||
|  |         "summary": "List a repository's tags", | ||||||
|  |         "operationId": "repoListTags", | ||||||
|  |         "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 | ||||||
|  |           } | ||||||
|  |         ], | ||||||
|  |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "$ref": "#/responses/TagList" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "/repos/{owner}/{repo}/times": { |     "/repos/{owner}/{repo}/times": { | ||||||
|       "get": { |       "get": { | ||||||
|         "produces": [ |         "produces": [ | ||||||
| @@ -8419,6 +8452,39 @@ | |||||||
|       "type": "string", |       "type": "string", | ||||||
|       "x-go-package": "code.gitea.io/gitea/vendor/code.gitea.io/sdk/gitea" |       "x-go-package": "code.gitea.io/gitea/vendor/code.gitea.io/sdk/gitea" | ||||||
|     }, |     }, | ||||||
|  |     "Tag": { | ||||||
|  |       "description": "Tag represents a repository tag", | ||||||
|  |       "type": "object", | ||||||
|  |       "properties": { | ||||||
|  |         "commit": { | ||||||
|  |           "type": "object", | ||||||
|  |           "properties": { | ||||||
|  |             "sha": { | ||||||
|  |               "type": "string", | ||||||
|  |               "x-go-name": "SHA" | ||||||
|  |             }, | ||||||
|  |             "url": { | ||||||
|  |               "type": "string", | ||||||
|  |               "x-go-name": "URL" | ||||||
|  |             } | ||||||
|  |           }, | ||||||
|  |           "x-go-name": "Commit" | ||||||
|  |         }, | ||||||
|  |         "name": { | ||||||
|  |           "type": "string", | ||||||
|  |           "x-go-name": "Name" | ||||||
|  |         }, | ||||||
|  |         "tarball_url": { | ||||||
|  |           "type": "string", | ||||||
|  |           "x-go-name": "TarballURL" | ||||||
|  |         }, | ||||||
|  |         "zipball_url": { | ||||||
|  |           "type": "string", | ||||||
|  |           "x-go-name": "ZipballURL" | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "x-go-package": "code.gitea.io/gitea/vendor/code.gitea.io/sdk/gitea" | ||||||
|  |     }, | ||||||
|     "Team": { |     "Team": { | ||||||
|       "description": "Team represents a team in an organization", |       "description": "Team represents a team in an organization", | ||||||
|       "type": "object", |       "type": "object", | ||||||
| @@ -8898,6 +8964,15 @@ | |||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "TagList": { | ||||||
|  |       "description": "TagList", | ||||||
|  |       "schema": { | ||||||
|  |         "type": "array", | ||||||
|  |         "items": { | ||||||
|  |           "$ref": "#/definitions/Tag" | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "Team": { |     "Team": { | ||||||
|       "description": "Team", |       "description": "Team", | ||||||
|       "schema": { |       "schema": { | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								vendor/code.gitea.io/git/repo_tag.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								vendor/code.gitea.io/git/repo_tag.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -103,26 +103,18 @@ func (repo *Repository) GetTagInfos() ([]*Tag, error) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	tagNames := strings.Split(stdout, "\n") | 	tagNames := strings.Split(stdout, "\n") | ||||||
| 	var tags []*Tag | 	var tags = make([]*Tag, 0, len(tagNames)) | ||||||
| 	for _, tagName := range tagNames { | 	for _, tagName := range tagNames { | ||||||
| 		tagName = strings.TrimSpace(tagName) | 		tagName = strings.TrimSpace(tagName) | ||||||
| 		if len(tagName) == 0 { | 		if len(tagName) == 0 { | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 		commitID, err := NewCommand("rev-parse", tagName).RunInDir(repo.Path) |  | ||||||
|  | 		tag, err := repo.GetTag(tagName) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 		commit, err := repo.GetCommit(commitID) | 		tags = append(tags, tag) | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		tags = append(tags, &Tag{ |  | ||||||
| 			Name:    tagName, |  | ||||||
| 			Message: commit.Message(), |  | ||||||
| 			Object:  commit.ID, |  | ||||||
| 			Tagger:  commit.Author, |  | ||||||
| 		}) |  | ||||||
| 	} | 	} | ||||||
| 	sortTagsByTime(tags) | 	sortTagsByTime(tags) | ||||||
| 	return tags, nil | 	return tags, nil | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Lunny Xiao
					Lunny Xiao