Files
gitea-release-resource/github.go
Jacob Frank 64e36f5d40 use proxy from environment
[#117482787]

Signed-off-by: Evan Short <eshort@pivotal.io>
2016-04-12 15:20:46 -07:00

268 lines
6.4 KiB
Go

package resource
import (
"errors"
"io"
"net/http"
"net/url"
"os"
"golang.org/x/oauth2"
"github.com/google/go-github/github"
"github.com/xoebus/statham"
)
//go:generate counterfeiter . GitHub
type GitHub interface {
ListReleases() ([]github.RepositoryRelease, error)
GetReleaseByTag(tag string) (*github.RepositoryRelease, error)
GetRelease(id int) (*github.RepositoryRelease, error)
CreateRelease(release github.RepositoryRelease) (*github.RepositoryRelease, error)
UpdateRelease(release github.RepositoryRelease) (*github.RepositoryRelease, error)
ListReleaseAssets(release github.RepositoryRelease) ([]github.ReleaseAsset, error)
UploadReleaseAsset(release github.RepositoryRelease, name string, file *os.File) error
DeleteReleaseAsset(asset github.ReleaseAsset) error
DownloadReleaseAsset(asset github.ReleaseAsset) (io.ReadCloser, error)
GetTarballLink(tag string) (*url.URL, error)
GetZipballLink(tag string) (*url.URL, error)
}
type GitHubClient struct {
client *github.Client
user string
repository string
}
func NewGitHubClient(source Source) (*GitHubClient, error) {
var client *github.Client
if source.AccessToken == "" {
proxyTransport := &http.Transport{Proxy: http.ProxyFromEnvironment}
httpClient := &http.Client{Transport: proxyTransport}
client = github.NewClient(httpClient)
} else {
var err error
client, err = oauthClient(source)
if err != nil {
return nil, err
}
}
if source.GitHubAPIURL != "" {
var err error
client.BaseURL, err = url.Parse(source.GitHubAPIURL)
if err != nil {
return nil, err
}
client.UploadURL, err = url.Parse(source.GitHubAPIURL)
if err != nil {
return nil, err
}
}
if source.GitHubUploadsURL != "" {
var err error
client.UploadURL, err = url.Parse(source.GitHubUploadsURL)
if err != nil {
return nil, err
}
}
return &GitHubClient{
client: client,
user: source.User,
repository: source.Repository,
}, nil
}
func (g *GitHubClient) ListReleases() ([]github.RepositoryRelease, error) {
releases, res, err := g.client.Repositories.ListReleases(g.user, g.repository, nil)
if err != nil {
return []github.RepositoryRelease{}, err
}
err = res.Body.Close()
if err != nil {
return nil, err
}
return releases, nil
}
func (g *GitHubClient) GetReleaseByTag(tag string) (*github.RepositoryRelease, error) {
release, res, err := g.client.Repositories.GetReleaseByTag(g.user, g.repository, tag)
if err != nil {
return &github.RepositoryRelease{}, err
}
err = res.Body.Close()
if err != nil {
return nil, err
}
return release, nil
}
func (g *GitHubClient) GetRelease(id int) (*github.RepositoryRelease, error) {
release, res, err := g.client.Repositories.GetRelease(g.user, g.repository, id)
if err != nil {
return &github.RepositoryRelease{}, err
}
err = res.Body.Close()
if err != nil {
return nil, err
}
return release, nil
}
func (g *GitHubClient) CreateRelease(release github.RepositoryRelease) (*github.RepositoryRelease, error) {
createdRelease, res, err := g.client.Repositories.CreateRelease(g.user, g.repository, &release)
if err != nil {
return &github.RepositoryRelease{}, err
}
err = res.Body.Close()
if err != nil {
return nil, err
}
return createdRelease, nil
}
func (g *GitHubClient) UpdateRelease(release github.RepositoryRelease) (*github.RepositoryRelease, error) {
if release.ID == nil {
return nil, errors.New("release did not have an ID: has it been saved yet?")
}
updatedRelease, res, err := g.client.Repositories.EditRelease(g.user, g.repository, *release.ID, &release)
if err != nil {
return &github.RepositoryRelease{}, err
}
err = res.Body.Close()
if err != nil {
return nil, err
}
return updatedRelease, nil
}
func (g *GitHubClient) ListReleaseAssets(release github.RepositoryRelease) ([]github.ReleaseAsset, error) {
assets, res, err := g.client.Repositories.ListReleaseAssets(g.user, g.repository, *release.ID, nil)
if err != nil {
return []github.ReleaseAsset{}, err
}
err = res.Body.Close()
if err != nil {
return nil, err
}
return assets, nil
}
func (g *GitHubClient) UploadReleaseAsset(release github.RepositoryRelease, name string, file *os.File) error {
_, res, err := g.client.Repositories.UploadReleaseAsset(
g.user,
g.repository,
*release.ID,
&github.UploadOptions{
Name: name,
},
file,
)
if err != nil {
return err
}
return res.Body.Close()
}
func (g *GitHubClient) DeleteReleaseAsset(asset github.ReleaseAsset) error {
res, err := g.client.Repositories.DeleteReleaseAsset(g.user, g.repository, *asset.ID)
if err != nil {
return err
}
return res.Body.Close()
}
func (g *GitHubClient) DownloadReleaseAsset(asset github.ReleaseAsset) (io.ReadCloser, error) {
reader, _, err := g.client.Repositories.DownloadReleaseAsset(g.user, g.repository, *asset.ID)
if err != nil {
return nil, err
}
return reader, err
}
func (g *GitHubClient) GetTarballLink(tag string) (*url.URL, error) {
opt := &github.RepositoryContentGetOptions{Ref: tag}
u, res, err := g.client.Repositories.GetArchiveLink(g.user, g.repository, github.Tarball, opt)
if err != nil {
return nil, err
}
res.Body.Close()
return u, nil
}
func (g *GitHubClient) GetZipballLink(tag string) (*url.URL, error) {
opt := &github.RepositoryContentGetOptions{Ref: tag}
u, res, err := g.client.Repositories.GetArchiveLink(g.user, g.repository, github.Zipball, opt)
if err != nil {
return nil, err
}
res.Body.Close()
return u, nil
}
func oauthClient(source Source) (*github.Client, error) {
ts := oauth2.StaticTokenSource(&oauth2.Token{
AccessToken: source.AccessToken,
})
oauthClient := oauth2.NewClient(oauth2.NoContext, ts)
apiHost := "api.github.com"
if source.GitHubAPIURL != "" {
uri, err := url.Parse(source.GitHubAPIURL)
if err != nil {
return nil, err
}
apiHost = uri.Host
}
uploadHost := "uploads.github.com"
if source.GitHubUploadsURL != "" {
uri, err := url.Parse(source.GitHubUploadsURL)
if err != nil {
return nil, err
}
uploadHost = uri.Host
}
// The google/go-github library uses the same http.Client to perform
// requests to both github.com and the S3 download API (for downloading
// release assets). We don't want it to user the same OAuth transport for
// both.
transport := statham.NewTransport(&http.Transport{Proxy: http.ProxyFromEnvironment}, statham.Mapping{
apiHost: oauthClient.Transport,
uploadHost: oauthClient.Transport,
})
httpClient := &http.Client{
Transport: transport,
}
return github.NewClient(httpClient), nil
}