1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-07-17 01:42:37 +02:00

feat: upload to s3

This commit is contained in:
Carlos Alexandro Becker
2018-05-13 13:08:14 -03:00
committed by Carlos Alexandro Becker
parent 58d8ac62ac
commit 1c426847d9
11 changed files with 199 additions and 15 deletions

View File

@ -23,12 +23,12 @@ changelog:
- '^test:' - '^test:'
- Merge pull request - Merge pull request
- Merge branch - Merge branch
dockers: # dockers:
- image: goreleaser/goreleaser # - image: goreleaser/goreleaser
tag_templates: # tag_templates:
- '{{ .Tag }}' # - '{{ .Tag }}'
- 'v{{ .Major }}.{{ .Minor }}' # - 'v{{ .Major }}.{{ .Minor }}'
- 'latest' # - 'latest'
archive: archive:
name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}' name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
replacements: replacements:
@ -79,3 +79,6 @@ snapcraft:
wrapped in your favorite CI. wrapped in your favorite CI.
grade: stable grade: stable
confinement: classic confinement: classic
s3:
- bucket: goreleaser

47
Gopkg.lock generated
View File

@ -31,6 +31,40 @@
] ]
revision = "ff0f66940b829dc66c81dad34746d4349b83eb9e" revision = "ff0f66940b829dc66c81dad34746d4349b83eb9e"
[[projects]]
name = "github.com/aws/aws-sdk-go"
packages = [
"aws",
"aws/awserr",
"aws/awsutil",
"aws/client",
"aws/client/metadata",
"aws/corehandlers",
"aws/credentials",
"aws/credentials/ec2rolecreds",
"aws/credentials/endpointcreds",
"aws/credentials/stscreds",
"aws/defaults",
"aws/ec2metadata",
"aws/endpoints",
"aws/request",
"aws/session",
"aws/signer/v4",
"internal/sdkio",
"internal/sdkrand",
"internal/shareddefaults",
"private/protocol",
"private/protocol/query",
"private/protocol/query/queryutil",
"private/protocol/rest",
"private/protocol/restxml",
"private/protocol/xml/xmlutil",
"service/s3",
"service/sts"
]
revision = "31a85efbe3bc741eb539d6310c8e66030b7c5cb7"
version = "v1.13.47"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/blakesmith/ar" name = "github.com/blakesmith/ar"
@ -61,6 +95,12 @@
revision = "507f6050b8568533fb3f5504de8e5205fa62a114" revision = "507f6050b8568533fb3f5504de8e5205fa62a114"
version = "v1.6.0" version = "v1.6.0"
[[projects]]
name = "github.com/go-ini/ini"
packages = ["."]
revision = "6529cf7c58879c08d927016dde4477f18a0634cb"
version = "v1.36.0"
[[projects]] [[projects]]
name = "github.com/golang/protobuf" name = "github.com/golang/protobuf"
packages = ["proto"] packages = ["proto"]
@ -106,6 +146,11 @@
revision = "9d5f1277e9a8ed20c3684bda8fde67c05628518c" revision = "9d5f1277e9a8ed20c3684bda8fde67c05628518c"
version = "v0.3.4" version = "v0.3.4"
[[projects]]
name = "github.com/jmespath/go-jmespath"
packages = ["."]
revision = "0b12d6b5"
[[projects]] [[projects]]
name = "github.com/masterminds/semver" name = "github.com/masterminds/semver"
packages = ["."] packages = ["."]
@ -213,6 +258,6 @@
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "f59fe644e96665a3145d68ef6c134f664ef0b0b4f11c37dd6569cc66ffdee16b" inputs-digest = "a47b30326926a615c574552d71af84d17e5198486ad61bed0d63672ebaba696d"
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

View File

@ -53,3 +53,7 @@
[[constraint]] [[constraint]]
name = "github.com/alecthomas/kingpin" name = "github.com/alecthomas/kingpin"
version = "~2.2.6" version = "~2.2.6"
[[constraint]]
name = "github.com/aws/aws-sdk-go"
version = "1.13.47"

View File

@ -244,6 +244,13 @@ type Before struct {
Hooks []string `yaml:",omitempty"` Hooks []string `yaml:",omitempty"`
} }
// S3 contains s3 config
type S3 struct {
Region string
Bucket string
Folder string
}
// Project includes all project configuration // Project includes all project configuration
type Project struct { type Project struct {
ProjectName string `yaml:"project_name,omitempty"` ProjectName string `yaml:"project_name,omitempty"`
@ -259,6 +266,7 @@ type Project struct {
Checksum Checksum `yaml:",omitempty"` Checksum Checksum `yaml:",omitempty"`
Dockers []Docker `yaml:",omitempty"` Dockers []Docker `yaml:",omitempty"`
Artifactories []Artifactory `yaml:",omitempty"` Artifactories []Artifactory `yaml:",omitempty"`
S3 []S3 `yaml:"s3,omitempty"`
Changelog Changelog `yaml:",omitempty"` Changelog Changelog `yaml:",omitempty"`
Dist string `yaml:",omitempty"` Dist string `yaml:",omitempty"`
Sign Sign `yaml:",omitempty"` Sign Sign `yaml:",omitempty"`

View File

@ -9,6 +9,7 @@ import (
"github.com/google/go-github/github" "github.com/google/go-github/github"
"github.com/goreleaser/goreleaser/config" "github.com/goreleaser/goreleaser/config"
"github.com/goreleaser/goreleaser/context" "github.com/goreleaser/goreleaser/context"
"github.com/goreleaser/goreleaser/internal/nametemplate"
"golang.org/x/oauth2" "golang.org/x/oauth2"
) )
@ -89,7 +90,7 @@ func (c *githubClient) CreateFile(
func (c *githubClient) CreateRelease(ctx *context.Context, body string) (int64, error) { func (c *githubClient) CreateRelease(ctx *context.Context, body string) (int64, error) {
var release *github.RepositoryRelease var release *github.RepositoryRelease
title, err := releaseTitle(ctx) title, err := nametemplate.Apply(ctx, "github", ctx.Config.Release.NameTemplate)
if err != nil { if err != nil {
return 0, err return 0, err
} }

View File

@ -1,4 +1,4 @@
package client package nametemplate
import ( import (
"bytes" "bytes"
@ -8,12 +8,12 @@ import (
"github.com/goreleaser/goreleaser/context" "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 var out bytes.Buffer
t, err := template.New("github"). t, err := template.New(name).
Option("missingkey=error"). Option("missingkey=error").
Funcs(mkFuncMap()). Funcs(mkFuncMap()).
Parse(ctx.Config.Release.NameTemplate) Parse(tmpl)
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@ -1,4 +1,4 @@
package client package nametemplate
import ( import (
"testing" "testing"
@ -29,8 +29,7 @@ func TestFuncMap(t *testing.T) {
Name: "MM/DD/YYYY", Name: "MM/DD/YYYY",
}, },
} { } {
ctx.Config.Release.NameTemplate = tc.Template out, err := Apply(ctx, "foo", tc.Template)
out, err := releaseTitle(ctx)
assert.NoError(t, err) assert.NoError(t, err)
assert.NotEmpty(t, out) assert.NotEmpty(t, out)
} }

View File

@ -31,6 +31,7 @@ import (
"github.com/goreleaser/goreleaser/pipeline/git" "github.com/goreleaser/goreleaser/pipeline/git"
"github.com/goreleaser/goreleaser/pipeline/nfpm" "github.com/goreleaser/goreleaser/pipeline/nfpm"
"github.com/goreleaser/goreleaser/pipeline/release" "github.com/goreleaser/goreleaser/pipeline/release"
"github.com/goreleaser/goreleaser/pipeline/s3"
"github.com/goreleaser/goreleaser/pipeline/scoop" "github.com/goreleaser/goreleaser/pipeline/scoop"
"github.com/goreleaser/goreleaser/pipeline/sign" "github.com/goreleaser/goreleaser/pipeline/sign"
"github.com/goreleaser/goreleaser/pipeline/snapcraft" "github.com/goreleaser/goreleaser/pipeline/snapcraft"
@ -58,6 +59,7 @@ var pipes = []Piper{
sign.Pipe{}, // sign artifacts sign.Pipe{}, // sign artifacts
docker.Pipe{}, // create and push docker images docker.Pipe{}, // create and push docker images
artifactory.Pipe{}, // push to artifactory artifactory.Pipe{}, // push to artifactory
s3.Pipe{}, // push to s3/minio
release.Pipe{}, // release to github release.Pipe{}, // release to github
brew.Pipe{}, // push to brew tap brew.Pipe{}, // push to brew tap
scoop.Pipe{}, // push to scoop bucket scoop.Pipe{}, // push to scoop bucket

View File

@ -18,6 +18,7 @@ import (
"github.com/goreleaser/goreleaser/pipeline/nfpm" "github.com/goreleaser/goreleaser/pipeline/nfpm"
"github.com/goreleaser/goreleaser/pipeline/project" "github.com/goreleaser/goreleaser/pipeline/project"
"github.com/goreleaser/goreleaser/pipeline/release" "github.com/goreleaser/goreleaser/pipeline/release"
"github.com/goreleaser/goreleaser/pipeline/s3"
"github.com/goreleaser/goreleaser/pipeline/scoop" "github.com/goreleaser/goreleaser/pipeline/scoop"
"github.com/goreleaser/goreleaser/pipeline/sign" "github.com/goreleaser/goreleaser/pipeline/sign"
"github.com/goreleaser/goreleaser/pipeline/snapcraft" "github.com/goreleaser/goreleaser/pipeline/snapcraft"
@ -54,6 +55,7 @@ var defaulters = []Defaulter{
sign.Pipe{}, sign.Pipe{},
docker.Pipe{}, docker.Pipe{},
artifactory.Pipe{}, artifactory.Pipe{},
s3.Pipe{},
brew.Pipe{}, brew.Pipe{},
scoop.Pipe{}, scoop.Pipe{},
} }

103
pipeline/s3/s3.go Normal file
View File

@ -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()
}

17
pipeline/s3/s3_test.go Normal file
View File

@ -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{})))
}