From 53bcc23e1f2715ce9c57a1546d20fbf7d384428a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Fr=C3=B6ssman?= Date: Thu, 11 Feb 2016 13:04:57 +0100 Subject: [PATCH 1/3] Avoid drone->gh args race with struct --- main.go | 49 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/main.go b/main.go index da4d3c2..13854f2 100644 --- a/main.go +++ b/main.go @@ -98,22 +98,37 @@ 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), + } + + 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) { +// Release holds ties the drone env data and github client together. +type releaseClient struct { + *github.Client + Owner string + Repo string + Tag 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 +136,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,29 +144,29 @@ 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(owner, repo, tag) +func (rc *releaseClient) getRelease() (*github.RepositoryRelease, error) { + release, _, err := rc.Client.Repositories.GetReleaseByTag(rc.Owner, rc.Repo, rc.Tag) if err != nil { - return nil, fmt.Errorf("Release %s not found", tag) + return nil, fmt.Errorf("Release %s not found", rc.Tag) } - fmt.Printf("Successfully retrieved %s release\n", tag) + fmt.Printf("Successfully retrieved %s release\n", rc.Tag) 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)} + 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", tag) + fmt.Printf("Successfully created %s release\n", rc.Tag) return release, nil } -func uploadFiles(client *github.Client, owner string, repo string, id int, files []string) error { - assets, _, err := client.Repositories.ListReleaseAssets(owner, repo, id, &github.ListOptions{}) +func (rc *releaseClient) uploadFiles(id int, files []string) error { + assets, _, err := rc.Client.Repositories.ListReleaseAssets(rc.Owner, rc.Repo, id, &github.ListOptions{}) if err != nil { return fmt.Errorf("Failed to fetch existing assets: %s", err) } @@ -164,7 +179,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(owner, repo, *asset.ID); err != nil { + if _, err := rc.Client.Repositories.DeleteReleaseAsset(rc.Owner, rc.Repo, *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 +187,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(owner, repo, id, uo, handle); err != nil { + if _, _, err = rc.Client.Repositories.UploadReleaseAsset(rc.Owner, rc.Repo, id, uo, handle); err != nil { return fmt.Errorf("Failed to upload %s artifact: %s", file, err) } From cc6a93ab03374c0a96e791a6afa494accd484892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Fr=C3=B6ssman?= Date: Thu, 11 Feb 2016 14:23:52 +0100 Subject: [PATCH 2/3] Add setting to create draft releases Closes #10 --- DOCS.md | 1 + main.go | 7 ++++++- types.go | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/DOCS.md b/DOCS.md index c39d797..a934242 100644 --- a/DOCS.md +++ b/DOCS.md @@ -4,6 +4,7 @@ can override the default configuration with the following parameters: * `api_key` - GitHub oauth token with public_repo or repo permission * `files` - Files to upload to GitHub Release, globs are allowed * `checksum` - Checksum takes hash methods to include in your GitHub release for the files specified. Supported hash methods include md5, sha1, sha256, sha512, adler32, and crc32. +* `draft` - create a draft release if set to true * `base_url` - GitHub base URL, only required for GHE * `upload_url` - GitHub upload URL, only required for GHE diff --git a/main.go b/main.go index 13854f2..00bd080 100644 --- a/main.go +++ b/main.go @@ -103,6 +103,7 @@ func main() { Owner: repo.Owner, Repo: repo.Name, Tag: filepath.Base(build.Ref), + Draft: vargs.Draft, } release, err := rc.buildRelease() @@ -123,6 +124,7 @@ type releaseClient struct { Owner string Repo string Tag string + Draft bool } func (rc *releaseClient) buildRelease() (*github.RepositoryRelease, error) { @@ -155,7 +157,10 @@ func (rc *releaseClient) getRelease() (*github.RepositoryRelease, error) { } func (rc *releaseClient) newRelease() (*github.RepositoryRelease, error) { - rr := &github.RepositoryRelease{TagName: github.String(rc.Tag)} + 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) diff --git a/types.go b/types.go index 295d5f7..c77e566 100644 --- a/types.go +++ b/types.go @@ -9,4 +9,5 @@ type Params struct { APIKey string `json:"api_key"` Files drone.StringSlice `json:"files"` Checksum drone.StringSlice `json:"checksum"` + Draft bool `json:"draft"` } From 00b0b14fc27d5456aa337aec55d58d2786e6522e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Fr=C3=B6ssman?= Date: Thu, 11 Feb 2016 15:07:22 +0100 Subject: [PATCH 3/3] Add file_exists option: overwrite/skip/fail Closes #9 --- DOCS.md | 1 + main.go | 46 +++++++++++++++++++++++++++++++++++++++++----- types.go | 13 +++++++------ 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/DOCS.md b/DOCS.md index a934242..4259020 100644 --- a/DOCS.md +++ b/DOCS.md @@ -3,6 +3,7 @@ can override the default configuration with the following parameters: * `api_key` - GitHub oauth token with public_repo or repo permission * `files` - Files to upload to GitHub Release, globs are allowed +* `file_exists` - What to do if an file asset already exists, supported values: **overwrite** (default), **skip** and **fail** * `checksum` - Checksum takes hash methods to include in your GitHub release for the files specified. Supported hash methods include md5, sha1, sha256, sha512, adler32, and crc32. * `draft` - create a draft release if set to true * `base_url` - GitHub base URL, only required for GHE diff --git a/main.go b/main.go index 00bd080..f7f1336 100644 --- a/main.go +++ b/main.go @@ -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, "/") { @@ -104,6 +111,7 @@ func main() { Repo: repo.Name, Tag: filepath.Base(build.Ref), Draft: vargs.Draft, + FileExists: vargs.FileExists, } release, err := rc.buildRelease() @@ -118,13 +126,20 @@ func main() { } } +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 + Owner string + Repo string + Tag string + Draft bool + FileExists string } func (rc *releaseClient) buildRelease() (*github.RepositoryRelease, error) { @@ -159,7 +174,7 @@ func (rc *releaseClient) getRelease() (*github.RepositoryRelease, error) { func (rc *releaseClient) newRelease() (*github.RepositoryRelease, error) { rr := &github.RepositoryRelease{ TagName: github.String(rc.Tag), - Draft: &rc.Draft, + Draft: &rc.Draft, } release, _, err := rc.Client.Repositories.CreateRelease(rc.Owner, rc.Repo, rr) if err != nil { @@ -176,7 +191,28 @@ func (rc *releaseClient) uploadFiles(id int, files []string) error { 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) diff --git a/types.go b/types.go index c77e566..8deee02 100644 --- a/types.go +++ b/types.go @@ -4,10 +4,11 @@ import "github.com/drone/drone-go/drone" // Params are the parameters that the GitHub Release plugin can parse. type Params struct { - BaseURL string `json:"base_url"` - UploadURL string `json:"upload_url"` - APIKey string `json:"api_key"` - Files drone.StringSlice `json:"files"` - Checksum drone.StringSlice `json:"checksum"` - Draft bool `json:"draft"` + BaseURL string `json:"base_url"` + UploadURL string `json:"upload_url"` + APIKey string `json:"api_key"` + Files drone.StringSlice `json:"files"` + Checksum drone.StringSlice `json:"checksum"` + Draft bool `json:"draft"` + FileExists string `json:"file_exists"` }