@ -37,6 +37,13 @@ func main() {
os . Exit ( 0 )
}
if vargs . FileExists == "" {
vargs . FileExists = "overwrite"
}
if ! fileExistsValues [ vargs . FileExists ] {
fmt . Printf ( "invalid value for file_exists: use [empty], overwrite, skip or fail" )
}
if vargs . BaseURL == "" {
vargs . BaseURL = "https://api.github.com/"
} else if ! strings . HasSuffix ( vargs . BaseURL , "/" ) {
@ -98,22 +105,47 @@ func main() {
client . BaseURL = baseURL
client . UploadURL = uploadURL
release , err := buildRelease ( client , repo . Owner , repo . Name , filepath . Base ( build . Ref ) )
rc := releaseClient {
Client : client ,
Owner : repo . Owner ,
Repo : repo . Name ,
Tag : filepath . Base ( build . Ref ) ,
Draft : vargs . Draft ,
FileExists : vargs . FileExists ,
}
release , err := rc . buildRelease ( )
if err != nil {
fmt . Println ( err )
os . Exit ( 1 )
}
if err := uploadFiles ( client , repo . Owner , repo . Name , * release . ID , files ) ; err != nil {
if err := rc . uploadFiles ( * release . ID , files ) ; err != nil {
fmt . Println ( err )
os . Exit ( 1 )
}
}
func buildRelease ( client * github . Client , owner string , repo string , tag string ) ( * github . RepositoryRelease , error ) {
var fileExistsValues = map [ string ] bool {
"overwrite" : true ,
"fail" : true ,
"skip" : true ,
}
// Release holds ties the drone env data and github client together.
type releaseClient struct {
* github . Client
Owner string
Repo string
Tag string
Draft bool
FileExists string
}
func ( rc * releaseClient ) buildRelease ( ) ( * github . RepositoryRelease , error ) {
// first attempt to get a release by that tag
release , err := getRelease ( client , owner , repo , tag )
release , err := rc . getRelease ( )
if err != nil && release == nil {
fmt . Println ( err )
} else if release != nil {
@ -121,7 +153,7 @@ func buildRelease(client *github.Client, owner string, repo string, tag string)
}
// if no release was found by that tag, create a new one
release , err = newRelease ( client , owner , repo , tag )
release , err = rc . newRelease ( )
if err != nil {
return nil , fmt . Errorf ( "Failed to retrieve or create a release: %s" , err )
}
@ -129,34 +161,58 @@ func buildRelease(client *github.Client, owner string, repo string, tag string)
return release , nil
}
func getRelease ( client * github . Client , owner string , repo string , tag string ) ( * github . RepositoryRelease , error ) {
release , _ , err := client . Repositories . GetReleaseByTag ( o wner, repo , t ag)
func ( rc * releaseClient ) getRelease ( ) ( * github . RepositoryRelease , error ) {
release , _ , err := r c. C lient. Repositories . GetReleaseByTag ( rc . O wner, rc . R epo , rc . T ag)
if err != nil {
return nil , fmt . Errorf ( "Release %s not found" , t ag)
return nil , fmt . Errorf ( "Release %s not found" , rc . T ag)
}
fmt . Printf ( "Successfully retrieved %s release\n" , t ag)
fmt . Printf ( "Successfully retrieved %s release\n" , rc . T ag)
return release , nil
}
func newRelease ( client * github . Client , owner string , repo string , tag string ) ( * github . RepositoryRelease , error ) {
rr := & github . RepositoryRelease { TagName : github . String ( tag ) }
release , _ , err := client . Repositories . CreateRelease ( owner , repo , rr )
func ( rc * releaseClient ) newRelease ( ) ( * github . RepositoryRelease , error ) {
rr := & github . RepositoryRelease {
TagName : github . String ( rc . Tag ) ,
Draft : & rc . Draft ,
}
release , _ , err := rc . Client . Repositories . CreateRelease ( rc . Owner , rc . Repo , rr )
if err != nil {
return nil , fmt . Errorf ( "Failed to create release: %s" , err )
}
fmt . Printf ( "Successfully created %s release\n" , t ag)
fmt . Printf ( "Successfully created %s release\n" , rc . T ag)
return release , nil
}
func uploadFiles ( client * github . Client , owner string , repo string , id int , files [ ] string ) error {
assets , _ , err := client . Repositories . ListReleaseAssets ( o wner, repo , id , & github . ListOptions { } )
func ( rc * releaseClient ) uploadFiles ( id int , files [ ] string ) error {
assets , _ , err := r c. C lient. Repositories . ListReleaseAssets ( rc . O wner, rc . R epo , id , & github . ListOptions { } )
if err != nil {
return fmt . Errorf ( "Failed to fetch existing assets: %s" , err )
}
var uploadFiles [ ] string
files :
for _ , file := range files {
for _ , asset := range assets {
if * asset . Name == path . Base ( file ) {
switch rc . FileExists {
case "overwrite" :
// do nothing
case "fail" :
return fmt . Errorf ( "Asset file %s already exists" , path . Base ( file ) )
case "skip" :
fmt . Printf ( "Skipping pre-existing %s artifact\n" , * asset . Name )
continue files
default :
return fmt . Errorf ( "Internal error, unkown file_exist value %s" , rc . FileExists )
}
}
}
uploadFiles = append ( uploadFiles , file )
}
for _ , file := range uploadFiles {
handle , err := os . Open ( file )
if err != nil {
return fmt . Errorf ( "Failed to read %s artifact: %s" , file , err )
@ -164,7 +220,7 @@ func uploadFiles(client *github.Client, owner string, repo string, id int, files
for _ , asset := range assets {
if * asset . Name == path . Base ( file ) {
if _ , err := client . Repositories . DeleteReleaseAsset ( o wner, repo , * asset . ID ) ; err != nil {
if _ , err := r c. C lient. Repositories . DeleteReleaseAsset ( rc . O wner, rc . R epo , * asset . ID ) ; err != nil {
return fmt . Errorf ( "Failed to delete %s artifact: %s" , file , err )
}
fmt . Printf ( "Successfully deleted old %s artifact\n" , * asset . Name )
@ -172,7 +228,7 @@ func uploadFiles(client *github.Client, owner string, repo string, id int, files
}
uo := & github . UploadOptions { Name : path . Base ( file ) }
if _ , _ , err = client . Repositories . UploadReleaseAsset ( o wner, repo , id , uo , handle ) ; err != nil {
if _ , _ , err = r c. C lient. Repositories . UploadReleaseAsset ( rc . O wner, rc . R epo , id , uo , handle ) ; err != nil {
return fmt . Errorf ( "Failed to upload %s artifact: %s" , file , err )
}