1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-03-25 21:29:14 +02:00

Merge pull request #184 from goreleaser/custom-release-file

Custom release file
This commit is contained in:
Carlos Alexandro Becker 2017-04-19 18:29:04 -03:00 committed by GitHub
commit 880b2c22ed
14 changed files with 161 additions and 58 deletions

View File

@ -4,7 +4,6 @@ package client
import (
"bytes"
"os"
"os/exec"
"github.com/goreleaser/goreleaser/context"
)
@ -19,17 +18,7 @@ type Info struct {
// Client interface
type Client interface {
GetInfo(ctx *context.Context) (info Info, err error)
CreateRelease(ctx *context.Context) (releaseID int, err error)
CreateRelease(ctx *context.Context, body string) (releaseID int, err error)
CreateFile(ctx *context.Context, content bytes.Buffer, path string) (err error)
Upload(ctx *context.Context, releaseID int, name string, file *os.File) (err error)
}
func describeRelease(diff string) string {
result := "## Changelog\n" + diff + "\n\n--\nAutomated with @goreleaser"
cmd := exec.Command("go", "version")
bts, err := cmd.CombinedOutput()
if err != nil {
return result
}
return result + "\nBuilt with " + string(bts)
}

View File

@ -1,15 +0,0 @@
package client
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestDescription(t *testing.T) {
assert := assert.New(t)
desc := describeRelease("0abf342 some message")
assert.Contains(desc, "0abf342 some message")
assert.Contains(desc, "Automated with @goreleaser")
assert.Contains(desc, "go version go1.")
}

View File

@ -88,11 +88,11 @@ func (c *githubClient) GetInfo(ctx *context.Context) (info Info, err error) {
return
}
func (c *githubClient) CreateRelease(ctx *context.Context) (releaseID int, err error) {
func (c *githubClient) CreateRelease(ctx *context.Context, body string) (releaseID int, err error) {
data := &github.RepositoryRelease{
Name: github.String(ctx.Git.CurrentTag),
TagName: github.String(ctx.Git.CurrentTag),
Body: github.String(describeRelease(ctx.Git.Diff)),
Body: github.String(body),
}
r, _, err := c.client.Repositories.GetReleaseByTag(
ctx,

View File

@ -17,23 +17,22 @@ import (
// GitInfo includes tags and diffs used in some point
type GitInfo struct {
CurrentTag string
PreviousTag string
Diff string
Commit string
CurrentTag string
Commit string
}
// Context carries along some data through the pipes
type Context struct {
ctx.Context
Config config.Project
Token string
Git GitInfo
Archives map[string]string
Artifacts []string
Version string
Validate bool
Publish bool
Config config.Project
Token string
Git GitInfo
Archives map[string]string
Artifacts []string
ReleaseNotes string
Version string
Validate bool
Publish bool
}
var lock sync.Mutex

15
main.go
View File

@ -1,6 +1,7 @@
package main
import (
"io/ioutil"
"log"
"os"
@ -52,6 +53,10 @@ func main() {
Usage: "Load configuration from `FILE`",
Value: "goreleaser.yml",
},
cli.StringFlag{
Name: "release-notes",
Usage: "Path to a markdown file with custom release notes",
},
cli.BoolFlag{
Name: "skip-validate",
Usage: "Skip all the validations against the release",
@ -62,7 +67,9 @@ func main() {
},
}
app.Action = func(c *cli.Context) (err error) {
// TODO: cover this with tests
var file = c.String("config")
var notes = c.String("release-notes")
cfg, err := config.Load(file)
if err != nil {
// Allow file not found errors if config file was not
@ -75,6 +82,14 @@ func main() {
var ctx = context.New(cfg)
ctx.Validate = !c.Bool("skip-validate")
ctx.Publish = !c.Bool("skip-publish")
if notes != "" {
bts, err := ioutil.ReadFile(notes)
if err != nil {
return cli.NewExitError(err.Error(), 1)
}
log.Println("Loaded custom release notes from", notes)
ctx.ReleaseNotes = string(bts)
}
for _, pipe := range pipes {
log.Println(pipe.Description())
log.SetPrefix(" -> ")

View File

@ -163,7 +163,7 @@ func (client *DummyClient) GetInfo(ctx *context.Context) (info client.Info, err
return
}
func (client *DummyClient) CreateRelease(ctx *context.Context) (releaseID int, err error) {
func (client *DummyClient) CreateRelease(ctx *context.Context, body string) (releaseID int, err error) {
return
}

View File

@ -31,6 +31,7 @@ func (Pipe) Run(ctx *context.Context) error {
if ctx.Config.Release.GitHub.Name == "" {
repo, err := remoteRepo()
ctx.Config.Release.GitHub = repo
// TODO add a test to cover this
if err != nil {
return errors.New("failed reading repo from git: " + err.Error())
}

View File

@ -12,6 +12,7 @@ import (
func remoteRepo() (result config.Repo, err error) {
cmd := exec.Command("git", "config", "--get", "remote.origin.url")
bts, err := cmd.CombinedOutput()
// TODO: cover this with tests
if err != nil {
return result, errors.New(err.Error() + ": " + string(bts))
}

View File

@ -47,15 +47,20 @@ func (Pipe) Description() string {
// Run the pipe
func (Pipe) Run(ctx *context.Context) (err error) {
tag, prev, commit, log, err := getInfo()
tag, commit, err := getInfo()
if err != nil {
return
}
ctx.Git = context.GitInfo{
CurrentTag: tag,
PreviousTag: prev,
Diff: log,
Commit: commit,
CurrentTag: tag,
Commit: commit,
}
if ctx.ReleaseNotes == "" {
log, err := getChangelog(tag)
if err != nil {
return err
}
ctx.ReleaseNotes = fmt.Sprintf("## Changelog\n\n%v", log)
}
// removes usual `v` prefix
ctx.Version = strings.TrimPrefix(tag, "v")
@ -81,19 +86,19 @@ func validate(commit, tag, version string) error {
return nil
}
func getInfo() (tag, prev, commit, log string, err error) {
func getChangelog(tag string) (string, error) {
prev, err := previous(tag)
if err != nil {
return "", err
}
return git("log", "--pretty=oneline", "--abbrev-commit", prev+".."+tag)
}
func getInfo() (tag, commit string, err error) {
tag, err = cleanGit("describe", "--tags", "--abbrev=0", "--always")
if err != nil {
return
}
prev, err = previous(tag)
if err != nil {
return
}
log, err = git("log", "--pretty=oneline", "--abbrev-commit", prev+".."+tag)
if err != nil {
return
}
commit, err = cleanGit("show", "--format='%H'", "HEAD")
return
}

View File

@ -118,6 +118,42 @@ func TestNoValidate(t *testing.T) {
assert.NoError(Pipe{}.Run(ctx))
}
func TestChangelog(t *testing.T) {
var assert = assert.New(t)
_, back := createAndChdir(t)
defer back()
gitInit(t)
gitCommit(t, "first")
gitTag(t, "v0.0.1")
gitCommit(t, "added feature 1")
gitCommit(t, "fixed bug 2")
gitTag(t, "v0.0.2")
var ctx = &context.Context{
Config: config.Project{},
}
assert.NoError(Pipe{}.Run(ctx))
assert.Equal("v0.0.2", ctx.Git.CurrentTag)
assert.Contains(ctx.ReleaseNotes, "## Changelog")
assert.Contains(ctx.ReleaseNotes, "added feature 1")
assert.Contains(ctx.ReleaseNotes, "fixed bug 2")
}
func TestCustomReleaseNotes(t *testing.T) {
var assert = assert.New(t)
_, back := createAndChdir(t)
defer back()
gitInit(t)
gitCommit(t, "first")
gitTag(t, "v0.0.1")
var ctx = &context.Context{
Config: config.Project{},
ReleaseNotes: "custom",
}
assert.NoError(Pipe{}.Run(ctx))
assert.Equal("v0.0.1", ctx.Git.CurrentTag)
assert.Equal(ctx.ReleaseNotes, "custom")
}
//
// helper functions
//

32
pipeline/release/body.go Normal file
View File

@ -0,0 +1,32 @@
package release
import (
"bytes"
"html/template"
"os/exec"
"github.com/goreleaser/goreleaser/context"
)
const bodyTemplate = `{{ .ReleaseNotes }}
---
Automated with @goreleaser
Built with {{ .GoVersion }}
`
func describeBody(ctx *context.Context) (bytes.Buffer, error) {
var out bytes.Buffer
bts, err := exec.Command("go", "version").CombinedOutput()
if err != nil {
return out, err
}
var template = template.Must(template.New("release").Parse(bodyTemplate))
err = template.Execute(&out, struct {
ReleaseNotes, GoVersion string
}{
ReleaseNotes: ctx.ReleaseNotes,
GoVersion: string(bts),
})
return out, err
}

View File

@ -0,0 +1,36 @@
package release
import (
"os"
"testing"
"github.com/goreleaser/goreleaser/context"
"github.com/stretchr/testify/assert"
)
func TestDescribeBody(t *testing.T) {
var assert = assert.New(t)
var changelog = "\nfeature1: description\nfeature2: other description"
var ctx = &context.Context{
ReleaseNotes: changelog,
}
out, err := describeBody(ctx)
assert.NoError(err)
assert.Contains(out.String(), changelog)
assert.Contains(out.String(), "Automated with @goreleaser")
assert.Contains(out.String(), "Built with go version go1.8")
}
func TestGoVersionFails(t *testing.T) {
var assert = assert.New(t)
var path = os.Getenv("PATH")
defer func() {
assert.NoError(os.Setenv("PATH", path))
}()
os.Setenv("PATH", "")
var ctx = &context.Context{
ReleaseNotes: "changelog",
}
_, err := describeBody(ctx)
assert.Error(err)
}

View File

@ -30,7 +30,11 @@ func doRun(ctx *context.Context, client client.Client) error {
return nil
}
log.Println("Creating or updating release", ctx.Git.CurrentTag, "on", ctx.Config.Release.GitHub.String())
releaseID, err := client.CreateRelease(ctx)
body, err := describeBody(ctx)
if err != nil {
return err
}
releaseID, err := client.CreateRelease(ctx, body.String())
if err != nil {
return err
}

View File

@ -148,7 +148,7 @@ func (client *DummyClient) GetInfo(ctx *context.Context) (info client.Info, err
return
}
func (client *DummyClient) CreateRelease(ctx *context.Context) (releaseID int, err error) {
func (client *DummyClient) CreateRelease(ctx *context.Context, body string) (releaseID int, err error) {
if client.FailToCreateRelease {
return 0, errors.New("release failed")
}