You've already forked goreleaser
mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-09-16 09:26:52 +02:00
Merge branch 'master' into name-template
This commit is contained in:
12
README.md
12
README.md
@@ -5,7 +5,6 @@ Deliver Go binaries as fast and easily as possible.
|
||||
GoReleaser builds Go binaries for several platforms, creates a github release and then
|
||||
push a homebrew formulae to a repository. All that wrapped in your favorite CI.
|
||||
|
||||
|
||||
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md).
|
||||
By participating, you are expected to uphold this code. Please report unacceptable behavior to root@carlosbecker.com.
|
||||
|
||||
@@ -19,14 +18,19 @@ So, the all-new goreleaser was born.
|
||||
|
||||
## Usage
|
||||
|
||||
Basically, you need to create a `goreleaser.yml` file in the root of your
|
||||
repository. A minimal config would look like this:
|
||||
Create a `goreleaser.yml` file in the root of your repository. A minimal config would look like this:
|
||||
|
||||
```yaml
|
||||
repo: user/repo
|
||||
binary_name: my-binary
|
||||
```
|
||||
|
||||
You may then run releaser at the root of your repository:
|
||||
|
||||
```sh
|
||||
curl -s https://raw.githubusercontent.com/goreleaser/get/master/latest | bash
|
||||
```
|
||||
|
||||
This will build `main.go` file as `my-binary`, for _Darwin_ and _Linux_,
|
||||
_x86_64_ and _i386_, packaging the binary, `LICENSE.md` and `README.md`
|
||||
and publish a new github release in the `user/repo` repository with
|
||||
@@ -97,7 +101,7 @@ after_success:
|
||||
test -n "$TRAVIS_TAG" && curl -s https://raw.githubusercontent.com/goreleaser/get/master/latest | bash
|
||||
```
|
||||
|
||||
## How the end result looks like
|
||||
## What the end result looks like
|
||||
|
||||
The release on github looks pretty much like this:
|
||||
|
||||
|
@@ -34,6 +34,11 @@ type GitInfo struct {
|
||||
Diff string
|
||||
}
|
||||
|
||||
// ArchiveConfig
|
||||
type ArchiveConfig struct {
|
||||
Format string
|
||||
}
|
||||
|
||||
// ProjectConfig includes all project configuration
|
||||
type ProjectConfig struct {
|
||||
Repo string
|
||||
@@ -44,6 +49,7 @@ type ProjectConfig struct {
|
||||
Build BuildConfig
|
||||
Git GitInfo `yaml:"-"`
|
||||
NameTemplate string `yaml:"name_template"`
|
||||
Archive ArchiveConfig
|
||||
}
|
||||
|
||||
// Load config file
|
||||
@@ -109,6 +115,9 @@ func (config *ProjectConfig) fillBasicData() {
|
||||
}
|
||||
if config.NameTemplate == "" {
|
||||
config.NameTemplate = "{{.BinaryName}}_{{.Os}}_{{.Arch}}"
|
||||
}
|
||||
if config.Archive.Format == "" {
|
||||
config.Archive.Format = "tar.gz"
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -13,6 +13,7 @@ func TestFillBasicData(t *testing.T) {
|
||||
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")
|
||||
|
@@ -19,7 +19,7 @@ import (
|
||||
const formulae = `class {{ .Name }} < Formula
|
||||
desc "{{ .Desc }}"
|
||||
homepage "{{ .Homepage }}"
|
||||
url "https://github.com/{{ .Repo }}/releases/download/{{ .Tag }}/{{ .File }}.tar.gz"
|
||||
url "https://github.com/{{ .Repo }}/releases/download/{{ .Tag }}/{{ .File }}.{{ .Format }}"
|
||||
head "https://github.com/{{ .Repo }}.git"
|
||||
version "{{ .Tag }}"
|
||||
|
||||
@@ -37,7 +37,7 @@ end
|
||||
`
|
||||
|
||||
type templateData struct {
|
||||
Name, Desc, Homepage, Repo, Tag, BinaryName, Caveats, File string
|
||||
Name, Desc, Homepage, Repo, Tag, BinaryName, Caveats, File, Format string
|
||||
}
|
||||
|
||||
// Pipe for brew deployment
|
||||
@@ -92,7 +92,7 @@ func sha(client *github.Client, owner, repo, name string, out bytes.Buffer) (*st
|
||||
if err == nil {
|
||||
return file.SHA, err
|
||||
}
|
||||
return github.String(fmt.Sprintf("%s", sha256.Sum256(out.Bytes()))), err
|
||||
return github.String(fmt.Sprintf("%s", sha256.Sum256(out.Bytes()))), nil
|
||||
}
|
||||
|
||||
func buildFormulae(config config.ProjectConfig, client *github.Client) (bytes.Buffer, error) {
|
||||
@@ -144,6 +144,7 @@ func dataFor(config config.ProjectConfig, client *github.Client) (result templat
|
||||
BinaryName: config.BinaryName,
|
||||
Caveats: config.Brew.Caveats,
|
||||
File: file,
|
||||
Format: config.Archive.Format,
|
||||
}, err
|
||||
}
|
||||
|
||||
|
@@ -27,6 +27,7 @@ var defaultTemplateData = templateData{
|
||||
Repo: "caarlos0/test",
|
||||
Tag: "v0.1.3",
|
||||
File: "test_#{%x(uname -s).gsub(/\\n/, '')}_#{%x(uname -m).gsub(/\\n/, '')}",
|
||||
Format: "tar.gz",
|
||||
}
|
||||
|
||||
func assertDefaultTemplateData(t *testing.T, formulae string) {
|
||||
|
@@ -1,14 +1,14 @@
|
||||
package compress
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/goreleaser/releaser/config"
|
||||
"github.com/goreleaser/releaser/name"
|
||||
"github.com/goreleaser/releaser/pipeline/compress/tar"
|
||||
"github.com/goreleaser/releaser/pipeline/compress/zip"
|
||||
"github.com/goreleaser/releaser/uname"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
@@ -35,55 +35,37 @@ func (Pipe) Run(config config.ProjectConfig) error {
|
||||
return g.Wait()
|
||||
}
|
||||
|
||||
type Archive interface {
|
||||
Close() error
|
||||
Add(name, path string) error
|
||||
}
|
||||
|
||||
func create(system, arch string, config config.ProjectConfig) error {
|
||||
name, err := name.For(config, system, arch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
file, err := os.Create("dist/" + name + ".tar.gz")
|
||||
file, err := os.Create("dist/" + name + "." + config.Archive.Format)
|
||||
log.Println("Creating", file.Name(), "...")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gw := gzip.NewWriter(file)
|
||||
tw := tar.NewWriter(gw)
|
||||
defer func() {
|
||||
_ = tw.Close()
|
||||
_ = gw.Close()
|
||||
_ = file.Close()
|
||||
}()
|
||||
defer func() { _ = file.Close() }()
|
||||
var archive = archiveFor(file, config.Archive.Format)
|
||||
defer func() { _ = archive.Close() }()
|
||||
for _, f := range config.Files {
|
||||
if err := addFile(tw, f, f); err != nil {
|
||||
if err := archive.Add(f, f); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return addFile(tw, config.BinaryName+extFor(system), "dist/"+name+"/"+config.BinaryName)
|
||||
}
|
||||
|
||||
func addFile(tw *tar.Writer, name, path string) (err error) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return
|
||||
func archiveFor(file *os.File, format string) Archive {
|
||||
if format == "zip" {
|
||||
return zip.New(file)
|
||||
}
|
||||
defer func() {
|
||||
_ = file.Close()
|
||||
}()
|
||||
stat, err := file.Stat()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
header := new(tar.Header)
|
||||
header.Name = name
|
||||
header.Size = stat.Size()
|
||||
header.Mode = int64(stat.Mode())
|
||||
header.ModTime = stat.ModTime()
|
||||
if err := tw.WriteHeader(header); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.Copy(tw, file); err != nil {
|
||||
return err
|
||||
}
|
||||
return
|
||||
return tar.New(file)
|
||||
}
|
||||
|
||||
func extFor(system string) string {
|
||||
|
58
pipeline/compress/tar/tar.go
Normal file
58
pipeline/compress/tar/tar.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package tar
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Archive struct {
|
||||
gw *gzip.Writer
|
||||
tw *tar.Writer
|
||||
}
|
||||
|
||||
func (a Archive) Close() error {
|
||||
if err := a.tw.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := a.gw.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func New(target *os.File) Archive {
|
||||
gw := gzip.NewWriter(target)
|
||||
tw := tar.NewWriter(gw)
|
||||
return Archive{
|
||||
gw: gw,
|
||||
tw: tw,
|
||||
}
|
||||
}
|
||||
|
||||
func (a Archive) Add(name, path string) (err error) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
_ = file.Close()
|
||||
}()
|
||||
stat, err := file.Stat()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
header := new(tar.Header)
|
||||
header.Name = name
|
||||
header.Size = stat.Size()
|
||||
header.Mode = int64(stat.Mode())
|
||||
header.ModTime = stat.ModTime()
|
||||
if err := a.tw.WriteHeader(header); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.Copy(a.tw, file); err != nil {
|
||||
return err
|
||||
}
|
||||
return
|
||||
}
|
35
pipeline/compress/zip/zip.go
Normal file
35
pipeline/compress/zip/zip.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package zip
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Archive struct {
|
||||
z *zip.Writer
|
||||
}
|
||||
|
||||
func (a Archive) Close() error {
|
||||
return a.z.Close()
|
||||
}
|
||||
|
||||
func New(target *os.File) Archive {
|
||||
return Archive{
|
||||
z: zip.NewWriter(target),
|
||||
}
|
||||
}
|
||||
|
||||
func (a Archive) Add(name, path string) (err error) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer func() { _ = file.Close() }()
|
||||
f, err := a.z.Create(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = io.Copy(f, file)
|
||||
return err
|
||||
}
|
@@ -46,11 +46,7 @@ func (Pipe) Run(config config.ProjectConfig) error {
|
||||
system := system
|
||||
arch := arch
|
||||
g.Go(func() error {
|
||||
name, err := name.For(config, system, arch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return upload(client, *r.ID, owner, repo, name+".tar.gz")
|
||||
return upload(client, *r.ID, system, arch, config)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -67,7 +63,13 @@ func description(diff string) string {
|
||||
return result + "\nBuilt with " + string(bts)
|
||||
}
|
||||
|
||||
func upload(client *github.Client, releaseID int, owner, repo, name string) error {
|
||||
func upload(client *github.Client, releaseID int, system, arch string, config config.ProjectConfig) error {
|
||||
owner, repo := split.OnSlash(config.Repo)
|
||||
name, err := name.For(config, system, arch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name = name + "." + config.Archive.Format
|
||||
file, err := os.Open("dist/" + name)
|
||||
if err != nil {
|
||||
return err
|
||||
|
Reference in New Issue
Block a user