Unverified Commit 9996a58e authored by Sander van Harmelen's avatar Sander van Harmelen Committed by GitHub

Merge pull request #551 from juranki/releases-pr

Add support for Releases and Release links
parents 321eba65 fb691d7b
......@@ -334,6 +334,8 @@ type Client struct {
Projects *ProjectsService
ProtectedBranches *ProtectedBranchesService
ProtectedTags *ProtectedTagsService
ReleaseLinks *ReleaseLinksService
Releases *ReleasesService
Repositories *RepositoriesService
RepositoryFiles *RepositoryFilesService
Runners *RunnersService
......@@ -478,6 +480,8 @@ func newClient(httpClient *http.Client) *Client {
c.Projects = &ProjectsService{client: c}
c.ProtectedBranches = &ProtectedBranchesService{client: c}
c.ProtectedTags = &ProtectedTagsService{client: c}
c.ReleaseLinks = &ReleaseLinksService{client: c}
c.Releases = &ReleasesService{client: c}
c.Repositories = &RepositoriesService{client: c}
c.RepositoryFiles = &RepositoryFilesService{client: c}
c.Runners = &RunnersService{client: c}
......
package gitlab
import (
"fmt"
"net/url"
)
// ReleaseLinksService handles communication with the release link methods
// of the GitLab API.
//
// GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html
type ReleaseLinksService struct {
client *Client
}
// ReleaseLink represents a release link.
//
// GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html
type ReleaseLink struct {
ID int `json:"id"`
Name string `json:"name"`
URL string `json:"url"`
External bool `json:"external"`
}
// ListReleaseLinksOptions represents ListReleaseLinks() options.
//
// GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html#get-links
type ListReleaseLinksOptions ListOptions
// ListReleaseLinks gets assets as links from a Release.
//
// GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html#get-links
func (s *ReleaseLinksService) ListReleaseLinks(pid interface{}, tagName string, opt *ListReleaseLinksOptions, options ...OptionFunc) ([]*ReleaseLink, *Response, error) {
project, err := parseID(pid)
if err != nil {
return nil, nil, err
}
u := fmt.Sprintf("projects/%s/releases/%s/assets/links", url.QueryEscape(project), tagName)
req, err := s.client.NewRequest("GET", u, opt, options)
if err != nil {
return nil, nil, err
}
rls := make([]*ReleaseLink, 0)
resp, err := s.client.Do(req, &rls)
if err != nil {
return nil, resp, err
}
return rls, resp, err
}
// GetReleaseLink returns a link from release assets.
//
// GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html#get-a-link
func (s *ReleaseLinksService) GetReleaseLink(pid interface{}, tagName string, link int, options ...OptionFunc) (*ReleaseLink, *Response, error) {
project, err := parseID(pid)
if err != nil {
return nil, nil, err
}
u := fmt.Sprintf("projects/%s/releases/%s/assets/links/%d",
url.QueryEscape(project),
tagName,
link)
req, err := s.client.NewRequest("GET", u, nil, options)
if err != nil {
return nil, nil, err
}
rl := new(ReleaseLink)
resp, err := s.client.Do(req, rl)
if err != nil {
return nil, resp, err
}
return rl, resp, err
}
// CreateReleaseLinkOptions represents CreateReleaseLink() options.
//
// GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html#create-a-link
type CreateReleaseLinkOptions struct {
Name *string `url:"name" json:"name"`
URL *string `url:"url" json:"url"`
}
// CreateReleaseLink creates a link.
//
// GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html#create-a-link
func (s *ReleaseLinksService) CreateReleaseLink(pid interface{}, tagName string, opt *CreateReleaseLinkOptions, options ...OptionFunc) (*ReleaseLink, *Response, error) {
project, err := parseID(pid)
if err != nil {
return nil, nil, err
}
u := fmt.Sprintf("projects/%s/releases/%s/assets/links", url.QueryEscape(project), tagName)
req, err := s.client.NewRequest("POST", u, opt, options)
if err != nil {
return nil, nil, err
}
rl := new(ReleaseLink)
resp, err := s.client.Do(req, rl)
if err != nil {
return nil, resp, err
}
return rl, resp, err
}
// UpdateReleaseLinkOptions represents UpdateReleaseLink() options.
//
// You have to specify at least one of Name of URL.
//
// GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html#update-a-link
type UpdateReleaseLinkOptions struct {
Name *string `url:"name,omitempty" json:"name,omitempty"`
URL *string `url:"url,omitempty" json:"url,omitempty"`
}
// UpdateReleaseLink updates an asset link.
//
// GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html#update-a-link
func (s *ReleaseLinksService) UpdateReleaseLink(pid interface{}, tagName string, link int, opt *UpdateReleaseLinkOptions, options ...OptionFunc) (*ReleaseLink, *Response, error) {
project, err := parseID(pid)
if err != nil {
return nil, nil, err
}
u := fmt.Sprintf("projects/%s/releases/%s/assets/links/%d",
url.QueryEscape(project),
tagName,
link)
req, err := s.client.NewRequest("PUT", u, opt, options)
if err != nil {
return nil, nil, err
}
rl := new(ReleaseLink)
resp, err := s.client.Do(req, rl)
if err != nil {
return nil, resp, err
}
return rl, resp, err
}
// DeleteReleaseLink deletes a link from release.
//
// GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html#delete-a-link
func (s *ReleaseLinksService) DeleteReleaseLink(pid interface{}, tagName string, link int, options ...OptionFunc) (*ReleaseLink, *Response, error) {
project, err := parseID(pid)
if err != nil {
return nil, nil, err
}
u := fmt.Sprintf("projects/%s/releases/%s/assets/links/%d",
url.QueryEscape(project),
tagName,
link,
)
req, err := s.client.NewRequest("DELETE", u, nil, options)
if err != nil {
return nil, nil, err
}
rl := new(ReleaseLink)
resp, err := s.client.Do(req, rl)
if err != nil {
return nil, resp, err
}
return rl, resp, err
}
package gitlab
import (
"fmt"
"net/http"
"testing"
)
const exampleReleaseLinkList = `[
{
"id": 2,
"name": "awesome-v0.2.msi",
"url": "http://192.168.10.15:3000/msi",
"external": true
},
{
"id": 1,
"name": "awesome-v0.2.dmg",
"url": "http://192.168.10.15:3000",
"external": true
}
]`
func TestReleaseLinksService_ListReleaseLinks(t *testing.T) {
mux, server, client := setup()
defer teardown(server)
mux.HandleFunc("/api/v4/projects/1/releases/v0.1/assets/links",
func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, exampleReleaseLinkList)
})
releaseLinks, _, err := client.ReleaseLinks.ListReleaseLinks(
1, "v0.1", &ListReleaseLinksOptions{},
)
if err != nil {
t.Error(err)
}
if len(releaseLinks) != 2 {
t.Error("expected 2 links")
}
if releaseLinks[0].Name != "awesome-v0.2.msi" {
t.Errorf("release link name, expected '%s', got '%s'", "awesome-v0.2.msi",
releaseLinks[0].Name)
}
}
const exampleReleaseLink = `{
"id":1,
"name":"awesome-v0.2.dmg",
"url":"http://192.168.10.15:3000",
"external":true
}`
func TestReleaseLinksService_CreateReleaseLink(t *testing.T) {
mux, server, client := setup()
defer teardown(server)
mux.HandleFunc("/api/v4/projects/1/releases/v0.1/assets/links",
func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
fmt.Fprint(w, exampleReleaseLink)
})
releaseLink, _, err := client.ReleaseLinks.CreateReleaseLink(
1, "v0.1",
&CreateReleaseLinkOptions{
Name: String("awesome-v0.2.dmg"),
URL: String("http://192.168.10.15:3000"),
})
if err != nil {
t.Error(err)
}
if releaseLink.Name != "awesome-v0.2.dmg" {
t.Errorf("release link name, expected '%s', got '%s'", "awesome-v0.2.dmg",
releaseLink.Name)
}
}
func TestReleaseLinksService_GetReleaseLink(t *testing.T) {
mux, server, client := setup()
defer teardown(server)
mux.HandleFunc("/api/v4/projects/1/releases/v0.1/assets/links/1",
func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, exampleReleaseLink)
})
releaseLink, _, err := client.ReleaseLinks.GetReleaseLink(1, "v0.1", 1)
if err != nil {
t.Error(err)
}
if releaseLink.Name != "awesome-v0.2.dmg" {
t.Errorf("release link name, expected '%s', got '%s'", "awesome-v0.2.dmg",
releaseLink.Name)
}
}
func TestReleaseLinksService_UpdateReleaseLink(t *testing.T) {
mux, server, client := setup()
defer teardown(server)
mux.HandleFunc("/api/v4/projects/1/releases/v0.1/assets/links/1",
func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
fmt.Fprint(w, exampleReleaseLink)
})
releaseLink, _, err := client.ReleaseLinks.UpdateReleaseLink(
1, "v0.1", 1,
&UpdateReleaseLinkOptions{
Name: String("awesome-v0.2.dmg"),
})
if err != nil {
t.Error(err)
}
if releaseLink.Name != "awesome-v0.2.dmg" {
t.Errorf("release link name, expected '%s', got '%s'", "awesome-v0.2.dmg",
releaseLink.Name)
}
}
func TestReleaseLinksService_DeleteReleaseLink(t *testing.T) {
mux, server, client := setup()
defer teardown(server)
mux.HandleFunc("/api/v4/projects/1/releases/v0.1/assets/links/1",
func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
fmt.Fprint(w, exampleReleaseLink)
})
releaseLink, _, err := client.ReleaseLinks.DeleteReleaseLink(1, "v0.1", 1)
if err != nil {
t.Error(err)
}
if releaseLink.Name != "awesome-v0.2.dmg" {
t.Errorf("release link name, expected '%s', got '%s'", "awesome-v0.2.dmg",
releaseLink.Name)
}
}
package gitlab
import (
"fmt"
"net/url"
"time"
)
// ReleasesService handles communication with the releases methods
// of the GitLab API.
//
// GitLab API docs: https://docs.gitlab.com/ce/api/releases/index.html
type ReleasesService struct {
client *Client
}
// Release represents a project release.
//
// GitLab API docs: https://docs.gitlab.com/ce/api/releases/index.html#list-releases
type Release struct {
TagName string `json:"tag_name"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
DescriptionHTML string `json:"description_html,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
Author struct {
ID int `json:"id"`
Name string `json:"name"`
Username string `json:"username"`
State string `json:"state"`
AvatarURL string `json:"avatar_url"`
WebURL string `json:"web_url"`
} `json:"author"`
Commit Commit `json:"commit"`
Assets struct {
Count int `json:"count"`
Sources []struct {
Format string `json:"format"`
URL string `json:"url"`
} `json:"sources"`
Links []ReleaseLink `json:"links"`
} `json:"assets"`
}
// ListReleasesOptions represents ListReleases() options.
//
// GitLab API docs: https://docs.gitlab.com/ce/api/releases/index.html#list-releases
type ListReleasesOptions ListOptions
// ListReleases gets a pagenated of releases accessible by the authenticated user.
//
// GitLab API docs: https://docs.gitlab.com/ce/api/releases/index.html#list-releases
func (s *ReleasesService) ListReleases(pid interface{}, opt *ListReleasesOptions, options ...OptionFunc) ([]*Release, *Response, error) {
project, err := parseID(pid)
if err != nil {
return nil, nil, err
}
u := fmt.Sprintf("projects/%s/releases", url.QueryEscape(project))
req, err := s.client.NewRequest("GET", u, opt, options)
if err != nil {
return nil, nil, err
}
r := make([]*Release, 0)
resp, err := s.client.Do(req, &r)
if err != nil {
return nil, resp, err
}
return r, resp, err
}
// GetRelease returns a single release, identified by a tag name.
//
// GitLab API docs:
// https://docs.gitlab.com/ce/api/releases/index.html#get-a-release-by-a-tag-name
func (s *ReleasesService) GetRelease(pid interface{}, tagName string, options ...OptionFunc) (*Release, *Response, error) {
project, err := parseID(pid)
if err != nil {
return nil, nil, err
}
u := fmt.Sprintf("projects/%s/releases/%s", url.QueryEscape(project), tagName)
req, err := s.client.NewRequest("GET", u, nil, options)
if err != nil {
return nil, nil, err
}
r := new(Release)
resp, err := s.client.Do(req, r)
if err != nil {
return nil, resp, err
}
return r, resp, err
}
// ReleaseAssets represents release assets in CreateRelease() options
//
// GitLab API docs:
// https://docs.gitlab.com/ce/api/releases/index.html#create-a-release
type ReleaseAssets struct {
Links []ReleaseAssetLink `url:"links" json:"links"`
}
// ReleaseAssetLink represents release asset link in CreateRelease() options
//
// GitLab API docs:
// https://docs.gitlab.com/ce/api/releases/index.html#create-a-release
type ReleaseAssetLink struct {
Name string `url:"name" json:"name"`
URL string `url:"url" json:"url"`
}
// CreateReleaseOptions represents CreateRelease() options.
//
// GitLab API docs:
// https://docs.gitlab.com/ce/api/releases/index.html#create-a-release
type CreateReleaseOptions struct {
Name *string `url:"name" json:"name"`
TagName *string `url:"tag_name" json:"tag_name"`
Description *string `url:"description" json:"description"`
Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
Assets *ReleaseAssets `url:"assets,omitempty" json:"assets,omitempty"`
}
// CreateRelease creates a release.
//
// GitLab API docs:
// https://docs.gitlab.com/ce/api/releases/index.html#create-a-release
func (s *ReleasesService) CreateRelease(pid interface{}, opts *CreateReleaseOptions, options ...OptionFunc) (*Release, *Response, error) {
project, err := parseID(pid)
if err != nil {
return nil, nil, err
}
u := fmt.Sprintf("projects/%s/releases", url.QueryEscape(project))
req, err := s.client.NewRequest("POST", u, opts, options)
if err != nil {
return nil, nil, err
}
r := new(Release)
resp, err := s.client.Do(req, r)
if err != nil {
return nil, resp, err
}
return r, resp, err
}
// UpdateReleaseOptions represents UpdateRelease() options.
//
// GitLab API docs:
// https://docs.gitlab.com/ce/api/releases/index.html#update-a-release
type UpdateReleaseOptions struct {
Name *string `url:"name" json:"name"`
Description *string `url:"description" json:"description"`
}
// UpdateRelease updates a release.
//
// GitLab API docs:
// https://docs.gitlab.com/ce/api/releases/index.html#update-a-release
func (s *ReleasesService) UpdateRelease(pid interface{}, tagName string, opts *UpdateReleaseOptions, options ...OptionFunc) (*Release, *Response, error) {
project, err := parseID(pid)
if err != nil {
return nil, nil, err
}
u := fmt.Sprintf("projects/%s/releases/%s", url.QueryEscape(project), tagName)
req, err := s.client.NewRequest("PUT", u, opts, options)
if err != nil {
return nil, nil, err
}
r := new(Release)
resp, err := s.client.Do(req, &r)
if err != nil {
return nil, resp, err
}
return r, resp, err
}
// DeleteRelease deletes a release.
//
// GitLab API docs:
// https://docs.gitlab.com/ce/api/releases/index.html#delete-a-release
func (s *ReleasesService) DeleteRelease(pid interface{}, tagName string, options ...OptionFunc) (*Release, *Response, error) {
project, err := parseID(pid)
if err != nil {
return nil, nil, err
}
u := fmt.Sprintf("projects/%s/releases/%s", url.QueryEscape(project), tagName)
req, err := s.client.NewRequest("DELETE", u, nil, options)
if err != nil {
return nil, nil, err
}
r := new(Release)
resp, err := s.client.Do(req, r)
if err != nil {
return nil, resp, err
}
return r, resp, err
}
package gitlab
import (
"fmt"
"io/ioutil"
"net/http"
"strings"
"testing"
)
const exampleReleaseListRsp = `[
{
"tag_name": "v0.2",
"description": "description",
"name": "Awesome app v0.2 beta",
"description_html": "html",
"created_at": "2019-01-03T01:56:19.539Z",
"author": {
"id": 1,
"name": "Administrator",
"username": "root",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar",
"web_url": "http://localhost:3000/root"
},
"commit": {
"id": "079e90101242458910cccd35eab0e211dfc359c0",
"short_id": "079e9010",
"title": "Update README.md",
"created_at": "2019-01-03T01:55:38.000Z",
"parent_ids": [
"f8d3d94cbd347e924aa7b715845e439d00e80ca4"
],
"message": "Update README.md",
"author_name": "Administrator",
"author_email": "admin@example.com",
"authored_date": "2019-01-03T01:55:38.000Z",
"committer_name": "Administrator",
"committer_email": "admin@example.com",
"committed_date": "2019-01-03T01:55:38.000Z"
},
"assets": {
"count": 4,
"sources": [
{
"format": "zip",
"url": "http://localhost:3000/archive/v0.2/awesome-app-v0.2.zip"
},
{
"format": "tar.gz",
"url": "http://localhost:3000/archive/v0.2/awesome-app-v0.2.tar.gz"
}
],
"links": [
{
"id": 2,
"name": "awesome-v0.2.msi",
"url": "http://192.168.10.15:3000/msi",
"external": true
},
{
"id": 1,
"name": "awesome-v0.2.dmg",
"url": "http://192.168.10.15:3000",
"external": true
}
]
}
},
{
"tag_name": "v0.1",
"description": "description",
"name": "Awesome app v0.1 alpha",
"description_html": "description_html",
"created_at": "2019-01-03T01:55:18.203Z",
"author": {
"id": 1,
"name": "Administrator",
"username": "root",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar",
"web_url": "http://localhost:3000/root"
},
"commit": {
"id": "f8d3d94cbd347e924aa7b715845e439d00e80ca4",
"short_id": "f8d3d94c",
"title": "Initial commit",
"created_at": "2019-01-03T01:53:28.000Z",
"parent_ids": [],
"message": "Initial commit",
"author_name": "Administrator",
"author_email": "admin@example.com",
"authored_date": "2019-01-03T01:53:28.000Z",
"committer_name": "Administrator",
"committer_email": "admin@example.com",
"committed_date": "2019-01-03T01:53:28.000Z"
},
"assets": {
"count": 2,
"sources": [
{
"format": "zip",
"url": "http://localhost:3000/archive/v0.1/awesome-app-v0.1.zip"
},
{
"format": "tar.gz",
"url": "http://localhost:3000/archive/v0.1/awesome-app-v0.1.tar.gz"
}
],
"links": []
}
}
]`
func TestReleasesService_ListReleases(t *testing.T) {
mux, server, client := setup()
defer teardown(server)
mux.HandleFunc("/api/v4/projects/1/releases",
func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, exampleReleaseListRsp)
})
opt := &ListReleasesOptions{}
releases, _, err := client.Releases.ListReleases(1, opt)
if err != nil {
t.Error(err)
}
if len(releases) != 2 {
t.Error("expected 2 releases")
}
}
const exampleReleaseRsp = `{
"tag_name": "v0.1",
"description": "description",
"name": "Awesome app v0.1 alpha",
"description_html": "description_html",
"created_at": "2019-01-03T01:55:18.203Z",
"author": {
"id": 1,
"name": "Administrator",
"username": "root",
"state": "active",
"avatar_url": "https://www.gravatar.com/avatar/",
"web_url": "http://localhost:3000/root"
},
"commit": {
"id": "f8d3d94cbd347e924aa7b715845e439d00e80ca4",
"short_id": "f8d3d94c",
"title": "Initial commit",
"created_at": "2019-01-03T01:53:28.000Z",
"parent_ids": [],
"message": "Initial commit",
"author_name": "Administrator",
"author_email": "admin@example.com",
"authored_date": "2019-01-03T01:53:28.000Z",
"committer_name": "Administrator",
"committer_email": "admin@example.com",
"committed_date": "2019-01-03T01:53:28.000Z"
},
"assets": {
"count": 2,
"sources": [
{
"format": "zip",
"url": "http://localhost:3000/archive/v0.1/awesome-app-v0.1.zip"
},
{
"format": "tar.gz",
"url": "http://localhost:3000/archive/v0.1/awesome-app-v0.1.tar.gz"
}
],
"links": []
}
}`
func TestReleasesService_GetRelease(t *testing.T) {
mux, server, client := setup()
defer teardown(server)
mux.HandleFunc("/api/v4/projects/1/releases/v0.1",
func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, exampleReleaseRsp)
})
release, _, err := client.Releases.GetRelease(1, "v0.1")
if err != nil {
t.Error(err)
}
if release.TagName != "v0.1" {
t.Errorf("expected tag v0.1, got %s", release.TagName)
}
}
func TestReleasesService_CreateRelease(t *testing.T) {
mux, server, client := setup()
defer teardown(server)
mux.HandleFunc("/api/v4/projects/1/releases",
func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
b, err := ioutil.ReadAll(r.Body)
if err != nil {
t.Fatalf("unable to read request body")
}
if !strings.Contains(string(b), "v0.1") {
t.Errorf("expected request body to contain v0.1, got %s",
string(b))
}
if strings.Contains(string(b), "assets") {
t.Errorf("expected request body not to have assets, got %s",
string(b))
}
fmt.Fprint(w, exampleReleaseRsp)
})
opts := &CreateReleaseOptions{
Name: String("name"),
TagName: String("v0.1"),
Description: String("Description"),
}
release, _, err := client.Releases.CreateRelease(1, opts)
if err != nil {
t.Error(err)
}
if release.TagName != "v0.1" {
t.Errorf("expected tag v0.1, got %s", release.TagName)
}
}
func TestReleasesService_CreateReleaseWithAsset(t *testing.T) {
mux, server, client := setup()
defer teardown(server)
mux.HandleFunc("/api/v4/projects/1/releases",
func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
b, err := ioutil.ReadAll(r.Body)
if err != nil {
t.Fatalf("unable to read request body")
}
if !strings.Contains(string(b), "v0.1") {
t.Errorf("expected request body to contain v0.1, got %s",
string(b))
}
if !strings.Contains(string(b), "assets") {
t.Errorf("expected request body to have assets, got %s",
string(b))
}
fmt.Println(string(b))
fmt.Fprint(w, exampleReleaseRsp)
})
opts := &CreateReleaseOptions{
Name: String("name"),
TagName: String("v0.1"),
Description: String("Description"),
Assets: &ReleaseAssets{
Links: []ReleaseAssetLink{
{"sldkf", "sldkfj"},
},
},
}
release, _, err := client.Releases.CreateRelease(1, opts)
if err != nil {
t.Error(err)
}
if release.TagName != "v0.1" {
t.Errorf("expected tag v0.1, got %s", release.TagName)
}
}
func TestReleasesService_UpdateRelease(t *testing.T) {
mux, server, client := setup()
defer teardown(server)
mux.HandleFunc("/api/v4/projects/1/releases/v0.1",
func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
fmt.Fprint(w, exampleReleaseRsp)
})
opts := &UpdateReleaseOptions{
Name: String("name"),
Description: String("Description"),
}
release, _, err := client.Releases.UpdateRelease(1, "v0.1", opts)
if err != nil {
t.Error(err)
}
if release.TagName != "v0.1" {
t.Errorf("expected tag v0.1, got %s", release.TagName)
}
}
func TestReleasesService_DeleteRelease(t *testing.T) {
mux, server, client := setup()
defer teardown(server)
mux.HandleFunc("/api/v4/projects/1/releases/v0.1",
func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
fmt.Fprint(w, exampleReleaseRsp)
})
release, _, err := client.Releases.DeleteRelease(1, "v0.1")
if err != nil {
t.Error(err)
}
if release.TagName != "v0.1" {
t.Errorf("expected tag v0.1, got %s", release.TagName)
}
}
......@@ -34,15 +34,15 @@ type TagsService struct {
// GitLab API docs: https://docs.gitlab.com/ce/api/tags.html
type Tag struct {
Commit *Commit `json:"commit"`
Release *Release `json:"release"`
Release *ReleaseNote `json:"release"`
Name string `json:"name"`
Message string `json:"message"`
}
// Release represents a GitLab version release.
// ReleaseNote represents a GitLab version release.
//
// GitLab API docs: https://docs.gitlab.com/ce/api/tags.html
type Release struct {
type ReleaseNote struct {
TagName string `json:"tag_name"`
Description string `json:"description"`
}
......@@ -121,6 +121,7 @@ type CreateTagOptions struct {
TagName *string `url:"tag_name,omitempty" json:"tag_name,omitempty"`
Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
Message *string `url:"message,omitempty" json:"message,omitempty"`
// ReleaseDescription parameter was deprecated in GitLab 11.7
ReleaseDescription *string `url:"release_description:omitempty" json:"release_description,omitempty"`
}
......@@ -168,20 +169,24 @@ func (s *TagsService) DeleteTag(pid interface{}, tag string, options ...OptionFu
return s.client.Do(req, nil)
}
// CreateReleaseOptions represents the available CreateRelease() options.
// CreateReleaseNoteOptions represents the available CreateReleaseNote() options.
//
// Deprecated: This feature was deprecated in GitLab 11.7.
//
// GitLab API docs:
// https://docs.gitlab.com/ce/api/tags.html#create-a-new-release
type CreateReleaseOptions struct {
type CreateReleaseNoteOptions struct {
Description *string `url:"description:omitempty" json:"description,omitempty"`
}
// CreateRelease Add release notes to the existing git tag.
// CreateReleaseNote Add release notes to the existing git tag.
// If there already exists a release for the given tag, status code 409 is returned.
//
// Deprecated: This feature was deprecated in GitLab 11.7.
//
// GitLab API docs:
// https://docs.gitlab.com/ce/api/tags.html#create-a-new-release
func (s *TagsService) CreateRelease(pid interface{}, tag string, opt *CreateReleaseOptions, options ...OptionFunc) (*Release, *Response, error) {
func (s *TagsService) CreateReleaseNote(pid interface{}, tag string, opt *CreateReleaseNoteOptions, options ...OptionFunc) (*ReleaseNote, *Response, error) {
project, err := parseID(pid)
if err != nil {
return nil, nil, err
......@@ -193,7 +198,7 @@ func (s *TagsService) CreateRelease(pid interface{}, tag string, opt *CreateRele
return nil, nil, err
}
r := new(Release)
r := new(ReleaseNote)
resp, err := s.client.Do(req, r)
if err != nil {
return nil, resp, err
......@@ -202,19 +207,21 @@ func (s *TagsService) CreateRelease(pid interface{}, tag string, opt *CreateRele
return r, resp, err
}
// UpdateReleaseOptions represents the available UpdateRelease() options.
// UpdateReleaseNoteOptions represents the available UpdateReleaseNote() options.
//
// GitLab API docs:
// https://docs.gitlab.com/ce/api/tags.html#update-a-release
type UpdateReleaseOptions struct {
type UpdateReleaseNoteOptions struct {
Description *string `url:"description:omitempty" json:"description,omitempty"`
}
// UpdateRelease Updates the release notes of a given release.
// UpdateReleaseNote Updates the release notes of a given release.
//
// Deprecated: This feature was deprecated in GitLab 11.7.
//
// GitLab API docs:
// https://docs.gitlab.com/ce/api/tags.html#update-a-release
func (s *TagsService) UpdateRelease(pid interface{}, tag string, opt *UpdateReleaseOptions, options ...OptionFunc) (*Release, *Response, error) {
func (s *TagsService) UpdateReleaseNote(pid interface{}, tag string, opt *UpdateReleaseNoteOptions, options ...OptionFunc) (*ReleaseNote, *Response, error) {
project, err := parseID(pid)
if err != nil {
return nil, nil, err
......@@ -226,7 +233,7 @@ func (s *TagsService) UpdateRelease(pid interface{}, tag string, opt *UpdateRele
return nil, nil, err
}
r := new(Release)
r := new(ReleaseNote)
resp, err := s.client.Do(req, r)
if err != nil {
return nil, resp, err
......
......@@ -7,7 +7,7 @@ import (
"testing"
)
func TestListTags(t *testing.T) {
func TestTagsService_ListTags(t *testing.T) {
mux, server, client := setup()
defer teardown(server)
......@@ -29,45 +29,47 @@ func TestListTags(t *testing.T) {
}
}
func TestCreateRelease(t *testing.T) {
func TestTagsService_CreateReleaseNote(t *testing.T) {
mux, server, client := setup()
defer teardown(server)
mux.HandleFunc("/api/v4/projects/1/repository/tags/1.0.0/release", func(w http.ResponseWriter, r *http.Request) {
mux.HandleFunc("/api/v4/projects/1/repository/tags/1.0.0/release",
func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
fmt.Fprint(w, `{"tag_name": "1.0.0", "description": "Amazing release. Wow"}`)
})
opt := &CreateReleaseOptions{Description: String("Amazing release. Wow")}
opt := &CreateReleaseNoteOptions{Description: String("Amazing release. Wow")}
release, _, err := client.Tags.CreateRelease(1, "1.0.0", opt)
release, _, err := client.Tags.CreateReleaseNote(1, "1.0.0", opt)
if err != nil {
t.Errorf("Tags.CreateRelease returned error: %v", err)
}
want := &Release{TagName: "1.0.0", Description: "Amazing release. Wow"}
want := &ReleaseNote{TagName: "1.0.0", Description: "Amazing release. Wow"}
if !reflect.DeepEqual(want, release) {
t.Errorf("Tags.CreateRelease returned %+v, want %+v", release, want)
}
}
func TestUpdateRelease(t *testing.T) {
func TestTagsService_UpdateReleaseNote(t *testing.T) {
mux, server, client := setup()
defer teardown(server)
mux.HandleFunc("/api/v4/projects/1/repository/tags/1.0.0/release", func(w http.ResponseWriter, r *http.Request) {
mux.HandleFunc("/api/v4/projects/1/repository/tags/1.0.0/release",
func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
fmt.Fprint(w, `{"tag_name": "1.0.0", "description": "Amazing release. Wow!"}`)
})
opt := &UpdateReleaseOptions{Description: String("Amazing release. Wow!")}
opt := &UpdateReleaseNoteOptions{Description: String("Amazing release. Wow!")}
release, _, err := client.Tags.UpdateRelease(1, "1.0.0", opt)
release, _, err := client.Tags.UpdateReleaseNote(1, "1.0.0", opt)
if err != nil {
t.Errorf("Tags.UpdateRelease returned error: %v", err)
}
want := &Release{TagName: "1.0.0", Description: "Amazing release. Wow!"}
want := &ReleaseNote{TagName: "1.0.0", Description: "Amazing release. Wow!"}
if !reflect.DeepEqual(want, release) {
t.Errorf("Tags.UpdateRelease returned %+v, want %+v", release, want)
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment