From dcf231a5fed5c71591ad240b06318f94cac0e6f9 Mon Sep 17 00:00:00 2001 From: Aus Lacroix Date: Mon, 13 Aug 2018 08:41:49 -0700 Subject: [PATCH 1/2] Add increlease verb, implementation. --- cmd.go | 72 +++++++++++++++++++++++++++++++++++++++++++++++ github-release.go | 24 ++++++++++++---- releases.go | 14 +++++++++ 3 files changed, 104 insertions(+), 6 deletions(-) diff --git a/cmd.go b/cmd.go index c6fd56c..d92d4d2 100644 --- a/cmd.go +++ b/cmd.go @@ -376,6 +376,78 @@ func releasecmd(opt Options) error { return nil } +func increleasecmd(opt Options) error { + cmdopt := opt.IncRelease + user := nvls(cmdopt.User, EnvUser) + repo := nvls(cmdopt.Repo, EnvRepo) + token := nvls(cmdopt.Token, EnvToken) + + vprintln("incremental release...") + + release, err := LatestRelease(user, repo, token) + if err != nil { + return err + } + + err = IncrementReleaseVersion(release) + if err != nil { + return err + } + + tag := nvls(cmdopt.Tag, release.TagName) + name := nvls(cmdopt.Name, tag) + desc := nvls(cmdopt.Desc, tag) + target := nvls(cmdopt.Target) + draft := cmdopt.Draft + prerelease := cmdopt.Prerelease + + if err := ValidateCredentials(user, repo, token, tag); err != nil { + return err + } + + params := ReleaseCreate{ + TagName: release.TagName, + TargetCommitish: target, + Name: name, + Body: desc, + Draft: draft, + Prerelease: prerelease, + } + + /* encode params as json */ + payload, err := json.Marshal(params) + if err != nil { + return fmt.Errorf("can't encode release creation params, %v", err) + } + reader := bytes.NewReader(payload) + + URL := nvls(EnvApiEndpoint, github.DefaultBaseURL) + fmt.Sprintf("/repos/%s/%s/releases", user, repo) + resp, err := github.DoAuthRequest("POST", URL, "application/json", token, nil, reader) + if err != nil { + return fmt.Errorf("while submitting %v, %v", string(payload), err) + } + defer resp.Body.Close() + + vprintln("RESPONSE:", resp) + if resp.StatusCode != http.StatusCreated { + if resp.StatusCode == 422 { + return fmt.Errorf("github returned %v (this is probably because the release already exists)", + resp.Status) + } + return fmt.Errorf("github returned %v", resp.Status) + } + + if VERBOSITY != 0 { + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("error while reading response, %v", err) + } + vprintln("BODY:", string(body)) + } + + return nil +} + func editcmd(opt Options) error { cmdopt := opt.Edit user := nvls(cmdopt.User, EnvUser) diff --git a/github-release.go b/github-release.go index 9c6f27c..016707e 100644 --- a/github-release.go +++ b/github-release.go @@ -46,6 +46,17 @@ type Options struct { Draft bool `goptions:"--draft, description='The release is a draft'"` Prerelease bool `goptions:"-p, --pre-release, description='The release is a pre-release'"` } `goptions:"release"` + IncRelease struct { + Token string `goptions:"-s, --security-token, description='Github token (required if $GITHUB_TOKEN not set)'"` + User string `goptions:"-u, --user, description='Github repo user or organisation (required if $GITHUB_USER not set)'"` + Repo string `goptions:"-r, --repo, description='Github repo (required if $GITHUB_REPO not set)'"` + Tag string `goptions:"-t, --tag, description='Git tag to create a release from'"` + Name string `goptions:"-n, --name, description='Name of the release (defaults to tag)'"` + Desc string `goptions:"-d, --description, description='Release description, use - for reading a description from stdin (defaults to tag)'"` + Target string `goptions:"-c, --target, description='Commit SHA or branch to create release of (defaults to the repository default branch)'"` + Draft bool `goptions:"--draft, description='The release is a draft'"` + Prerelease bool `goptions:"-p, --pre-release, description='The release is a pre-release'"` + } `goptions:"increlease"` Edit struct { Token string `goptions:"-s, --security-token, description='Github token (required if $GITHUB_TOKEN not set)'"` User string `goptions:"-u, --user, description='Github repo user or organisation (required if $GITHUB_USER not set)'"` @@ -74,12 +85,13 @@ type Options struct { type Command func(Options) error var commands = map[goptions.Verbs]Command{ - "download": downloadcmd, - "upload": uploadcmd, - "release": releasecmd, - "edit": editcmd, - "delete": deletecmd, - "info": infocmd, + "download": downloadcmd, + "upload": uploadcmd, + "release": releasecmd, + "increlease": increleasecmd, + "edit": editcmd, + "delete": deletecmd, + "info": infocmd, } var ( diff --git a/releases.go b/releases.go index bc8cf9b..7f4c34e 100644 --- a/releases.go +++ b/releases.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "strconv" "strings" "time" @@ -126,6 +127,19 @@ func ReleaseOfTag(user, repo, tag, token string) (*Release, error) { return nil, fmt.Errorf("could not find the release corresponding to tag %s", tag) } +func IncrementReleaseVersion(release *Release) error { + version, err := strconv.Atoi(release.TagName[1:]) + version++ + + release.TagName = fmt.Sprintf("v%d", version) + release.Name = release.TagName + release.Description = time.Now().Format(RELEASE_DATE_FORMAT) + + fmt.Printf("Release: %+v\n", release) + + return err +} + /* find the release-id of the specified tag */ func IdOfTag(user, repo, tag, token string) (int, error) { release, err := ReleaseOfTag(user, repo, tag, token) From ac303525939147df5b24846150135fecfdcc4ed8 Mon Sep 17 00:00:00 2001 From: Aus Lacroix Date: Mon, 13 Aug 2018 09:00:29 -0700 Subject: [PATCH 2/2] More robust implementation. Handle no release existing. --- cmd.go | 11 ++--------- releases.go | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/cmd.go b/cmd.go index d92d4d2..f024402 100644 --- a/cmd.go +++ b/cmd.go @@ -384,15 +384,8 @@ func increleasecmd(opt Options) error { vprintln("incremental release...") - release, err := LatestRelease(user, repo, token) - if err != nil { - return err - } - - err = IncrementReleaseVersion(release) - if err != nil { - return err - } + release, _ := LatestRelease(user, repo, token) + release = IncrementReleaseVersion(release) tag := nvls(cmdopt.Tag, release.TagName) name := nvls(cmdopt.Name, tag) diff --git a/releases.go b/releases.go index 7f4c34e..ae8add1 100644 --- a/releases.go +++ b/releases.go @@ -127,17 +127,19 @@ func ReleaseOfTag(user, repo, tag, token string) (*Release, error) { return nil, fmt.Errorf("could not find the release corresponding to tag %s", tag) } -func IncrementReleaseVersion(release *Release) error { - version, err := strconv.Atoi(release.TagName[1:]) - version++ +func IncrementReleaseVersion(release *Release) *Release { + // Handle nil release gracefully + version := 0 + if release != nil { + version, _ = strconv.Atoi(release.TagName[1:]) + version++ + } else { + release = &Release{} + } release.TagName = fmt.Sprintf("v%d", version) - release.Name = release.TagName - release.Description = time.Now().Format(RELEASE_DATE_FORMAT) - - fmt.Printf("Release: %+v\n", release) - return err + return release } /* find the release-id of the specified tag */