Add GetTag, GetAnnotatedTag & CreateTag (#533)

Add func to manage git tags via api

close #528

Co-authored-by: Andrew Thornton <art27@cantab.net>
Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/533
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: 6543 <6543@obermui.de>
Co-committed-by: 6543 <6543@obermui.de>
This commit is contained in:
6543 2021-08-13 20:27:52 +08:00
parent dee0475f01
commit f5cc003900
2 changed files with 109 additions and 16 deletions

View file

@ -5,6 +5,8 @@
package gitea
import (
"bytes"
"encoding/json"
"fmt"
)
@ -18,6 +20,24 @@ type Tag struct {
TarballURL string `json:"tarball_url"`
}
// AnnotatedTag represents an annotated tag
type AnnotatedTag struct {
Tag string `json:"tag"`
SHA string `json:"sha"`
URL string `json:"url"`
Message string `json:"message"`
Tagger *CommitUser `json:"tagger"`
Object *AnnotatedTagObject `json:"object"`
Verification *PayloadCommitVerification `json:"verification"`
}
// AnnotatedTagObject contains meta information of the tag object
type AnnotatedTagObject struct {
Type string `json:"type"`
URL string `json:"url"`
SHA string `json:"sha"`
}
// ListRepoTagsOptions options for listing a repository's tags
type ListRepoTagsOptions struct {
ListOptions
@ -34,8 +54,69 @@ func (c *Client) ListRepoTags(user, repo string, opt ListRepoTagsOptions) ([]*Ta
return tags, resp, err
}
// GetTag get the tag of a repository
func (c *Client) GetTag(user, repo, tag string) (*Tag, *Response, error) {
if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
return nil, nil, err
}
if err := escapeValidatePathSegments(&user, &repo, &tag); err != nil {
return nil, nil, err
}
t := new(Tag)
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/tags/%s", user, repo, tag), nil, nil, &t)
return t, resp, err
}
// GetAnnotatedTag get the tag object of an annotated tag (not lightweight tags) of a repository
func (c *Client) GetAnnotatedTag(user, repo, sha string) (*AnnotatedTag, *Response, error) {
if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
return nil, nil, err
}
if err := escapeValidatePathSegments(&user, &repo, &sha); err != nil {
return nil, nil, err
}
t := new(AnnotatedTag)
resp, err := c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/git/tags/%s", user, repo, sha), nil, nil, &t)
return t, resp, err
}
// CreateTagOption options when creating a tag
type CreateTagOption struct {
TagName string `json:"tag_name"`
Message string `json:"message"`
Target string `json:"target"`
}
// Validate validates CreateTagOption
func (opt CreateTagOption) Validate() error {
if len(opt.TagName) == 0 {
return fmt.Errorf("TagName is required")
}
return nil
}
// CreateTag create a new git tag in a repository
func (c *Client) CreateTag(user, repo string, opt CreateTagOption) (*Tag, *Response, error) {
if err := c.checkServerVersionGreaterThanOrEqual(version1_15_0); err != nil {
return nil, nil, err
}
if err := escapeValidatePathSegments(&user, &repo); err != nil {
return nil, nil, err
}
if err := opt.Validate(); err != nil {
return nil, nil, err
}
body, err := json.Marshal(opt)
if err != nil {
return nil, nil, err
}
t := new(Tag)
resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/tags", user, repo), jsonHeader, bytes.NewReader(body), &t)
return t, resp, err
}
// DeleteTag deletes a tag from a repository, if no release refers to it
func (c *Client) DeleteTag(user, repo string, tag string) (*Response, error) {
func (c *Client) DeleteTag(user, repo, tag string) (*Response, error) {
if err := escapeValidatePathSegments(&user, &repo, &tag); err != nil {
return nil, err
}

View file

@ -5,6 +5,7 @@
package gitea
import (
"fmt"
"log"
"testing"
@ -18,30 +19,41 @@ func TestTags(t *testing.T) {
repo, _ := createTestRepo(t, "TestTags", c)
// Create Tags
createTestTag(t, c, repo, "tag1")
cTagMSG := "A tag message.\n\n:)"
cTag, resp, err := c.CreateTag(repo.Owner.UserName, repo.Name, CreateTagOption{
TagName: "tag1",
Message: cTagMSG,
Target: "master",
})
assert.NoError(t, err)
assert.EqualValues(t, 201, resp.StatusCode)
assert.EqualValues(t, cTagMSG, cTag.Message)
assert.EqualValues(t, fmt.Sprintf("%s/test01/TestTags/archive/tag1.zip", c.url), cTag.ZipballURL)
tags, _, err := c.ListRepoTags(repo.Owner.UserName, repo.Name, ListRepoTagsOptions{})
assert.NoError(t, err)
assert.Len(t, tags, 1)
assert.EqualValues(t, cTag, tags[0])
// get tag
gTag, _, err := c.GetTag(repo.Owner.UserName, repo.Name, cTag.Name)
assert.NoError(t, err)
assert.EqualValues(t, cTag, gTag)
aTag, _, err := c.GetAnnotatedTag(repo.Owner.UserName, repo.Name, cTag.ID)
assert.NoError(t, err)
assert.EqualValues(t, cTag.Name, aTag.Tag)
assert.EqualValues(t, cTag.ID, aTag.SHA)
assert.EqualValues(t, fmt.Sprintf("%s/api/v1/repos/test01/TestTags/git/tags/%s", c.url, cTag.ID), aTag.URL)
assert.EqualValues(t, cTag.Message+"\n", aTag.Message)
assert.EqualValues(t, false, aTag.Verification.Verified)
assert.EqualValues(t, "commit", aTag.Object.Type)
// DeleteReleaseTag
resp, err := c.DeleteTag(repo.Owner.UserName, repo.Name, "tag1")
resp, err = c.DeleteTag(repo.Owner.UserName, repo.Name, "tag1")
assert.NoError(t, err)
assert.EqualValues(t, 204, resp.StatusCode)
tags, _, err = c.ListRepoTags(repo.Owner.UserName, repo.Name, ListRepoTagsOptions{})
assert.NoError(t, err)
assert.Len(t, tags, 0)
}
// createTestTag use create release api since there exist no api to create tag only
// https://github.com/go-gitea/gitea/issues/14669
func createTestTag(t *testing.T, c *Client, repo *Repository, name string) {
rel, _, err := c.CreateRelease(repo.Owner.UserName, repo.Name, CreateReleaseOption{
TagName: name,
Target: "master",
Title: "TMP Release",
})
assert.NoError(t, err)
_, err = c.DeleteRelease(repo.Owner.UserName, repo.Name, rel.ID)
assert.NoError(t, err)
}