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:
parent
dee0475f01
commit
f5cc003900
2 changed files with 109 additions and 16 deletions
|
@ -5,6 +5,8 @@
|
||||||
package gitea
|
package gitea
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,6 +20,24 @@ type Tag struct {
|
||||||
TarballURL string `json:"tarball_url"`
|
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
|
// ListRepoTagsOptions options for listing a repository's tags
|
||||||
type ListRepoTagsOptions struct {
|
type ListRepoTagsOptions struct {
|
||||||
ListOptions
|
ListOptions
|
||||||
|
@ -34,8 +54,69 @@ func (c *Client) ListRepoTags(user, repo string, opt ListRepoTagsOptions) ([]*Ta
|
||||||
return tags, resp, err
|
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
|
// 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 {
|
if err := escapeValidatePathSegments(&user, &repo, &tag); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
package gitea
|
package gitea
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -18,30 +19,41 @@ func TestTags(t *testing.T) {
|
||||||
repo, _ := createTestRepo(t, "TestTags", c)
|
repo, _ := createTestRepo(t, "TestTags", c)
|
||||||
|
|
||||||
// Create Tags
|
// 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{})
|
tags, _, err := c.ListRepoTags(repo.Owner.UserName, repo.Name, ListRepoTagsOptions{})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, tags, 1)
|
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
|
// 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.NoError(t, err)
|
||||||
assert.EqualValues(t, 204, resp.StatusCode)
|
assert.EqualValues(t, 204, resp.StatusCode)
|
||||||
tags, _, err = c.ListRepoTags(repo.Owner.UserName, repo.Name, ListRepoTagsOptions{})
|
tags, _, err = c.ListRepoTags(repo.Owner.UserName, repo.Name, ListRepoTagsOptions{})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, tags, 0)
|
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)
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue