1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-03-17 20:47:50 +02:00

Always use latest tag as source. Fixes #72.

Stash local changes and checkout tag before building and releasing.
Added a Cleaner interface to revert repo to original state after.
Clean is even called after errors.
Source pipe is implemented as pointer to store local state.
This commit is contained in:
Jorin Vogel 2017-01-19 09:47:17 +01:00
parent 22dd16df81
commit 655e64b4bf
3 changed files with 124 additions and 10 deletions

35
main.go
View File

@ -15,6 +15,7 @@ import (
"github.com/goreleaser/goreleaser/pipeline/git"
"github.com/goreleaser/goreleaser/pipeline/release"
"github.com/goreleaser/goreleaser/pipeline/repos"
"github.com/goreleaser/goreleaser/pipeline/source"
"github.com/urfave/cli"
)
@ -27,6 +28,8 @@ var pipes = []pipeline.Pipe{
git.Pipe{},
repos.Pipe{},
&source.Pipe{},
// real work
build.Pipe{},
archive.Pipe{},
@ -46,27 +49,39 @@ func main() {
Value: "goreleaser.yml",
},
}
app.Action = func(c *cli.Context) (err error) {
app.Action = func(c *cli.Context) error {
var file = c.String("config")
cfg, err := config.Load(file)
// Allow failing to load the config file if file is not explicitly specified
if err != nil && c.IsSet("config") {
return cli.NewExitError(err.Error(), 1)
}
context := context.New(cfg)
ctx := context.New(cfg)
log.SetFlags(0)
for _, pipe := range pipes {
log.Println(pipe.Description())
log.SetPrefix(" -> ")
if err := pipe.Run(context); err != nil {
return cli.NewExitError(err.Error(), 1)
}
log.SetPrefix("")
if err := runPipeline(ctx); err != nil {
return cli.NewExitError(err.Error(), 1)
}
log.Println("Done!")
return
return nil
}
if err := app.Run(os.Args); err != nil {
log.Fatalln(err)
}
}
func runPipeline(ctx *context.Context) error {
for _, pipe := range pipes {
log.Println(pipe.Description())
log.SetPrefix(" -> ")
err := pipe.Run(ctx)
log.SetPrefix("")
cleaner, ok := pipe.(pipeline.Cleaner)
if ok {
defer cleaner.Clean(ctx)
}
if err != nil {
return err
}
}
return nil
}

10
pipeline/cleaner.go Normal file
View File

@ -0,0 +1,10 @@
package pipeline
import "github.com/goreleaser/goreleaser/context"
// Cleaner is an interface that a pipe can implement
// to cleanup after all pipes ran.
type Cleaner interface {
// Clean is called after pipeline is done - even if a pipe returned an error.
Clean(*context.Context)
}

89
pipeline/source/source.go Normal file
View File

@ -0,0 +1,89 @@
// Package source provides pipes to take care of using the correct source files.
// For the releasing process we need the files of the tag we are releasing.
package source
import (
"bytes"
"fmt"
"log"
"os/exec"
"github.com/goreleaser/goreleaser/context"
)
// Pipe to use the latest Git tag as source.
type Pipe struct {
dirty bool
wrongBranch bool
}
// Description of the pipe
func (p *Pipe) Description() string {
return "Using source from latest tag..."
}
// Run uses the latest tag as source.
// Uncommited changes are stashed.
func (p *Pipe) Run(ctx *context.Context) error {
cmd := exec.Command("git", "diff-index", "--quiet", "HEAD", "--")
err := cmd.Run()
dirty := err != nil
if dirty {
log.Println("Stashing changes...")
cmd = exec.Command("git", "stash", "--include-untracked", "--quiet")
var stdout bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stdout
err = cmd.Run()
if err != nil {
return fmt.Errorf("failed stashing changes: %s", stdout.String())
}
}
p.dirty = dirty
cmd = exec.Command("git", "describe", "--exact-match", "--match", ctx.Git.CurrentTag)
err = cmd.Run()
wrongBranch := err != nil
if wrongBranch {
log.Println("Checking out tag...")
cmd = exec.Command("git", "checkout", ctx.Git.CurrentTag)
var stdout bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stdout
if err = cmd.Run(); err != nil {
return fmt.Errorf("failed changing branch: %s", stdout.String())
}
}
p.wrongBranch = wrongBranch
return nil
}
// Clean switches back to the original branch and restores changes.
func (p *Pipe) Clean(ctx *context.Context) {
if p.wrongBranch {
log.Println("Checking out original branch...")
cmd := exec.Command("git", "checkout", "-")
var stdout bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stdout
if err := cmd.Run(); err != nil {
log.Printf("failed changing branch: %s\n", stdout.String())
}
}
if p.dirty {
log.Println("Popping stashed changes...")
cmd := exec.Command("git", "stash", "pop")
var stdout bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stdout
if err := cmd.Run(); err != nil {
log.Printf("failed popping stashed changes: %s\n", stdout.String())
}
}
}