diff --git a/github/github.go b/github/github.go index 14b5328..2df7917 100644 --- a/github/github.go +++ b/github/github.go @@ -30,7 +30,8 @@ const ( headerRateRemaining = "X-RateLimit-Remaining" headerRateReset = "X-RateLimit-Reset" - mimePreview = "application/vnd.github.preview" + mimePreview = "application/vnd.github.preview" + mimeReleasePreview = "application/vnd.github.manifold-preview" ) // A Client manages communication with the GitHub API. diff --git a/github/repos_releases.go b/github/repos_releases.go new file mode 100644 index 0000000..aea8ed9 --- /dev/null +++ b/github/repos_releases.go @@ -0,0 +1,123 @@ +// Copyright 2013 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import "fmt" + +// RepositoryRelease represents a GitHub release in a repository. +type RepositoryRelease struct { + ID *int `json:"id,omitempty"` + TagName *string `json:"tag_name,omitempty"` + TargetCommitish *string `json:"target_commitish,omitempty"` + Name *string `json:"name,omitempty"` + Body *string `json:"body,omitempty"` + Draft *bool `json:"draft"` + Prerelease *bool `json:"prerelease"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + PublishedAt *Timestamp `json:"published_at,omitempty"` + URL *string `json:"url,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` + AssetsURL *string `json:"assets_url,omitempty"` + UploadURL *string `json:"upload_url,omitempty"` +} + +func (r RepositoryRelease) String() string { + return Stringify(r) +} + +// ListReleases lists the releases for a repository. +// +// GitHub API docs: http://developer.github.com/v3/repos/releases/#list-releases-for-a-repository +func (s *RepositoriesService) ListReleases(owner, repo string) ([]RepositoryRelease, *Response, error) { + u := fmt.Sprintf("repos/%s/%s/releases", owner, repo) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + req.Header.Add("Accept", mimeReleasePreview) + + releases := new([]RepositoryRelease) + resp, err := s.client.Do(req, releases) + if err != nil { + return nil, resp, err + } + return *releases, resp, err +} + +// GetRelease fetches a single release. +// +// GitHub API docs: http://developer.github.com/v3/repos/releases/#get-a-single-release +func (s *RepositoriesService) GetRelease(owner, repo string, id int) (*RepositoryRelease, *Response, error) { + u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + req.Header.Add("Accept", mimeReleasePreview) + + release := new(RepositoryRelease) + resp, err := s.client.Do(req, release) + if err != nil { + return nil, resp, err + } + return release, resp, err +} + +// CreateRelease adds a new release for a repository. +// +// GitHub API docs : http://developer.github.com/v3/repos/releases/#create-a-release +func (s *RepositoriesService) CreateRelease(owner, repo string, release *RepositoryRelease) (*RepositoryRelease, *Response, error) { + u := fmt.Sprintf("repos/%s/%s/releases", owner, repo) + + req, err := s.client.NewRequest("POST", u, release) + if err != nil { + return nil, nil, err + } + req.Header.Add("Accept", mimeReleasePreview) + + r := new(RepositoryRelease) + resp, err := s.client.Do(req, r) + if err != nil { + return nil, resp, err + } + return r, resp, err +} + +// EditRelease edits a repository release. +// +// GitHub API docs : http://developer.github.com/v3/repos/releases/#edit-a-release +func (s *RepositoriesService) EditRelease(owner, repo string, id int, release *RepositoryRelease) (*RepositoryRelease, *Response, error) { + u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id) + + req, err := s.client.NewRequest("PATCH", u, release) + if err != nil { + return nil, nil, err + } + req.Header.Add("Accept", mimeReleasePreview) + + r := new(RepositoryRelease) + resp, err := s.client.Do(req, r) + if err != nil { + return nil, resp, err + } + return r, resp, err +} + +// DeleteRelease delete a single release from a repository. +// +// GitHub API docs : http://developer.github.com/v3/repos/releases/#delete-a-release +func (s *RepositoriesService) DeleteRelease(owner, repo string, id int) (*Response, error) { + u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id) + + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + req.Header.Add("Accept", mimeReleasePreview) + return s.client.Do(req, nil) +} diff --git a/github/repos_releases_test.go b/github/repos_releases_test.go new file mode 100644 index 0000000..e22741c --- /dev/null +++ b/github/repos_releases_test.go @@ -0,0 +1,127 @@ +// Copyright 2013 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "encoding/json" + "fmt" + "net/http" + "reflect" + "testing" +) + +func TestRepositoriesService_ListReleases(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/repos/o/u/releases", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mimeReleasePreview) + fmt.Fprint(w, `[{"id":1}]`) + }) + + releases, _, err := client.Repositories.ListReleases("o", "u") + if err != nil { + t.Errorf("Repositories.ListReleases returned error: %v", err) + } + want := []RepositoryRelease{{ID: Int(1)}} + if !reflect.DeepEqual(releases, want) { + t.Errorf("Repositories.ListReleases returned %+v, want %+v", releases, want) + } +} + +func TestRepositoriesService_GetRelease(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/repos/o/u/releases/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testHeader(t, r, "Accept", mimeReleasePreview) + fmt.Fprint(w, `{"id":1}`) + }) + + release, resp, err := client.Repositories.GetRelease("o", "u", 1) + if err != nil { + t.Errorf("Repositories.GetRelease returned error: %v\n%v", err, resp.Body) + } + + want := &RepositoryRelease{ID: Int(1)} + if !reflect.DeepEqual(release, want) { + t.Errorf("Repositories.GetRelease returned %+v, want %+v", release, want) + } +} + +func TestRepositoriesService_CreateRelease(t *testing.T) { + setup() + defer teardown() + + input := &RepositoryRelease{Name: String("v1.0")} + + mux.HandleFunc("/repos/o/u/releases", func(w http.ResponseWriter, r *http.Request) { + v := new(RepositoryRelease) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "POST") + testHeader(t, r, "Accept", mimeReleasePreview) + if !reflect.DeepEqual(v, input) { + t.Errorf("Request body = %+v, want %+v", v, input) + } + fmt.Fprint(w, `{"id":1}`) + }) + + release, _, err := client.Repositories.CreateRelease("o", "u", input) + if err != nil { + t.Errorf("Repositories.CreateRelease returned error: %v", err) + } + + want := &RepositoryRelease{ID: Int(1)} + if !reflect.DeepEqual(release, want) { + t.Errorf("Repositories.CreateRelease returned %+v, want %+v", release, want) + } +} + +func TestRepositoriesService_EditRelease(t *testing.T) { + setup() + defer teardown() + + input := &RepositoryRelease{Name: String("n")} + + mux.HandleFunc("/repos/o/u/releases/1", func(w http.ResponseWriter, r *http.Request) { + v := new(RepositoryRelease) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "PATCH") + testHeader(t, r, "Accept", mimeReleasePreview) + if !reflect.DeepEqual(v, input) { + t.Errorf("Request body = %+v, want %+v", v, input) + } + fmt.Fprint(w, `{"id":1}`) + }) + + release, _, err := client.Repositories.EditRelease("o", "u", 1, input) + if err != nil { + t.Errorf("Repositories.EditRelease returned error: %v", err) + } + want := &RepositoryRelease{ID: Int(1)} + if !reflect.DeepEqual(release, want) { + t.Errorf("Repositories.EditRelease returned = %+v, want %+v", release, want) + } +} + +func TestRepositoriesService_DeleteRelease(t *testing.T) { + setup() + defer teardown() + + mux.HandleFunc("/repos/o/u/releases/1", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + testHeader(t, r, "Accept", mimeReleasePreview) + }) + + _, err := client.Repositories.DeleteRelease("o", "u", 1) + if err != nil { + t.Errorf("Repositories.DeleteRelease returned error: %v", err) + } +}