diff --git a/.goreleaser.yml b/.goreleaser.yml index d7f751829..41c63b4a0 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -26,14 +26,16 @@ builds: post: packr clean - goos: + - linux - darwin + - windows goarch: - amd64 goarm: - "6" main: ./buffalo/main.go - binary: buffalo-with-sqlite - flags: -tags sqlite + binary: buffalo-with-zbuffalo + flags: -tags zbuffalo hooks: pre: packr post: packr clean diff --git a/Dockerfile b/Dockerfile index ccee56c5c..26e260ac5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -50,7 +50,7 @@ RUN if [ -z "$CODECOV_TOKEN" ] ; then \ else curl -s https://codecov.io/bash -o codecov && \ bash codecov -f cover.out -X fix; fi -RUN gometalinter --vendor --deadline=5m ./... +RUN gometalinter --vendor --deadline=5m ./... --skip=internal WORKDIR $GOPATH/src/ RUN buffalo new --db-type=sqlite3 hello_world --ci-provider=travis diff --git a/Makefile b/Makefile index 316962fe5..b7286a619 100644 --- a/Makefile +++ b/Makefile @@ -17,5 +17,9 @@ install: deps $(GO_BIN) $(INSTALL) packr clean -test: deps - $(GO_BIN) test -tags ${TAGS} ./... \ No newline at end of file +test: + $(GO_BIN) test -tags ${TAGS} ./... + +ci-test: + $(GO_BIN) test -tags ${TAGS} -race -v ./... + docker build . \ No newline at end of file diff --git a/grifts/release.go b/grifts/release.go index dfde92660..5a042339d 100644 --- a/grifts/release.go +++ b/grifts/release.go @@ -1,131 +1,66 @@ package grifts import ( - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "regexp" - "strings" - + "github.com/gobuffalo/buffalo/internal/release" "github.com/markbates/grift/grift" "github.com/pkg/errors" ) var _ = grift.Desc("release", "Generates a CHANGELOG and creates a new GitHub release based on what is in the version.go file.") var _ = grift.Add("release", func(c *grift.Context) error { - v, err := findVersion() - if err != nil { - return err - } - err = installBin() + v, err := release.FindVersion("runtime/version.go") if err != nil { return err } - err = localTest() + rr, err := release.New(v) if err != nil { return err } - err = dockerTest() - if err != nil { - return err - } - - grift.Run("shoulders", c) - - if err := push(); err != nil { - return errors.WithStack(err) - } - - err = tagRelease(v) - if err != nil { - return err - } - - return runReleaser(v) + rr.Add(release.InBranch("master", func() error { + m, err := release.New(v) + if err != nil { + return errors.WithStack(err) + } + m.Add(release.Command("make", "install")) + m.Add(release.Command("make", "ci-test")) + m.Add(release.Runner{ + Name: "grift shoulders", + Fn: func() error { + return grift.Run("shoulders", c) + }, + }) + p, err := release.PackAndCommit() + if err != nil { + return errors.WithStack(err) + } + m.Add(p) + + tr, err := release.TagRelease("master", v) + if err != nil { + return errors.WithStack(err) + } + m.Add(tr) + m.Add(release.Command("bash", "'goreleaser --rm-dist'")) + + m.Add(release.Command("git", "branch", "-D", "development")) + m.Add(release.Command("git", "branch", "development")) + return m.Run() + })) + + rr.Add(release.InBranch("development", func() error { + m, err := release.New("development") + if err != nil { + return errors.WithStack(err) + } + p, err := release.UnpackAndCommit() + if err != nil { + return errors.WithStack(err) + } + m.Add(p) + return m.Run() + })) + return rr.Run() }) - -func installBin() error { - cmd := exec.Command("go", "install", "-v", "./buffalo") - cmd.Stdin = os.Stdin - cmd.Stderr = os.Stderr - cmd.Stdout = os.Stdout - return cmd.Run() -} - -func localTest() error { - cmd := exec.Command("go", "test", "-tags", "sqlite", "-v", "-race", "./...") - cmd.Stdin = os.Stdin - cmd.Stderr = os.Stderr - cmd.Stdout = os.Stdout - return cmd.Run() -} - -func dockerTest() error { - cmd := exec.Command("docker", "build", ".") - cmd.Stdin = os.Stdin - cmd.Stderr = os.Stderr - cmd.Stdout = os.Stdout - return cmd.Run() -} - -func tagRelease(v string) error { - cmd := exec.Command("git", "tag", v) - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { - return err - } - - cmd = exec.Command("git", "push", "origin", "--tags") - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - return cmd.Run() -} - -func runReleaser(v string) error { - cmd := exec.Command("goreleaser", "--rm-dist") - cmd.Stdin = os.Stdin - cmd.Stderr = os.Stderr - cmd.Stdout = os.Stdout - return cmd.Run() -} - -func push() error { - cmd := exec.Command("git", "push", "origin", "master") - cmd.Stdin = os.Stdin - cmd.Stderr = os.Stderr - cmd.Stdout = os.Stdout - return cmd.Run() -} - -func findVersion() (string, error) { - pwd, err := os.Getwd() - if err != nil { - return "", err - } - vfile, err := ioutil.ReadFile(filepath.Join(pwd, "runtime/version.go")) - if err != nil { - return "", err - } - - //var Version = "v0.4.0" - re := regexp.MustCompile(`const Version = "(.+)"`) - matches := re.FindStringSubmatch(string(vfile)) - if len(matches) < 2 { - return "", errors.New("failed to find the version") - } - v := matches[1] - if strings.Contains(v, "dev") { - return "", errors.Errorf("version can not be a dev version %s", v) - } - if !strings.HasPrefix(v, "v") { - return "", errors.Errorf("version must match format `v0.0.0`: %s", v) - } - return v, nil -} diff --git a/internal/release/release.go b/internal/release/release.go new file mode 100644 index 000000000..269a7b075 --- /dev/null +++ b/internal/release/release.go @@ -0,0 +1,160 @@ +package release + +import ( + "fmt" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "regexp" + "strings" + + "github.com/pkg/errors" +) + +type Runner struct { + Name string + Fn func() error +} + +type Manager struct { + Version string + Runners []Runner +} + +func (m *Manager) Add(r Runner) { + m.Runners = append(m.Runners, r) +} + +func (m Manager) Run() error { + for _, r := range m.Runners { + fmt.Println(r.Name) + if err := r.Fn(); err != nil { + return errors.Wrapf(err, "releaser runner %s failed", r.Name) + } + } + return nil +} + +func New(version string) (*Manager, error) { + version = strings.TrimSpace(version) + if version == "" { + return nil, errors.New("version can not be empty") + } + return &Manager{ + Version: version, + Runners: []Runner{}, + }, nil +} + +func CurrentBranch() (string, error) { + cmd := exec.Command("git", "symbolic-ref", "--short", "HEAD") + b, err := cmd.CombinedOutput() + return string(b), err +} + +func InBranch(name string, fn func() error) Runner { + f := func() error { + cur, err := CurrentBranch() + if err != nil { + return errors.WithStack(err) + } + defer func() { + if err := Command("git", "checkout", cur).Fn(); err != nil { + log.Fatal(err) + } + }() + if err := Command("git", "checkout", name).Fn(); err != nil { + return errors.WithStack(err) + } + return fn() + } + return Runner{ + Name: "git branch: " + name, + Fn: f, + } +} + +func TagRelease(branch string, version string) (Runner, error) { + r := Runner{ + Name: fmt.Sprintf("tag %s as %s", branch, version), + } + m, err := New(version) + if err != nil { + return r, errors.WithStack(err) + } + m.Add(Command("git", "tag", version)) + m.Add(Command("git", "push", "origin", branch)) + m.Add(Command("git", "push", "origin", "--tags")) + r.Fn = m.Run + return r, nil +} + +func PackAndCommit() (Runner, error) { + r := Runner{Name: "packr"} + m, err := New("n/a") + if err != nil { + return r, errors.WithStack(err) + } + m.Add(Command("packr")) + m.Add(Command("git", "add", "**/*-packr.go")) + m.Add(Command("git", "commit", "**/*-packr.go", "-m", "committed packr files")) + r.Fn = m.Run + return r, nil +} + +func UnpackAndCommit() (Runner, error) { + r := Runner{Name: "packr"} + m, err := New("n/a") + if err != nil { + return r, errors.WithStack(err) + } + m.Add(Command("packr", "clean")) + m.Add(Command("git", "add", "**/*-packr.go")) + m.Add(Command("git", "commit", "**/*-packr.go", "-m", "deleted packr files")) + r.Fn = m.Run + return r, nil +} + +func Command(name string, args ...string) Runner { + cmd := exec.Command(name, args...) + cmd.Stdin = os.Stdin + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stdout + + fn := func() error { + return cmd.Run() + } + r := Runner{ + Name: strings.Join(cmd.Args, " "), + Fn: fn, + } + return r +} + +func FindVersion(path string) (string, error) { + pwd, err := os.Getwd() + if err != nil { + return "", err + } + vfile, err := ioutil.ReadFile(filepath.Join(pwd, path)) + if err != nil { + return "", err + } + + //var Version = "v0.4.0" + re := regexp.MustCompile(`const Version = "(.+)"`) + matches := re.FindStringSubmatch(string(vfile)) + if len(matches) < 2 { + return "", errors.New("failed to find the version") + } + v := matches[1] + if strings.Contains(v, "dev") { + return "", errors.Errorf("version can not be a dev version %s", v) + } + if !strings.HasPrefix(v, "v") { + return "", errors.Errorf("version must match format `v0.0.0`: %s", v) + } + return v, nil +}