You've already forked goreleaser
							
							
				mirror of
				https://github.com/goreleaser/goreleaser.git
				synced 2025-10-30 23:58:09 +02:00 
			
		
		
		
	Merge pull request #76 from goreleaser/context
Really big refactory: Context
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,4 +1,3 @@ | ||||
| dist | ||||
| releasr | ||||
| dist/ | ||||
| vendor | ||||
| releaser | ||||
|   | ||||
							
								
								
									
										16
									
								
								clients/github.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								clients/github.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| package clients | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
|  | ||||
| 	"github.com/google/go-github/github" | ||||
| 	"golang.org/x/oauth2" | ||||
| ) | ||||
|  | ||||
| func Github(token string) *github.Client { | ||||
| 	ts := oauth2.StaticTokenSource( | ||||
| 		&oauth2.Token{AccessToken: token}, | ||||
| 	) | ||||
| 	tc := oauth2.NewClient(context.Background(), ts) | ||||
| 	return github.NewClient(tc) | ||||
| } | ||||
| @@ -1,45 +0,0 @@ | ||||
| package config | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"html/template" | ||||
| ) | ||||
|  | ||||
| // ArchiveConfig config used for the archive | ||||
| type ArchiveConfig struct { | ||||
| 	Format       string | ||||
| 	NameTemplate string `yaml:"name_template"` | ||||
| 	Replacements map[string]string | ||||
| } | ||||
|  | ||||
| type archiveNameData struct { | ||||
| 	Os         string | ||||
| 	Arch       string | ||||
| 	Version    string | ||||
| 	BinaryName string | ||||
| } | ||||
|  | ||||
| // ArchiveName following the given template | ||||
| func (config ProjectConfig) ArchiveName(goos, goarch string) (string, error) { | ||||
| 	var data = archiveNameData{ | ||||
| 		Os:         replace(config.Archive.Replacements, goos), | ||||
| 		Arch:       replace(config.Archive.Replacements, goarch), | ||||
| 		Version:    config.Git.CurrentTag, | ||||
| 		BinaryName: config.BinaryName, | ||||
| 	} | ||||
| 	var out bytes.Buffer | ||||
| 	t, err := template.New(data.BinaryName).Parse(config.Archive.NameTemplate) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	err = t.Execute(&out, data) | ||||
| 	return out.String(), err | ||||
| } | ||||
|  | ||||
| func replace(replacements map[string]string, original string) string { | ||||
| 	result := replacements[original] | ||||
| 	if result == "" { | ||||
| 		return original | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
| @@ -1,27 +0,0 @@ | ||||
| package config | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestNameTemplate(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	var config = ProjectConfig{ | ||||
| 		BinaryName: "test", | ||||
| 		Git: GitInfo{ | ||||
| 			CurrentTag: "v1.2.3", | ||||
| 		}, | ||||
| 		Archive: ArchiveConfig{ | ||||
| 			NameTemplate: "{{.BinaryName}}_{{.Os}}_{{.Arch}}_{{.Version}}", | ||||
| 			Replacements: map[string]string{ | ||||
| 				"darwin": "Darwin", | ||||
| 				"amd64":  "x86_64", | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	name, err := config.ArchiveName("darwin", "amd64") | ||||
| 	assert.NoError(err) | ||||
| 	assert.Equal("test_Darwin_x86_64_v1.2.3", name) | ||||
| } | ||||
							
								
								
									
										139
									
								
								config/config.go
									
									
									
									
									
								
							
							
						
						
									
										139
									
								
								config/config.go
									
									
									
									
									
								
							| @@ -1,23 +1,15 @@ | ||||
| package config | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"path" | ||||
| 	"path/filepath" | ||||
|  | ||||
| 	"github.com/goreleaser/releaser/config/git" | ||||
| 	yaml "gopkg.in/yaml.v1" | ||||
| ) | ||||
|  | ||||
| var filePatterns = []string{"LICENCE*", "LICENSE*", "README*", "CHANGELOG*"} | ||||
|  | ||||
| // Homebrew contains the brew section | ||||
| type Homebrew struct { | ||||
| 	Repo    string | ||||
| 	Folder  string | ||||
| 	Token   string `yaml:"-"` | ||||
| 	Caveats string | ||||
| } | ||||
|  | ||||
| @@ -29,11 +21,11 @@ type BuildConfig struct { | ||||
| 	Ldflags string | ||||
| } | ||||
|  | ||||
| // GitInfo includes tags and diffs used in some point | ||||
| type GitInfo struct { | ||||
| 	CurrentTag  string | ||||
| 	PreviousTag string | ||||
| 	Diff        string | ||||
| // ArchiveConfig config used for the archive | ||||
| type ArchiveConfig struct { | ||||
| 	Format       string | ||||
| 	NameTemplate string `yaml:"name_template"` | ||||
| 	Replacements map[string]string | ||||
| } | ||||
|  | ||||
| // ProjectConfig includes all project configuration | ||||
| @@ -42,9 +34,7 @@ type ProjectConfig struct { | ||||
| 	BinaryName string `yaml:"binary_name"` | ||||
| 	Files      []string | ||||
| 	Brew       Homebrew | ||||
| 	Token      string `yaml:"-"` | ||||
| 	Build      BuildConfig | ||||
| 	Git        GitInfo `yaml:"-"` | ||||
| 	Archive    ArchiveConfig | ||||
| } | ||||
|  | ||||
| @@ -54,123 +44,6 @@ func Load(file string) (config ProjectConfig, err error) { | ||||
| 	if err != nil { | ||||
| 		return config, err | ||||
| 	} | ||||
| 	if err := yaml.Unmarshal(data, &config); err != nil { | ||||
| 		return config, err | ||||
| 	} | ||||
| 	config.fillBasicData() | ||||
| 	if err := config.fillFiles(); err != nil { | ||||
| 		return config, err | ||||
| 	} | ||||
| 	if err := config.fillGitData(); err != nil { | ||||
| 		return config, err | ||||
| 	} | ||||
| 	return config, config.validate() | ||||
| } | ||||
|  | ||||
| func (config *ProjectConfig) validate() (err error) { | ||||
| 	if config.BinaryName == "" { | ||||
| 		return errors.New("missing binary_name") | ||||
| 	} | ||||
| 	if config.Repo == "" { | ||||
| 		return errors.New("missing repo") | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func (config *ProjectConfig) fillFiles() (err error) { | ||||
| 	if len(config.Files) != 0 { | ||||
| 		return | ||||
| 	} | ||||
| 	config.Files = []string{} | ||||
| 	for _, pattern := range filePatterns { | ||||
| 		matches, err := globPath(pattern) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		config.Files = append(config.Files, matches...) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func (config *ProjectConfig) fillBasicData() { | ||||
| 	if config.Token == "" { | ||||
| 		config.Token = os.Getenv("GITHUB_TOKEN") | ||||
| 	} | ||||
| 	if config.Brew.Repo != "" { | ||||
| 		config.Brew.Token = config.Token | ||||
| 	} | ||||
| 	if config.Build.Main == "" { | ||||
| 		config.Build.Main = "main.go" | ||||
| 	} | ||||
| 	if len(config.Build.Oses) == 0 { | ||||
| 		config.Build.Oses = []string{"linux", "darwin"} | ||||
| 	} | ||||
| 	if len(config.Build.Arches) == 0 { | ||||
| 		config.Build.Arches = []string{"amd64", "386"} | ||||
| 	} | ||||
| 	if config.Build.Ldflags == "" { | ||||
| 		config.Build.Ldflags = "-s -w" | ||||
| 	} | ||||
| 	if config.Archive.NameTemplate == "" { | ||||
| 		config.Archive.NameTemplate = "{{.BinaryName}}_{{.Os}}_{{.Arch}}" | ||||
| 	} | ||||
| 	if config.Archive.Format == "" { | ||||
| 		config.Archive.Format = "tar.gz" | ||||
| 	} | ||||
| 	if len(config.Archive.Replacements) == 0 { | ||||
| 		config.Archive.Replacements = map[string]string{ | ||||
| 			"darwin":  "Darwin", | ||||
| 			"linux":   "Linux", | ||||
| 			"freebsd": "FreeBSD", | ||||
| 			"openbsd": "OpenBSD", | ||||
| 			"netbsd":  "NetBSD", | ||||
| 			"windows": "Windows", | ||||
| 			"386":     "i386", | ||||
| 			"amd64":   "x86_64", | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (config *ProjectConfig) fillGitData() (err error) { | ||||
| 	tag, err := git.CurrentTag() | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	previous, err := git.PreviousTag(tag) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	log, err := git.Log(previous, tag) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	config.Git.CurrentTag = tag | ||||
| 	config.Git.PreviousTag = previous | ||||
| 	config.Git.Diff = log | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func globPath(p string) (m []string, err error) { | ||||
| 	var cwd string | ||||
| 	var dirs []string | ||||
|  | ||||
| 	if cwd, err = os.Getwd(); err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	fp := path.Join(cwd, p) | ||||
|  | ||||
| 	if dirs, err = filepath.Glob(fp); err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	// Normalise to avoid nested dirs in tarball | ||||
| 	for _, dir := range dirs { | ||||
| 		_, f := filepath.Split(dir) | ||||
| 		m = append(m, f) | ||||
| 	} | ||||
|  | ||||
| 	err = yaml.Unmarshal(data, &config) | ||||
| 	return | ||||
| } | ||||
|   | ||||
| @@ -1,91 +0,0 @@ | ||||
| package config | ||||
|  | ||||
| import ( | ||||
| 	"os" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestFillBasicData(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	config := ProjectConfig{} | ||||
| 	config.fillBasicData() | ||||
|  | ||||
| 	assert.Equal("main.go", config.Build.Main) | ||||
| 	assert.Equal("tar.gz", config.Archive.Format) | ||||
| 	assert.Contains(config.Build.Oses, "darwin") | ||||
| 	assert.Contains(config.Build.Oses, "linux") | ||||
| 	assert.Contains(config.Build.Arches, "386") | ||||
| 	assert.Contains(config.Build.Arches, "amd64") | ||||
| } | ||||
|  | ||||
| func TestFillFilesMissingFiles(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	config := ProjectConfig{} | ||||
| 	err := config.fillFiles() | ||||
|  | ||||
| 	assert.NoError(err) | ||||
| 	assert.Equal([]string{}, config.Files) | ||||
| } | ||||
|  | ||||
| func TestFillFilesUSENMarkdown(t *testing.T) { | ||||
| 	assertFiles(t, "./.test/1", []string{"LICENSE.md", "README.md"}) | ||||
| } | ||||
|  | ||||
| func TestFillFilesRealENMarkdown(t *testing.T) { | ||||
| 	assertFiles(t, "./.test/2", []string{"LICENCE.md", "README.md"}) | ||||
| } | ||||
|  | ||||
| func TestFillFilesArbitratryENTXT(t *testing.T) { | ||||
| 	assertFiles(t, "./.test/3", []string{"LICENCE.txt", "README.txt"}) | ||||
| } | ||||
|  | ||||
| func TestFillFilesArbitratryENNoSuffix(t *testing.T) { | ||||
| 	assertFiles(t, "./.test/4", []string{"LICENCE"}) | ||||
| } | ||||
|  | ||||
| func TestFillFilesChangelog(t *testing.T) { | ||||
| 	assertFiles(t, "./.test/5", []string{"CHANGELOG", "CHANGELOG.md"}) | ||||
| } | ||||
|  | ||||
| func TestValidadeMissingBinaryName(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	config := ProjectConfig{Repo: "asd/asd"} | ||||
| 	assert.Error(config.validate()) | ||||
| } | ||||
|  | ||||
| func TestValidadeMissingRepo(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	config := ProjectConfig{BinaryName: "asd"} | ||||
| 	assert.Error(config.validate()) | ||||
| } | ||||
|  | ||||
| func TestValidadeMinimalConfig(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	config := ProjectConfig{BinaryName: "asd", Repo: "asd/asd"} | ||||
| 	assert.NoError(config.validate()) | ||||
| } | ||||
|  | ||||
| func assertFiles(t *testing.T, dir string, files []string) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	cwd, _ := os.Getwd() | ||||
| 	if err := os.Chdir(dir); err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 	defer func() { | ||||
| 		if err := os.Chdir(cwd); err != nil { | ||||
| 			panic(err) | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	config := ProjectConfig{} | ||||
| 	err := config.fillFiles() | ||||
|  | ||||
| 	assert.NoError(err) | ||||
| 	assert.Equal(files, config.Files) | ||||
| } | ||||
							
								
								
									
										30
									
								
								context/context.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								context/context.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| package context | ||||
|  | ||||
| import "github.com/goreleaser/releaser/config" | ||||
|  | ||||
| // GitInfo includes tags and diffs used in some point | ||||
| type GitInfo struct { | ||||
| 	CurrentTag  string | ||||
| 	PreviousTag string | ||||
| 	Diff        string | ||||
| } | ||||
|  | ||||
| type Repo struct { | ||||
| 	Owner, Name string | ||||
| } | ||||
|  | ||||
| type Context struct { | ||||
| 	Config   *config.ProjectConfig | ||||
| 	Token    *string | ||||
| 	Git      *GitInfo | ||||
| 	Repo     *Repo | ||||
| 	BrewRepo *Repo | ||||
| 	Archives map[string]string | ||||
| } | ||||
|  | ||||
| func New(config config.ProjectConfig) *Context { | ||||
| 	return &Context{ | ||||
| 		Config:   &config, | ||||
| 		Archives: map[string]string{}, | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										26
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								main.go
									
									
									
									
									
								
							| @@ -5,17 +5,33 @@ import ( | ||||
| 	"os" | ||||
|  | ||||
| 	"github.com/goreleaser/releaser/config" | ||||
| 	"github.com/goreleaser/releaser/context" | ||||
| 	"github.com/goreleaser/releaser/pipeline" | ||||
| 	"github.com/goreleaser/releaser/pipeline/brew" | ||||
| 	"github.com/goreleaser/releaser/pipeline/build" | ||||
| 	"github.com/goreleaser/releaser/pipeline/compress" | ||||
| 	"github.com/goreleaser/releaser/pipeline/defaults" | ||||
| 	"github.com/goreleaser/releaser/pipeline/env" | ||||
| 	"github.com/goreleaser/releaser/pipeline/git" | ||||
| 	"github.com/goreleaser/releaser/pipeline/release" | ||||
| 	"github.com/goreleaser/releaser/pipeline/repos" | ||||
| 	"github.com/goreleaser/releaser/pipeline/valid" | ||||
| 	"github.com/urfave/cli" | ||||
| ) | ||||
|  | ||||
| var version = "master" | ||||
|  | ||||
| var pipes = []pipeline.Pipe{ | ||||
| 	// load data, set defaults, etc... | ||||
| 	defaults.Pipe{}, | ||||
| 	env.Pipe{}, | ||||
| 	git.Pipe{}, | ||||
| 	repos.Pipe{}, | ||||
|  | ||||
| 	// validate | ||||
| 	valid.Pipe{}, | ||||
|  | ||||
| 	// real work | ||||
| 	build.Pipe{}, | ||||
| 	compress.Pipe{}, | ||||
| 	release.Pipe{}, | ||||
| @@ -40,11 +56,15 @@ func main() { | ||||
| 		if err != nil { | ||||
| 			return cli.NewExitError(err.Error(), 1) | ||||
| 		} | ||||
| 		log.Println("Releasing", config.Git.CurrentTag, "...") | ||||
| 		context := context.New(config) | ||||
| 		log.SetFlags(0) | ||||
| 		for _, pipe := range pipes { | ||||
| 			if err := pipe.Run(config); err != nil { | ||||
| 				return cli.NewExitError(pipe.Name()+" failed: "+err.Error(), 1) | ||||
| 			log.Println(pipe.Description()) | ||||
| 			log.SetPrefix(" -> ") | ||||
| 			if err := pipe.Run(context); err != nil { | ||||
| 				return cli.NewExitError(err.Error(), 1) | ||||
| 			} | ||||
| 			log.SetPrefix("") | ||||
| 		} | ||||
| 		log.Println("Done!") | ||||
| 		return | ||||
|   | ||||
| @@ -2,17 +2,15 @@ package brew | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"context" | ||||
| 	"log" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| 	"text/template" | ||||
|  | ||||
| 	"github.com/google/go-github/github" | ||||
| 	"github.com/goreleaser/releaser/config" | ||||
| 	"github.com/goreleaser/releaser/clients" | ||||
| 	"github.com/goreleaser/releaser/context" | ||||
| 	"github.com/goreleaser/releaser/sha256sum" | ||||
| 	"github.com/goreleaser/releaser/split" | ||||
| 	"golang.org/x/oauth2" | ||||
| ) | ||||
|  | ||||
| const formulae = `class {{ .Name }} < Formula | ||||
| @@ -43,25 +41,20 @@ type templateData struct { | ||||
| type Pipe struct{} | ||||
|  | ||||
| // Name of the pipe | ||||
| func (Pipe) Name() string { | ||||
| 	return "Homebrew" | ||||
| func (Pipe) Description() string { | ||||
| 	return "Creating homebrew formulae..." | ||||
| } | ||||
|  | ||||
| // Run the pipe | ||||
| func (Pipe) Run(config config.ProjectConfig) error { | ||||
| 	if config.Brew.Repo == "" { | ||||
| func (Pipe) Run(ctx *context.Context) error { | ||||
| 	if ctx.Config.Brew.Repo == "" { | ||||
| 		return nil | ||||
| 	} | ||||
| 	ts := oauth2.StaticTokenSource( | ||||
| 		&oauth2.Token{AccessToken: config.Token}, | ||||
| 	) | ||||
| 	tc := oauth2.NewClient(context.Background(), ts) | ||||
| 	client := github.NewClient(tc) | ||||
| 	client := clients.Github(*ctx.Token) | ||||
| 	path := filepath.Join(ctx.Config.Brew.Folder, ctx.Config.BinaryName+".rb") | ||||
|  | ||||
| 	owner, repo := split.OnSlash(config.Brew.Repo) | ||||
| 	path := filepath.Join(config.Brew.Folder, config.BinaryName+".rb") | ||||
| 	log.Println("Updating", path, "on", config.Brew.Repo, "...") | ||||
| 	out, err := buildFormulae(config, client) | ||||
| 	log.Println("Updating", path, "on", ctx.Config.Brew.Repo, "...") | ||||
| 	out, err := buildFormulae(ctx, client) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| @@ -72,9 +65,13 @@ func (Pipe) Run(config config.ProjectConfig) error { | ||||
| 			Email: github.String("bot@goreleaser"), | ||||
| 		}, | ||||
| 		Content: out.Bytes(), | ||||
| 		Message: github.String(config.BinaryName + " version " + config.Git.CurrentTag), | ||||
| 		Message: github.String( | ||||
| 			ctx.Config.BinaryName + " version " + ctx.Git.CurrentTag, | ||||
| 		), | ||||
| 	} | ||||
|  | ||||
| 	owner := ctx.BrewRepo.Owner | ||||
| 	repo := ctx.BrewRepo.Name | ||||
| 	file, _, res, err := client.Repositories.GetContents( | ||||
| 		owner, repo, path, &github.RepositoryContentGetOptions{}, | ||||
| 	) | ||||
| @@ -87,8 +84,8 @@ func (Pipe) Run(config config.ProjectConfig) error { | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func buildFormulae(config config.ProjectConfig, client *github.Client) (bytes.Buffer, error) { | ||||
| 	data, err := dataFor(config, client) | ||||
| func buildFormulae(ctx *context.Context, client *github.Client) (bytes.Buffer, error) { | ||||
| 	data, err := dataFor(ctx, client) | ||||
| 	if err != nil { | ||||
| 		return bytes.Buffer{}, err | ||||
| 	} | ||||
| @@ -105,19 +102,15 @@ func doBuildFormulae(data templateData) (bytes.Buffer, error) { | ||||
| 	return out, err | ||||
| } | ||||
|  | ||||
| func dataFor(config config.ProjectConfig, client *github.Client) (result templateData, err error) { | ||||
| func dataFor(ctx *context.Context, client *github.Client) (result templateData, err error) { | ||||
| 	var homepage string | ||||
| 	var description string | ||||
| 	owner, repo := split.OnSlash(config.Repo) | ||||
| 	rep, _, err := client.Repositories.Get(owner, repo) | ||||
| 	rep, _, err := client.Repositories.Get(ctx.Repo.Owner, ctx.Repo.Name) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	file, err := config.ArchiveName("darwin", "amd64") | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	sum, err := sha256sum.For("dist/" + file + "." + config.Archive.Format) | ||||
| 	file := ctx.Archives["darwinamd64"] | ||||
| 	sum, err := sha256sum.For("dist/" + file + "." + ctx.Config.Archive.Format) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| @@ -132,15 +125,15 @@ func dataFor(config config.ProjectConfig, client *github.Client) (result templat | ||||
| 		description = *rep.Description | ||||
| 	} | ||||
| 	return templateData{ | ||||
| 		Name:       formulaNameFor(config.BinaryName), | ||||
| 		Name:       formulaNameFor(ctx.Config.BinaryName), | ||||
| 		Desc:       description, | ||||
| 		Homepage:   homepage, | ||||
| 		Repo:       config.Repo, | ||||
| 		Tag:        config.Git.CurrentTag, | ||||
| 		BinaryName: config.BinaryName, | ||||
| 		Caveats:    config.Brew.Caveats, | ||||
| 		Repo:       ctx.Config.Repo, | ||||
| 		Tag:        ctx.Git.CurrentTag, | ||||
| 		BinaryName: ctx.Config.BinaryName, | ||||
| 		Caveats:    ctx.Config.Brew.Caveats, | ||||
| 		File:       file, | ||||
| 		Format:     config.Archive.Format, | ||||
| 		Format:     ctx.Config.Archive.Format, | ||||
| 		SHA256:     sum, | ||||
| 	}, err | ||||
| } | ||||
|   | ||||
| @@ -7,7 +7,7 @@ import ( | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
|  | ||||
| 	"github.com/goreleaser/releaser/config" | ||||
| 	"github.com/goreleaser/releaser/context" | ||||
| 	"golang.org/x/sync/errgroup" | ||||
| ) | ||||
|  | ||||
| @@ -15,44 +15,45 @@ import ( | ||||
| type Pipe struct{} | ||||
|  | ||||
| // Name of the pipe | ||||
| func (Pipe) Name() string { | ||||
| 	return "Build" | ||||
| func (Pipe) Description() string { | ||||
| 	return "Building..." | ||||
| } | ||||
|  | ||||
| // Run the pipe | ||||
| func (Pipe) Run(config config.ProjectConfig) error { | ||||
| func (Pipe) Run(ctx *context.Context) error { | ||||
| 	var g errgroup.Group | ||||
| 	for _, system := range config.Build.Oses { | ||||
| 		for _, arch := range config.Build.Arches { | ||||
| 			system := system | ||||
| 			arch := arch | ||||
| 	for _, goos := range ctx.Config.Build.Oses { | ||||
| 		for _, goarch := range ctx.Config.Build.Arches { | ||||
| 			goos := goos | ||||
| 			goarch := goarch | ||||
| 			name, err := nameFor(ctx, goos, goarch) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			ctx.Archives[goos+goarch] = name | ||||
| 			g.Go(func() error { | ||||
| 				return build(system, arch, config) | ||||
| 				return build(name, goos, goarch, ctx) | ||||
| 			}) | ||||
| 		} | ||||
| 	} | ||||
| 	return g.Wait() | ||||
| } | ||||
|  | ||||
| func build(system, arch string, config config.ProjectConfig) error { | ||||
| 	name, err := config.ArchiveName(system, arch) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	ldflags := config.Build.Ldflags + " -X main.version=" + config.Git.CurrentTag | ||||
| 	output := "dist/" + name + "/" + config.BinaryName | ||||
| 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.BinaryName + extFor(goos) | ||||
| 	log.Println("Building", output, "...") | ||||
| 	cmd := exec.Command( | ||||
| 		"go", | ||||
| 		"build", | ||||
| 		"-ldflags="+ldflags, | ||||
| 		"-o", output, | ||||
| 		config.Build.Main, | ||||
| 		ctx.Config.Build.Main, | ||||
| 	) | ||||
| 	cmd.Env = append( | ||||
| 		cmd.Env, | ||||
| 		"GOOS="+system, | ||||
| 		"GOARCH="+arch, | ||||
| 		"GOOS="+goos, | ||||
| 		"GOARCH="+goarch, | ||||
| 		"GOROOT="+os.Getenv("GOROOT"), | ||||
| 		"GOPATH="+os.Getenv("GOPATH"), | ||||
| 	) | ||||
|   | ||||
							
								
								
									
										46
									
								
								pipeline/build/name.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								pipeline/build/name.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| package build | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"text/template" | ||||
|  | ||||
| 	"github.com/goreleaser/releaser/context" | ||||
| ) | ||||
|  | ||||
| type nameData struct { | ||||
| 	Os         string | ||||
| 	Arch       string | ||||
| 	Version    string | ||||
| 	BinaryName string | ||||
| } | ||||
|  | ||||
| func nameFor(ctx *context.Context, goos, goarch string) (string, error) { | ||||
| 	var data = nameData{ | ||||
| 		Os:         replace(ctx.Config.Archive.Replacements, goos), | ||||
| 		Arch:       replace(ctx.Config.Archive.Replacements, goarch), | ||||
| 		Version:    ctx.Git.CurrentTag, | ||||
| 		BinaryName: ctx.Config.BinaryName, | ||||
| 	} | ||||
| 	var out bytes.Buffer | ||||
| 	t, err := template.New(data.BinaryName).Parse(ctx.Config.Archive.NameTemplate) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	err = t.Execute(&out, data) | ||||
| 	return out.String(), err | ||||
| } | ||||
|  | ||||
| func replace(replacements map[string]string, original string) string { | ||||
| 	result := replacements[original] | ||||
| 	if result == "" { | ||||
| 		return original | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| func extFor(goos string) string { | ||||
| 	if goos == "windows" { | ||||
| 		return ".exe" | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
							
								
								
									
										42
									
								
								pipeline/build/name_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								pipeline/build/name_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| package build | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/goreleaser/releaser/config" | ||||
| 	"github.com/goreleaser/releaser/context" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestExtWindows(t *testing.T) { | ||||
| 	assert.Equal(t, extFor("windows"), ".exe") | ||||
| } | ||||
|  | ||||
| func TestExtOthers(t *testing.T) { | ||||
| 	assert.Empty(t, extFor("linux")) | ||||
| } | ||||
|  | ||||
| func TestNameFor(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	var config = &config.ProjectConfig{ | ||||
| 		BinaryName: "test", | ||||
| 		Archive: config.ArchiveConfig{ | ||||
| 			NameTemplate: "{{.BinaryName}}_{{.Os}}_{{.Arch}}_{{.Version}}", | ||||
| 			Replacements: map[string]string{ | ||||
| 				"darwin": "Darwin", | ||||
| 				"amd64":  "x86_64", | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	var ctx = &context.Context{ | ||||
| 		Config: config, | ||||
| 		Git: &context.GitInfo{ | ||||
| 			CurrentTag: "v1.2.3", | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	name, err := nameFor(ctx, "darwin", "amd64") | ||||
| 	assert.NoError(err) | ||||
| 	assert.Equal("test_Darwin_x86_64_v1.2.3", name) | ||||
| } | ||||
| @@ -1,10 +1,12 @@ | ||||
| package compress | ||||
|  | ||||
| import ( | ||||
| 	"io/ioutil" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
|  | ||||
| 	"github.com/goreleaser/releaser/config" | ||||
| 	"github.com/goreleaser/releaser/context" | ||||
| 	"github.com/goreleaser/releaser/pipeline/compress/tar" | ||||
| 	"github.com/goreleaser/releaser/pipeline/compress/zip" | ||||
| 	"golang.org/x/sync/errgroup" | ||||
| @@ -14,21 +16,18 @@ import ( | ||||
| type Pipe struct{} | ||||
|  | ||||
| // Name of the pipe | ||||
| func (Pipe) Name() string { | ||||
| 	return "Compress" | ||||
| func (Pipe) Description() string { | ||||
| 	return "Creating archives..." | ||||
| } | ||||
|  | ||||
| // Run the pipe | ||||
| func (Pipe) Run(config config.ProjectConfig) error { | ||||
| func (Pipe) Run(ctx *context.Context) error { | ||||
| 	var g errgroup.Group | ||||
| 	for _, system := range config.Build.Oses { | ||||
| 		for _, arch := range config.Build.Arches { | ||||
| 			system := system | ||||
| 			arch := arch | ||||
| 			g.Go(func() error { | ||||
| 				return create(system, arch, config) | ||||
| 			}) | ||||
| 		} | ||||
| 	for _, archive := range ctx.Archives { | ||||
| 		archive := archive | ||||
| 		g.Go(func() error { | ||||
| 			return create(archive, ctx) | ||||
| 		}) | ||||
| 	} | ||||
| 	return g.Wait() | ||||
| } | ||||
| @@ -38,25 +37,31 @@ type Archive interface { | ||||
| 	Add(name, path string) error | ||||
| } | ||||
|  | ||||
| func create(system, arch string, config config.ProjectConfig) error { | ||||
| 	name, err := config.ArchiveName(system, arch) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	file, err := os.Create("dist/" + name + "." + config.Archive.Format) | ||||
| 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(), "...") | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer func() { _ = file.Close() }() | ||||
| 	var archive = archiveFor(file, config.Archive.Format) | ||||
| 	var archive = archiveFor(file, ctx.Config.Archive.Format) | ||||
| 	defer func() { _ = archive.Close() }() | ||||
| 	for _, f := range config.Files { | ||||
| 		if err := archive.Add(f, f); err != nil { | ||||
| 	for _, f := range ctx.Config.Files { | ||||
| 		if err = archive.Add(f, f); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return archive.Add(config.BinaryName+extFor(system), "dist/"+name+"/"+config.BinaryName) | ||||
| 	files, err := ioutil.ReadDir(folder) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	for _, f := range files { | ||||
| 		if err := archive.Add(f.Name(), filepath.Join(folder, f.Name())); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func archiveFor(file *os.File, format string) Archive { | ||||
| @@ -65,10 +70,3 @@ func archiveFor(file *os.File, format string) Archive { | ||||
| 	} | ||||
| 	return tar.New(file) | ||||
| } | ||||
|  | ||||
| func extFor(system string) string { | ||||
| 	if system == "windows" { | ||||
| 		return ".exe" | ||||
| 	} | ||||
| 	return "" | ||||
| } | ||||
|   | ||||
| @@ -1,15 +0,0 @@ | ||||
| package compress | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestExtWindows(t *testing.T) { | ||||
| 	assert.Equal(t, extFor("windows"), ".exe") | ||||
| } | ||||
|  | ||||
| func TestExtOthers(t *testing.T) { | ||||
| 	assert.Empty(t, extFor("linux")) | ||||
| } | ||||
							
								
								
									
										83
									
								
								pipeline/defaults/defaults.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								pipeline/defaults/defaults.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| package defaults | ||||
|  | ||||
| import ( | ||||
| 	"io/ioutil" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/goreleaser/releaser/context" | ||||
| ) | ||||
|  | ||||
| var defaultFiles = []string{"licence", "license", "readme", "changelog"} | ||||
|  | ||||
| // Pipe for brew deployment | ||||
| type Pipe struct{} | ||||
|  | ||||
| // Name of the pipe | ||||
| func (Pipe) Description() string { | ||||
| 	return "Setting defaults..." | ||||
| } | ||||
|  | ||||
| // Run the pipe | ||||
| func (Pipe) Run(ctx *context.Context) (err error) { | ||||
| 	if ctx.Config.Build.Main == "" { | ||||
| 		ctx.Config.Build.Main = "main.go" | ||||
| 	} | ||||
| 	if len(ctx.Config.Build.Oses) == 0 { | ||||
| 		ctx.Config.Build.Oses = []string{"linux", "darwin"} | ||||
| 	} | ||||
| 	if len(ctx.Config.Build.Arches) == 0 { | ||||
| 		ctx.Config.Build.Arches = []string{"amd64", "386"} | ||||
| 	} | ||||
| 	if ctx.Config.Build.Ldflags == "" { | ||||
| 		ctx.Config.Build.Ldflags = "-s -w" | ||||
| 	} | ||||
| 	if ctx.Config.Archive.NameTemplate == "" { | ||||
| 		ctx.Config.Archive.NameTemplate = "{{.BinaryName}}_{{.Os}}_{{.Arch}}" | ||||
| 	} | ||||
| 	if ctx.Config.Archive.Format == "" { | ||||
| 		ctx.Config.Archive.Format = "tar.gz" | ||||
| 	} | ||||
| 	if len(ctx.Config.Archive.Replacements) == 0 { | ||||
| 		ctx.Config.Archive.Replacements = map[string]string{ | ||||
| 			"darwin":  "Darwin", | ||||
| 			"linux":   "Linux", | ||||
| 			"freebsd": "FreeBSD", | ||||
| 			"openbsd": "OpenBSD", | ||||
| 			"netbsd":  "NetBSD", | ||||
| 			"windows": "Windows", | ||||
| 			"386":     "i386", | ||||
| 			"amd64":   "x86_64", | ||||
| 		} | ||||
| 	} | ||||
| 	if len(ctx.Config.Files) != 0 { | ||||
| 		return | ||||
| 	} | ||||
| 	files, err := findFiles() | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	ctx.Config.Files = files | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func findFiles() (files []string, err error) { | ||||
| 	all, err := ioutil.ReadDir(".") | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	for _, file := range all { | ||||
| 		if accept(file.Name()) { | ||||
| 			files = append(files, file.Name()) | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func accept(file string) bool { | ||||
| 	for _, accepted := range defaultFiles { | ||||
| 		if strings.HasPrefix(strings.ToLower(file), accepted) { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
							
								
								
									
										69
									
								
								pipeline/defaults/defaults_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								pipeline/defaults/defaults_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | ||||
| package defaults | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/goreleaser/releaser/config" | ||||
| 	"github.com/goreleaser/releaser/context" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestFillBasicData(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	var config = &config.ProjectConfig{} | ||||
| 	var ctx = &context.Context{ | ||||
| 		Config: config, | ||||
| 	} | ||||
|  | ||||
| 	assert.NoError(Pipe{}.Run(ctx)) | ||||
|  | ||||
| 	assert.Equal("main.go", config.Build.Main) | ||||
| 	assert.Equal("tar.gz", config.Archive.Format) | ||||
| 	assert.Contains(config.Build.Oses, "darwin") | ||||
| 	assert.Contains(config.Build.Oses, "linux") | ||||
| 	assert.Contains(config.Build.Arches, "386") | ||||
| 	assert.Contains(config.Build.Arches, "amd64") | ||||
| 	assert.NotEmpty( | ||||
| 		config.Archive.Replacements, | ||||
| 		config.Archive.NameTemplate, | ||||
| 		config.Build.Ldflags, | ||||
| 		config.Files, | ||||
| 	) | ||||
| } | ||||
|  | ||||
| func TestFilesFilled(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	var config = &config.ProjectConfig{ | ||||
| 		Files: []string{ | ||||
| 			"README.md", | ||||
| 		}, | ||||
| 	} | ||||
| 	var ctx = &context.Context{ | ||||
| 		Config: config, | ||||
| 	} | ||||
|  | ||||
| 	assert.NoError(Pipe{}.Run(ctx)) | ||||
| 	assert.Len(config.Files, 1) | ||||
| } | ||||
|  | ||||
| func TestAcceptFiles(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
|  | ||||
| 	var files = []string{ | ||||
| 		"LICENSE.md", | ||||
| 		"LIceNSE.txt", | ||||
| 		"LICENSE", | ||||
| 		"LICENCE.txt", | ||||
| 		"LICEncE", | ||||
| 		"README", | ||||
| 		"READme.md", | ||||
| 		"CHANGELOG.txt", | ||||
| 		"ChanGELOG.md", | ||||
| 	} | ||||
|  | ||||
| 	for _, file := range files { | ||||
| 		assert.True(accept(file)) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										28
									
								
								pipeline/env/env.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								pipeline/env/env.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| package env | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"os" | ||||
|  | ||||
| 	"github.com/goreleaser/releaser/context" | ||||
| ) | ||||
|  | ||||
| var ErrMissingToken = errors.New("Missing GITHUB_TOKEN") | ||||
|  | ||||
| // Pipe for env | ||||
| type Pipe struct{} | ||||
|  | ||||
| // Name of the pipe | ||||
| func (Pipe) Description() string { | ||||
| 	return "Loading data from environment variables..." | ||||
| } | ||||
|  | ||||
| // Run the pipe | ||||
| func (Pipe) Run(ctx *context.Context) (err error) { | ||||
| 	token := os.Getenv("GITHUB_TOKEN") | ||||
| 	if token == "" { | ||||
| 		return ErrMissingToken | ||||
| 	} | ||||
| 	ctx.Token = &token | ||||
| 	return | ||||
| } | ||||
							
								
								
									
										34
									
								
								pipeline/git/git.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								pipeline/git/git.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| package git | ||||
|  | ||||
| import "github.com/goreleaser/releaser/context" | ||||
|  | ||||
| // Pipe for brew deployment | ||||
| type Pipe struct{} | ||||
|  | ||||
| // Name of the pipe | ||||
| func (Pipe) Description() string { | ||||
| 	return "Gathering Git data..." | ||||
| } | ||||
|  | ||||
| // Run the pipe | ||||
| func (Pipe) Run(ctx *context.Context) (err error) { | ||||
| 	tag, err := currentTag() | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	previous, err := previousTag(tag) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	log, err := log(previous, tag) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	ctx.Git = &context.GitInfo{ | ||||
| 		CurrentTag:  tag, | ||||
| 		PreviousTag: previous, | ||||
| 		Diff:        log, | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| @@ -2,8 +2,7 @@ package git | ||||
| 
 | ||||
| import "os/exec" | ||||
| 
 | ||||
| // Log between two tags | ||||
| func Log(previous, current string) (str string, err error) { | ||||
| func log(previous, current string) (str string, err error) { | ||||
| 	cmd := exec.Command( | ||||
| 		"git", | ||||
| 		"log", | ||||
| @@ -8,14 +8,14 @@ import ( | ||||
| 
 | ||||
| func TestLog(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	log, err := Log("v0.1.9", "v0.2.0") | ||||
| 	log, err := log("v0.1.9", "v0.2.0") | ||||
| 	assert.NoError(err) | ||||
| 	assert.NotEmpty(log) | ||||
| } | ||||
| 
 | ||||
| func TestLogInvalidRef(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	log, err := Log("wtfff", "nope") | ||||
| 	log, err := log("wtfff", "nope") | ||||
| 	assert.Error(err) | ||||
| 	assert.Empty(log) | ||||
| } | ||||
| @@ -6,13 +6,11 @@ import ( | ||||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| // CurrentTag tag being built | ||||
| func CurrentTag() (tag string, err error) { | ||||
| func currentTag() (tag string, err error) { | ||||
| 	return getTag("") | ||||
| } | ||||
| 
 | ||||
| // PreviousTag previous tag of the base tag | ||||
| func PreviousTag(base string) (tag string, err error) { | ||||
| func previousTag(base string) (tag string, err error) { | ||||
| 	return getTag(base + "^") | ||||
| } | ||||
| 
 | ||||
| @@ -8,21 +8,21 @@ import ( | ||||
| 
 | ||||
| func TestCurrentTag(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tag, err := CurrentTag() | ||||
| 	tag, err := currentTag() | ||||
| 	assert.NoError(err) | ||||
| 	assert.NotEmpty(tag) | ||||
| } | ||||
| 
 | ||||
| func TestPreviousTag(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tag, err := PreviousTag("v0.2.0") | ||||
| 	tag, err := previousTag("v0.2.0") | ||||
| 	assert.NoError(err) | ||||
| 	assert.NotEmpty(tag) | ||||
| } | ||||
| 
 | ||||
| func TestInvalidRef(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	tag, err := PreviousTag("this-should-not-exist") | ||||
| 	tag, err := previousTag("this-should-not-exist") | ||||
| 	assert.Error(err) | ||||
| 	assert.Empty(tag) | ||||
| } | ||||
| @@ -1,12 +1,12 @@ | ||||
| package pipeline | ||||
|  | ||||
| import "github.com/goreleaser/releaser/config" | ||||
| import "github.com/goreleaser/releaser/context" | ||||
|  | ||||
| // Pipe interface | ||||
| type Pipe interface { | ||||
| 	// Name of the pipe | ||||
| 	Name() string | ||||
| 	Description() string | ||||
|  | ||||
| 	// Run the pipe | ||||
| 	Run(config config.ProjectConfig) error | ||||
| 	Run(ctx *context.Context) error | ||||
| } | ||||
|   | ||||
| @@ -1,15 +1,13 @@ | ||||
| package release | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
|  | ||||
| 	"github.com/google/go-github/github" | ||||
| 	"github.com/goreleaser/releaser/config" | ||||
| 	"github.com/goreleaser/releaser/split" | ||||
| 	"golang.org/x/oauth2" | ||||
| 	"github.com/goreleaser/releaser/clients" | ||||
| 	"github.com/goreleaser/releaser/context" | ||||
| 	"golang.org/x/sync/errgroup" | ||||
| ) | ||||
|  | ||||
| @@ -17,49 +15,44 @@ import ( | ||||
| type Pipe struct{} | ||||
|  | ||||
| // Name of the pipe | ||||
| func (Pipe) Name() string { | ||||
| 	return "GithubRelease" | ||||
| func (Pipe) Description() string { | ||||
| 	return "Releasing to GitHub..." | ||||
| } | ||||
|  | ||||
| // Run the pipe | ||||
| func (Pipe) Run(config config.ProjectConfig) error { | ||||
| 	ts := oauth2.StaticTokenSource( | ||||
| 		&oauth2.Token{AccessToken: config.Token}, | ||||
| 	) | ||||
| 	tc := oauth2.NewClient(context.Background(), ts) | ||||
| 	client := github.NewClient(tc) | ||||
| func (Pipe) Run(ctx *context.Context) error { | ||||
| 	client := clients.Github(*ctx.Token) | ||||
|  | ||||
| 	r, err := getOrCreateRelease(client, config) | ||||
| 	r, err := getOrCreateRelease(client, ctx) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	var g errgroup.Group | ||||
| 	for _, system := range config.Build.Oses { | ||||
| 		for _, arch := range config.Build.Arches { | ||||
| 			system := system | ||||
| 			arch := arch | ||||
| 			g.Go(func() error { | ||||
| 				return upload(client, *r.ID, system, arch, config) | ||||
| 			}) | ||||
| 		} | ||||
| 	for _, archive := range ctx.Archives { | ||||
| 		archive := archive | ||||
| 		g.Go(func() error { | ||||
| 			return upload(client, *r.ID, archive, ctx) | ||||
| 		}) | ||||
|  | ||||
| 	} | ||||
| 	return g.Wait() | ||||
| } | ||||
|  | ||||
| func getOrCreateRelease(client *github.Client, config config.ProjectConfig) (*github.RepositoryRelease, error) { | ||||
| 	owner, repo := split.OnSlash(config.Repo) | ||||
| func getOrCreateRelease(client *github.Client, ctx *context.Context) (*github.RepositoryRelease, error) { | ||||
| 	owner := ctx.Repo.Owner | ||||
| 	repo := ctx.Repo.Name | ||||
| 	data := &github.RepositoryRelease{ | ||||
| 		Name:    github.String(config.Git.CurrentTag), | ||||
| 		TagName: github.String(config.Git.CurrentTag), | ||||
| 		Body:    github.String(description(config.Git.Diff)), | ||||
| 		Name:    github.String(ctx.Git.CurrentTag), | ||||
| 		TagName: github.String(ctx.Git.CurrentTag), | ||||
| 		Body:    github.String(description(ctx.Git.Diff)), | ||||
| 	} | ||||
| 	r, res, err := client.Repositories.GetReleaseByTag(owner, repo, config.Git.CurrentTag) | ||||
| 	if err != nil && res.StatusCode == 404 { | ||||
| 		log.Println("Creating release", config.Git.CurrentTag, "on", config.Repo, "...") | ||||
| 	r, _, err := client.Repositories.GetReleaseByTag(owner, repo, ctx.Git.CurrentTag) | ||||
| 	if err != nil { | ||||
| 		log.Println("Creating release", ctx.Git.CurrentTag, "on", ctx.Config.Repo, "...") | ||||
| 		r, _, err = client.Repositories.CreateRelease(owner, repo, data) | ||||
| 		return r, err | ||||
| 	} | ||||
| 	log.Println("Updating existing release", config.Git.CurrentTag, "on", config.Repo, "...") | ||||
| 	log.Println("Updating existing release", ctx.Git.CurrentTag, "on", ctx.Config.Repo, "...") | ||||
| 	r, _, err = client.Repositories.EditRelease(owner, repo, *r.ID, data) | ||||
| 	return r, err | ||||
| } | ||||
| @@ -74,26 +67,19 @@ func description(diff string) string { | ||||
| 	return result + "\nBuilt with " + string(bts) | ||||
| } | ||||
|  | ||||
| func upload(client *github.Client, releaseID int, system, arch string, config config.ProjectConfig) error { | ||||
| 	owner, repo := split.OnSlash(config.Repo) | ||||
| 	name, err := config.ArchiveName(system, arch) | ||||
| func upload(client *github.Client, releaseID int, archive string, ctx *context.Context) error { | ||||
| 	archive = archive + "." + ctx.Config.Archive.Format | ||||
| 	file, err := os.Open("dist/" + archive) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	name = name + "." + config.Archive.Format | ||||
| 	file, err := os.Open("dist/" + name) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer func() { | ||||
| 		_ = file.Close() | ||||
| 	}() | ||||
| 	defer func() { _ = file.Close() }() | ||||
| 	log.Println("Uploading", file.Name(), "...") | ||||
| 	_, _, err = client.Repositories.UploadReleaseAsset( | ||||
| 		owner, | ||||
| 		repo, | ||||
| 		ctx.Repo.Owner, | ||||
| 		ctx.Repo.Name, | ||||
| 		releaseID, | ||||
| 		&github.UploadOptions{Name: name}, | ||||
| 		&github.UploadOptions{Name: archive}, | ||||
| 		file, | ||||
| 	) | ||||
| 	return err | ||||
|   | ||||
							
								
								
									
										35
									
								
								pipeline/repos/repos.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								pipeline/repos/repos.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| package repos | ||||
|  | ||||
| import ( | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/goreleaser/releaser/context" | ||||
| ) | ||||
|  | ||||
| // Pipe for brew deployment | ||||
| type Pipe struct{} | ||||
|  | ||||
| // Name of the pipe | ||||
| func (Pipe) Description() string { | ||||
| 	return "Filling repositories data..." | ||||
| } | ||||
|  | ||||
| // Run the pipe | ||||
| func (Pipe) Run(ctx *context.Context) (err error) { | ||||
| 	owner, name := split(ctx.Config.Repo) | ||||
| 	ctx.Repo = &context.Repo{ | ||||
| 		Owner: owner, | ||||
| 		Name:  name, | ||||
| 	} | ||||
| 	owner, name = split(ctx.Config.Brew.Repo) | ||||
| 	ctx.BrewRepo = &context.Repo{ | ||||
| 		Owner: owner, | ||||
| 		Name:  name, | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func split(pair string) (string, string) { | ||||
| 	parts := strings.Split(pair, "/") | ||||
| 	return parts[0], parts[1] | ||||
| } | ||||
| @@ -1,4 +1,4 @@ | ||||
| package split | ||||
| package repos | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| @@ -8,7 +8,7 @@ import ( | ||||
| 
 | ||||
| func TestSplit(t *testing.T) { | ||||
| 	assert := assert.New(t) | ||||
| 	a, b := OnSlash("a/b") | ||||
| 	a, b := split("a/b") | ||||
| 	assert.Equal("a", a) | ||||
| 	assert.Equal("b", b) | ||||
| } | ||||
							
								
								
									
										26
									
								
								pipeline/valid/valid.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								pipeline/valid/valid.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| package valid | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
|  | ||||
| 	"github.com/goreleaser/releaser/context" | ||||
| ) | ||||
|  | ||||
| // Pipe for brew deployment | ||||
| type Pipe struct{} | ||||
|  | ||||
| // Name of the pipe | ||||
| func (Pipe) Description() string { | ||||
| 	return "Validating configuration..." | ||||
| } | ||||
|  | ||||
| // Run the pipe | ||||
| func (Pipe) Run(ctx *context.Context) (err error) { | ||||
| 	if ctx.Config.BinaryName == "" { | ||||
| 		return errors.New("missing binary_name") | ||||
| 	} | ||||
| 	if ctx.Config.Repo == "" { | ||||
| 		return errors.New("missing repo") | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
							
								
								
									
										32
									
								
								pipeline/valid/valid_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								pipeline/valid/valid_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| package valid | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/goreleaser/releaser/config" | ||||
| 	"github.com/goreleaser/releaser/context" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func runPipe(repo, bin string) error { | ||||
| 	var config = &config.ProjectConfig{ | ||||
| 		Repo:       repo, | ||||
| 		BinaryName: bin, | ||||
| 	} | ||||
| 	var ctx = &context.Context{ | ||||
| 		Config: config, | ||||
| 	} | ||||
| 	return Pipe{}.Run(ctx) | ||||
| } | ||||
|  | ||||
| func TestValidadeMissingBinaryName(t *testing.T) { | ||||
| 	assert.Error(t, runPipe("a/b", "")) | ||||
| } | ||||
|  | ||||
| func TestValidadeMissingRepo(t *testing.T) { | ||||
| 	assert.Error(t, runPipe("", "a")) | ||||
| } | ||||
|  | ||||
| func TestValidadeMinimalConfig(t *testing.T) { | ||||
| 	assert.NoError(t, runPipe("a/b", "a")) | ||||
| } | ||||
| @@ -1,9 +0,0 @@ | ||||
| package split | ||||
|  | ||||
| import "strings" | ||||
|  | ||||
| // OnSlash split a string on / and return the first 2 parts | ||||
| func OnSlash(pair string) (string, string) { | ||||
| 	parts := strings.Split(pair, "/") | ||||
| 	return parts[0], parts[1] | ||||
| } | ||||
		Reference in New Issue
	
	Block a user