Skip to content
Permalink
Browse files

feat: upload to s3

  • Loading branch information...
caarlos0 committed May 13, 2018
1 parent 58d8ac6 commit 1c426847d9ac8f8cc161153e46f72f9e322e19da
@@ -23,12 +23,12 @@ changelog:
- '^test:'
- Merge pull request
- Merge branch
dockers:
- image: goreleaser/goreleaser
tag_templates:
- '{{ .Tag }}'
- 'v{{ .Major }}.{{ .Minor }}'
- 'latest'
# dockers:
# - image: goreleaser/goreleaser
# tag_templates:
# - '{{ .Tag }}'
# - 'v{{ .Major }}.{{ .Minor }}'
# - 'latest'
archive:
name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
replacements:
@@ -79,3 +79,6 @@ snapcraft:
wrapped in your favorite CI.
grade: stable
confinement: classic
s3:
- bucket: goreleaser

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
@@ -53,3 +53,7 @@
[[constraint]]
name = "github.com/alecthomas/kingpin"
version = "~2.2.6"

[[constraint]]
name = "github.com/aws/aws-sdk-go"
version = "1.13.47"
@@ -244,6 +244,13 @@ type Before struct {
Hooks []string `yaml:",omitempty"`
}

// S3 contains s3 config
type S3 struct {
Region string
Bucket string
Folder string
}

// Project includes all project configuration
type Project struct {
ProjectName string `yaml:"project_name,omitempty"`
@@ -259,6 +266,7 @@ type Project struct {
Checksum Checksum `yaml:",omitempty"`
Dockers []Docker `yaml:",omitempty"`
Artifactories []Artifactory `yaml:",omitempty"`
S3 []S3 `yaml:"s3,omitempty"`
Changelog Changelog `yaml:",omitempty"`
Dist string `yaml:",omitempty"`
Sign Sign `yaml:",omitempty"`
@@ -9,6 +9,7 @@ import (
"github.com/google/go-github/github"
"github.com/goreleaser/goreleaser/config"
"github.com/goreleaser/goreleaser/context"
"github.com/goreleaser/goreleaser/internal/nametemplate"
"golang.org/x/oauth2"
)

@@ -89,7 +90,7 @@ func (c *githubClient) CreateFile(

func (c *githubClient) CreateRelease(ctx *context.Context, body string) (int64, error) {
var release *github.RepositoryRelease
title, err := releaseTitle(ctx)
title, err := nametemplate.Apply(ctx, "github", ctx.Config.Release.NameTemplate)
if err != nil {
return 0, err
}
@@ -1,4 +1,4 @@
package client
package nametemplate

import (
"bytes"
@@ -8,12 +8,12 @@ import (
"github.com/goreleaser/goreleaser/context"
)

func releaseTitle(ctx *context.Context) (string, error) {
func Apply(ctx *context.Context, name, tmpl string) (string, error) {
var out bytes.Buffer
t, err := template.New("github").
t, err := template.New(name).
Option("missingkey=error").
Funcs(mkFuncMap()).
Parse(ctx.Config.Release.NameTemplate)
Parse(tmpl)
if err != nil {
return "", err
}
@@ -1,4 +1,4 @@
package client
package nametemplate

import (
"testing"
@@ -29,8 +29,7 @@ func TestFuncMap(t *testing.T) {
Name: "MM/DD/YYYY",
},
} {
ctx.Config.Release.NameTemplate = tc.Template
out, err := releaseTitle(ctx)
out, err := Apply(ctx, "foo", tc.Template)
assert.NoError(t, err)
assert.NotEmpty(t, out)
}
@@ -31,6 +31,7 @@ import (
"github.com/goreleaser/goreleaser/pipeline/git"
"github.com/goreleaser/goreleaser/pipeline/nfpm"
"github.com/goreleaser/goreleaser/pipeline/release"
"github.com/goreleaser/goreleaser/pipeline/s3"
"github.com/goreleaser/goreleaser/pipeline/scoop"
"github.com/goreleaser/goreleaser/pipeline/sign"
"github.com/goreleaser/goreleaser/pipeline/snapcraft"
@@ -58,6 +59,7 @@ var pipes = []Piper{
sign.Pipe{}, // sign artifacts
docker.Pipe{}, // create and push docker images
artifactory.Pipe{}, // push to artifactory
s3.Pipe{}, // push to s3/minio
release.Pipe{}, // release to github
brew.Pipe{}, // push to brew tap
scoop.Pipe{}, // push to scoop bucket
@@ -18,6 +18,7 @@ import (
"github.com/goreleaser/goreleaser/pipeline/nfpm"
"github.com/goreleaser/goreleaser/pipeline/project"
"github.com/goreleaser/goreleaser/pipeline/release"
"github.com/goreleaser/goreleaser/pipeline/s3"
"github.com/goreleaser/goreleaser/pipeline/scoop"
"github.com/goreleaser/goreleaser/pipeline/sign"
"github.com/goreleaser/goreleaser/pipeline/snapcraft"
@@ -54,6 +55,7 @@ var defaulters = []Defaulter{
sign.Pipe{},
docker.Pipe{},
artifactory.Pipe{},
s3.Pipe{},
brew.Pipe{},
scoop.Pipe{},
}
@@ -0,0 +1,103 @@
// Package s3 provides a Pipe that push artifacts to s3/minio
package s3

import (
"os"
"path/filepath"

"github.com/apex/log"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/goreleaser/goreleaser/config"
"github.com/goreleaser/goreleaser/context"
"github.com/goreleaser/goreleaser/internal/artifact"
"github.com/goreleaser/goreleaser/internal/nametemplate"
"golang.org/x/sync/errgroup"
)

// Pipe for Artifactory
type Pipe struct{}

// String returns the description of the pipe
func (Pipe) String() string {
return "releasing to s3"
}

// Default sets the pipe defaults
func (Pipe) Default(ctx *context.Context) error {
for i := range ctx.Config.S3 {
s3 := &ctx.Config.S3[i]
if s3.Folder == "" {
s3.Folder = "{{ .ProjectName }}/{{ .Tag }}"
}
if s3.Region == "" {
s3.Region = "us-east-1"
}
}
return nil
}

// Run the pipe
func (Pipe) Run(ctx *context.Context) error {
var g errgroup.Group
sem := make(chan bool, ctx.Parallelism)
for _, conf := range ctx.Config.S3 {
conf := conf
sem <- true
g.Go(func() error {
defer func() {
<-sem
}()
return upload(ctx, conf)
})
}
return g.Wait()
}

func upload(ctx *context.Context, conf config.S3) error {
sess := session.Must(session.NewSession())
svc := s3.New(sess, &aws.Config{
Region: aws.String(conf.Region),
})
folder, err := nametemplate.Apply(ctx, "s3", conf.Folder)
if err != nil {
return err
}

var g errgroup.Group
sem := make(chan bool, ctx.Parallelism)
for _, artifact := range ctx.Artifacts.Filter(
artifact.Or(
artifact.ByType(artifact.UploadableArchive),
artifact.ByType(artifact.UploadableBinary),
artifact.ByType(artifact.Checksum),
artifact.ByType(artifact.Signature),
artifact.ByType(artifact.LinuxPackage),
),
).List() {
sem <- true
artifact := artifact
g.Go(func() error {
defer func() {
<-sem
}()
f, err := os.Open(artifact.Path)
if err != nil {
return err
}
log.WithFields(log.Fields{
"bucket": conf.Bucket,
"folder": folder,
"artifact": artifact.Name,
}).Info("uploading")
_, err = svc.PutObjectWithContext(ctx, &s3.PutObjectInput{
Bucket: aws.String(conf.Bucket),
Key: aws.String(filepath.Join(folder, artifact.Name)),
Body: f,
})
return err
})
}
return g.Wait()
}
@@ -0,0 +1,17 @@
package s3

import (
"testing"

"github.com/goreleaser/goreleaser/config"
"github.com/goreleaser/goreleaser/context"
"github.com/stretchr/testify/assert"
)

func TestDescription(t *testing.T) {
assert.NotEmpty(t, Pipe{}.String())
}

func TestNoS3(t *testing.T) {
assert.NoError(t, Pipe{}.Run(context.New(config.Project{})))
}

0 comments on commit 1c42684

Please sign in to comment.
You can’t perform that action at this time.