package github
import (
"context"
"errors"
"fmt"
"io"
"mime"
"net/http"
"os"
"path/filepath"
"strings"
)
type RepositoryRelease struct {
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,omitempty"`
Prerelease *bool `json:"prerelease,omitempty"`
MakeLatest *string `json:"make_latest,omitempty"`
DiscussionCategoryName *string `json:"discussion_category_name,omitempty"`
GenerateReleaseNotes *bool `json:"generate_release_notes,omitempty"`
ID *int64 `json:"id,omitempty"`
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"`
Assets []*ReleaseAsset `json:"assets,omitempty"`
UploadURL *string `json:"upload_url,omitempty"`
ZipballURL *string `json:"zipball_url,omitempty"`
TarballURL *string `json:"tarball_url,omitempty"`
Author *User `json:"author,omitempty"`
NodeID *string `json:"node_id,omitempty"`
}
func (r RepositoryRelease ) String () string {
return Stringify (r )
}
type RepositoryReleaseNotes struct {
Name string `json:"name"`
Body string `json:"body"`
}
type GenerateNotesOptions struct {
TagName string `json:"tag_name"`
PreviousTagName *string `json:"previous_tag_name,omitempty"`
TargetCommitish *string `json:"target_commitish,omitempty"`
}
type ReleaseAsset struct {
ID *int64 `json:"id,omitempty"`
URL *string `json:"url,omitempty"`
Name *string `json:"name,omitempty"`
Label *string `json:"label,omitempty"`
State *string `json:"state,omitempty"`
ContentType *string `json:"content_type,omitempty"`
Size *int `json:"size,omitempty"`
DownloadCount *int `json:"download_count,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
BrowserDownloadURL *string `json:"browser_download_url,omitempty"`
Uploader *User `json:"uploader,omitempty"`
NodeID *string `json:"node_id,omitempty"`
}
func (r ReleaseAsset ) String () string {
return Stringify (r )
}
func (s *RepositoriesService ) ListReleases (ctx context .Context , owner , repo string , opts *ListOptions ) ([]*RepositoryRelease , *Response , error ) {
u := fmt .Sprintf ("repos/%s/%s/releases" , owner , repo )
u , err := addOptions (u , opts )
if err != nil {
return nil , nil , err
}
req , err := s .client .NewRequest ("GET" , u , nil )
if err != nil {
return nil , nil , err
}
var releases []*RepositoryRelease
resp , err := s .client .Do (ctx , req , &releases )
if err != nil {
return nil , resp , err
}
return releases , resp , nil
}
func (s *RepositoriesService ) GetRelease (ctx context .Context , owner , repo string , id int64 ) (*RepositoryRelease , *Response , error ) {
u := fmt .Sprintf ("repos/%s/%s/releases/%d" , owner , repo , id )
return s .getSingleRelease (ctx , u )
}
func (s *RepositoriesService ) GetLatestRelease (ctx context .Context , owner , repo string ) (*RepositoryRelease , *Response , error ) {
u := fmt .Sprintf ("repos/%s/%s/releases/latest" , owner , repo )
return s .getSingleRelease (ctx , u )
}
func (s *RepositoriesService ) GetReleaseByTag (ctx context .Context , owner , repo , tag string ) (*RepositoryRelease , *Response , error ) {
u := fmt .Sprintf ("repos/%s/%s/releases/tags/%s" , owner , repo , tag )
return s .getSingleRelease (ctx , u )
}
func (s *RepositoriesService ) GenerateReleaseNotes (ctx context .Context , owner , repo string , opts *GenerateNotesOptions ) (*RepositoryReleaseNotes , *Response , error ) {
u := fmt .Sprintf ("repos/%s/%s/releases/generate-notes" , owner , repo )
req , err := s .client .NewRequest ("POST" , u , opts )
if err != nil {
return nil , nil , err
}
r := new (RepositoryReleaseNotes )
resp , err := s .client .Do (ctx , req , r )
if err != nil {
return nil , resp , err
}
return r , resp , nil
}
func (s *RepositoriesService ) getSingleRelease (ctx context .Context , url string ) (*RepositoryRelease , *Response , error ) {
req , err := s .client .NewRequest ("GET" , url , nil )
if err != nil {
return nil , nil , err
}
release := new (RepositoryRelease )
resp , err := s .client .Do (ctx , req , release )
if err != nil {
return nil , resp , err
}
return release , resp , nil
}
type repositoryReleaseRequest struct {
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,omitempty"`
Prerelease *bool `json:"prerelease,omitempty"`
MakeLatest *string `json:"make_latest,omitempty"`
GenerateReleaseNotes *bool `json:"generate_release_notes,omitempty"`
DiscussionCategoryName *string `json:"discussion_category_name,omitempty"`
}
func (s *RepositoriesService ) CreateRelease (ctx context .Context , owner , repo string , release *RepositoryRelease ) (*RepositoryRelease , *Response , error ) {
u := fmt .Sprintf ("repos/%s/%s/releases" , owner , repo )
releaseReq := &repositoryReleaseRequest {
TagName : release .TagName ,
TargetCommitish : release .TargetCommitish ,
Name : release .Name ,
Body : release .Body ,
Draft : release .Draft ,
Prerelease : release .Prerelease ,
MakeLatest : release .MakeLatest ,
DiscussionCategoryName : release .DiscussionCategoryName ,
GenerateReleaseNotes : release .GenerateReleaseNotes ,
}
req , err := s .client .NewRequest ("POST" , u , releaseReq )
if err != nil {
return nil , nil , err
}
r := new (RepositoryRelease )
resp , err := s .client .Do (ctx , req , r )
if err != nil {
return nil , resp , err
}
return r , resp , nil
}
func (s *RepositoriesService ) EditRelease (ctx context .Context , owner , repo string , id int64 , release *RepositoryRelease ) (*RepositoryRelease , *Response , error ) {
u := fmt .Sprintf ("repos/%s/%s/releases/%d" , owner , repo , id )
releaseReq := &repositoryReleaseRequest {
TagName : release .TagName ,
TargetCommitish : release .TargetCommitish ,
Name : release .Name ,
Body : release .Body ,
Draft : release .Draft ,
Prerelease : release .Prerelease ,
MakeLatest : release .MakeLatest ,
DiscussionCategoryName : release .DiscussionCategoryName ,
}
req , err := s .client .NewRequest ("PATCH" , u , releaseReq )
if err != nil {
return nil , nil , err
}
r := new (RepositoryRelease )
resp , err := s .client .Do (ctx , req , r )
if err != nil {
return nil , resp , err
}
return r , resp , nil
}
func (s *RepositoriesService ) DeleteRelease (ctx context .Context , owner , repo string , id int64 ) (*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
}
return s .client .Do (ctx , req , nil )
}
func (s *RepositoriesService ) ListReleaseAssets (ctx context .Context , owner , repo string , id int64 , opts *ListOptions ) ([]*ReleaseAsset , *Response , error ) {
u := fmt .Sprintf ("repos/%s/%s/releases/%d/assets" , owner , repo , id )
u , err := addOptions (u , opts )
if err != nil {
return nil , nil , err
}
req , err := s .client .NewRequest ("GET" , u , nil )
if err != nil {
return nil , nil , err
}
var assets []*ReleaseAsset
resp , err := s .client .Do (ctx , req , &assets )
if err != nil {
return nil , resp , err
}
return assets , resp , nil
}
func (s *RepositoriesService ) GetReleaseAsset (ctx context .Context , owner , repo string , id int64 ) (*ReleaseAsset , *Response , error ) {
u := fmt .Sprintf ("repos/%s/%s/releases/assets/%d" , owner , repo , id )
req , err := s .client .NewRequest ("GET" , u , nil )
if err != nil {
return nil , nil , err
}
asset := new (ReleaseAsset )
resp , err := s .client .Do (ctx , req , asset )
if err != nil {
return nil , resp , err
}
return asset , resp , nil
}
func (s *RepositoriesService ) DownloadReleaseAsset (ctx context .Context , owner , repo string , id int64 , followRedirectsClient *http .Client ) (rc io .ReadCloser , redirectURL string , err error ) {
u := fmt .Sprintf ("repos/%s/%s/releases/assets/%d" , owner , repo , id )
req , err := s .client .NewRequest ("GET" , u , nil )
if err != nil {
return nil , "" , err
}
req .Header .Set ("Accept" , defaultMediaType )
s .client .clientMu .Lock ()
defer s .client .clientMu .Unlock ()
var loc string
saveRedirect := s .client .client .CheckRedirect
s .client .client .CheckRedirect = func (req *http .Request , via []*http .Request ) error {
loc = req .URL .String ()
return errors .New ("disable redirect" )
}
defer func () { s .client .client .CheckRedirect = saveRedirect }()
req = withContext (ctx , req )
resp , err := s .client .client .Do (req )
if err != nil {
if !strings .Contains (err .Error(), "disable redirect" ) {
return nil , "" , err
}
if followRedirectsClient != nil {
rc , err := s .downloadReleaseAssetFromURL (ctx , followRedirectsClient , loc )
return rc , "" , err
}
return nil , loc , nil
}
if err := CheckResponse (resp ); err != nil {
_ = resp .Body .Close ()
return nil , "" , err
}
return resp .Body , "" , nil
}
func (s *RepositoriesService ) downloadReleaseAssetFromURL (ctx context .Context , followRedirectsClient *http .Client , url string ) (rc io .ReadCloser , err error ) {
req , err := http .NewRequest ("GET" , url , nil )
if err != nil {
return nil , err
}
req = withContext (ctx , req )
req .Header .Set ("Accept" , "*/*" )
resp , err := followRedirectsClient .Do (req )
if err != nil {
return nil , err
}
if err := CheckResponse (resp ); err != nil {
_ = resp .Body .Close ()
return nil , err
}
return resp .Body , nil
}
func (s *RepositoriesService ) EditReleaseAsset (ctx context .Context , owner , repo string , id int64 , release *ReleaseAsset ) (*ReleaseAsset , *Response , error ) {
u := fmt .Sprintf ("repos/%s/%s/releases/assets/%d" , owner , repo , id )
req , err := s .client .NewRequest ("PATCH" , u , release )
if err != nil {
return nil , nil , err
}
asset := new (ReleaseAsset )
resp , err := s .client .Do (ctx , req , asset )
if err != nil {
return nil , resp , err
}
return asset , resp , nil
}
func (s *RepositoriesService ) DeleteReleaseAsset (ctx context .Context , owner , repo string , id int64 ) (*Response , error ) {
u := fmt .Sprintf ("repos/%s/%s/releases/assets/%d" , owner , repo , id )
req , err := s .client .NewRequest ("DELETE" , u , nil )
if err != nil {
return nil , err
}
return s .client .Do (ctx , req , nil )
}
func (s *RepositoriesService ) UploadReleaseAsset (ctx context .Context , owner , repo string , id int64 , opts *UploadOptions , file *os .File ) (*ReleaseAsset , *Response , error ) {
u := fmt .Sprintf ("repos/%s/%s/releases/%d/assets" , owner , repo , id )
u , err := addOptions (u , opts )
if err != nil {
return nil , nil , err
}
stat , err := file .Stat ()
if err != nil {
return nil , nil , err
}
if stat .IsDir () {
return nil , nil , errors .New ("the asset to upload can't be a directory" )
}
mediaType := mime .TypeByExtension (filepath .Ext (file .Name ()))
if opts .MediaType != "" {
mediaType = opts .MediaType
}
req , err := s .client .NewUploadRequest (u , file , stat .Size (), mediaType )
if err != nil {
return nil , nil , err
}
asset := new (ReleaseAsset )
resp , err := s .client .Do (ctx , req , asset )
if err != nil {
return nil , resp , err
}
return asset , resp , nil
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .