mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-03-17 20:47:50 +02:00
Merge pull request #98 from goreleaser/tag-only
Always use latest tag as source
This commit is contained in:
commit
0636aa8d8d
35
main.go
35
main.go
@ -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
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ type Pipe struct{}
|
||||
|
||||
// Description of the pipe
|
||||
func (Pipe) Description() string {
|
||||
return "Creating archives..."
|
||||
return "Creating archives"
|
||||
}
|
||||
|
||||
// Run the pipe
|
||||
@ -41,7 +41,7 @@ type Archive interface {
|
||||
func create(name string, ctx *context.Context) error {
|
||||
folder := filepath.Join("dist", name)
|
||||
file, err := os.Create(folder + "." + ctx.Config.Archive.Format)
|
||||
log.Println("Creating", file.Name(), "...")
|
||||
log.Println("Creating", file.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
// contain darwin and/or goarch doesn't contain amd64)
|
||||
var ErrNoDarwin64Build = errors.New("brew tap requires a darwin amd64 build")
|
||||
|
||||
const formulae = `class {{ .Name }} < Formula
|
||||
const formula = `class {{ .Name }} < Formula
|
||||
desc "{{ .Desc }}"
|
||||
homepage "{{ .Homepage }}"
|
||||
url "https://github.com/{{ .Repo }}/releases/download/{{ .Tag }}/{{ .File }}.{{ .Format }}"
|
||||
@ -63,7 +63,7 @@ type Pipe struct{}
|
||||
|
||||
// Description of the pipe
|
||||
func (Pipe) Description() string {
|
||||
return "Creating homebrew formulae..."
|
||||
return "Creating homebrew formula"
|
||||
}
|
||||
|
||||
// Run the pipe
|
||||
@ -76,8 +76,8 @@ func (Pipe) Run(ctx *context.Context) error {
|
||||
ctx.Config.Brew.Folder, ctx.Config.Build.BinaryName+".rb",
|
||||
)
|
||||
|
||||
log.Println("Updating", path, "on", ctx.Config.Brew.Repo, "...")
|
||||
out, err := buildFormulae(ctx, client)
|
||||
log.Println("Pushing", path, "to", ctx.Config.Brew.Repo)
|
||||
out, err := buildFormula(ctx, client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -107,17 +107,17 @@ func (Pipe) Run(ctx *context.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func buildFormulae(ctx *context.Context, client *github.Client) (bytes.Buffer, error) {
|
||||
func buildFormula(ctx *context.Context, client *github.Client) (bytes.Buffer, error) {
|
||||
data, err := dataFor(ctx, client)
|
||||
if err != nil {
|
||||
return bytes.Buffer{}, err
|
||||
}
|
||||
return doBuildFormulae(data)
|
||||
return doBuildFormula(data)
|
||||
}
|
||||
|
||||
func doBuildFormulae(data templateData) (bytes.Buffer, error) {
|
||||
func doBuildFormula(data templateData) (bytes.Buffer, error) {
|
||||
var out bytes.Buffer
|
||||
tmpl, err := template.New(data.BinaryName).Parse(formulae)
|
||||
tmpl, err := template.New(data.BinaryName).Parse(formula)
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ func TestFullFormulae(t *testing.T) {
|
||||
data := defaultTemplateData
|
||||
data.Caveats = "Here are some caveats"
|
||||
data.Dependencies = []string{"gtk", "git"}
|
||||
out, err := doBuildFormulae(data)
|
||||
out, err := doBuildFormula(data)
|
||||
assert.NoError(err)
|
||||
formulae := out.String()
|
||||
assertDefaultTemplateData(t, formulae)
|
||||
@ -57,7 +57,7 @@ func TestFullFormulae(t *testing.T) {
|
||||
|
||||
func TestFormulaeNoCaveats(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
out, err := doBuildFormulae(defaultTemplateData)
|
||||
out, err := doBuildFormula(defaultTemplateData)
|
||||
assert.NoError(err)
|
||||
formulae := out.String()
|
||||
assertDefaultTemplateData(t, formulae)
|
||||
|
@ -16,7 +16,7 @@ type Pipe struct{}
|
||||
|
||||
// Description of the pipe
|
||||
func (Pipe) Description() string {
|
||||
return "Building..."
|
||||
return "Building binaries"
|
||||
}
|
||||
|
||||
// Run the pipe
|
||||
@ -42,7 +42,7 @@ func (Pipe) Run(ctx *context.Context) error {
|
||||
func build(name, goos, goarch string, ctx *context.Context) error {
|
||||
ldflags := ctx.Config.Build.Ldflags + " -X main.version=" + ctx.Git.CurrentTag
|
||||
output := "dist/" + name + "/" + ctx.Config.Build.BinaryName + extFor(goos)
|
||||
log.Println("Building", output, "...")
|
||||
log.Println("Building", output)
|
||||
cmd := exec.Command(
|
||||
"go",
|
||||
"build",
|
||||
|
10
pipeline/cleaner.go
Normal file
10
pipeline/cleaner.go
Normal 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)
|
||||
}
|
@ -15,7 +15,7 @@ type Pipe struct{}
|
||||
|
||||
// Description of the pipe
|
||||
func (Pipe) Description() string {
|
||||
return "Setting defaults..."
|
||||
return "Setting defaults"
|
||||
}
|
||||
|
||||
// Run the pipe
|
||||
|
2
pipeline/env/env.go
vendored
2
pipeline/env/env.go
vendored
@ -15,7 +15,7 @@ type Pipe struct{}
|
||||
|
||||
// Description of the pipe
|
||||
func (Pipe) Description() string {
|
||||
return "Loading data from environment variables..."
|
||||
return "Loading environment variables"
|
||||
}
|
||||
|
||||
// Run the pipe
|
||||
|
@ -7,7 +7,7 @@ type Pipe struct{}
|
||||
|
||||
// Description of the pipe
|
||||
func (Pipe) Description() string {
|
||||
return "Gathering Git data..."
|
||||
return "Getting Git info"
|
||||
}
|
||||
|
||||
// Run the pipe
|
||||
|
@ -16,7 +16,7 @@ type Pipe struct{}
|
||||
|
||||
// Description of the pipe
|
||||
func (Pipe) Description() string {
|
||||
return "Releasing to GitHub..."
|
||||
return "Releasing to GitHub"
|
||||
}
|
||||
|
||||
// Run the pipe
|
||||
@ -48,11 +48,11 @@ func getOrCreateRelease(client *github.Client, ctx *context.Context) (*github.Re
|
||||
}
|
||||
r, _, err := client.Repositories.GetReleaseByTag(owner, repo, ctx.Git.CurrentTag)
|
||||
if err != nil {
|
||||
log.Println("Creating release", ctx.Git.CurrentTag, "on", ctx.Config.Release.Repo, "...")
|
||||
log.Println("Creating release", ctx.Git.CurrentTag, "on", ctx.Config.Release.Repo)
|
||||
r, _, err = client.Repositories.CreateRelease(owner, repo, data)
|
||||
return r, err
|
||||
}
|
||||
log.Println("Updating existing release", ctx.Git.CurrentTag, "on", ctx.Config.Release.Repo, "...")
|
||||
log.Println("Updating existing release", ctx.Git.CurrentTag, "on", ctx.Config.Release.Repo)
|
||||
r, _, err = client.Repositories.EditRelease(owner, repo, *r.ID, data)
|
||||
return r, err
|
||||
}
|
||||
@ -74,7 +74,7 @@ func upload(client *github.Client, releaseID int, archive string, ctx *context.C
|
||||
return err
|
||||
}
|
||||
defer func() { _ = file.Close() }()
|
||||
log.Println("Uploading", file.Name(), "...")
|
||||
log.Println("Uploading", file.Name())
|
||||
_, _, err = client.Repositories.UploadReleaseAsset(
|
||||
ctx.ReleaseRepo.Owner,
|
||||
ctx.ReleaseRepo.Name,
|
||||
|
@ -11,7 +11,7 @@ type Pipe struct{}
|
||||
|
||||
// Description of the pipe
|
||||
func (Pipe) Description() string {
|
||||
return "Filling repositories data..."
|
||||
return "Setting repositories"
|
||||
}
|
||||
|
||||
// Run the pipe
|
||||
@ -31,5 +31,8 @@ func (Pipe) Run(ctx *context.Context) (err error) {
|
||||
|
||||
func split(pair string) (string, string) {
|
||||
parts := strings.Split(pair, "/")
|
||||
if len(parts) == 1 {
|
||||
return parts[0], ""
|
||||
}
|
||||
return parts[0], parts[1]
|
||||
}
|
||||
|
@ -11,4 +11,20 @@ func TestSplit(t *testing.T) {
|
||||
a, b := split("a/b")
|
||||
assert.Equal("a", a)
|
||||
assert.Equal("b", b)
|
||||
|
||||
a, b = split("")
|
||||
assert.Equal("", a)
|
||||
assert.Equal("", b)
|
||||
|
||||
a, b = split("a")
|
||||
assert.Equal("a", a)
|
||||
assert.Equal("", b)
|
||||
|
||||
a, b = split("a/")
|
||||
assert.Equal("a", a)
|
||||
assert.Equal("", b)
|
||||
|
||||
a, b = split("/b")
|
||||
assert.Equal("", a)
|
||||
assert.Equal("b", b)
|
||||
}
|
||||
|
85
pipeline/source/source.go
Normal file
85
pipeline/source/source.go
Normal file
@ -0,0 +1,85 @@
|
||||
// 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"
|
||||
"errors"
|
||||
"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.
|
||||
// Uncommitted 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")
|
||||
if err = run("git", "stash", "--include-untracked", "--quiet"); err != nil {
|
||||
return fmt.Errorf("failed stashing changes: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
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", ctx.Git.CurrentTag)
|
||||
if err = run("git", "checkout", ctx.Git.CurrentTag); err != nil {
|
||||
return fmt.Errorf("failed changing branch: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
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")
|
||||
if err := run("git", "checkout", "-"); err != nil {
|
||||
log.Println("failed changing branch: ", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
if p.dirty {
|
||||
log.Println("Popping stashed changes")
|
||||
if err := run("git", "stash", "pop"); err != nil {
|
||||
log.Println("failed popping stashed changes:", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func run(bin string, args ...string) error {
|
||||
cmd := exec.Command(bin, args...)
|
||||
var out bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
cmd.Stderr = &out
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return errors.New(out.String())
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user