You've already forked goreleaser
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:
committed by
Carlos Alexandro Becker
parent
58d8ac62ac
commit
1c426847d9
@ -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
|
||||
|
||||
|
47
Gopkg.lock
generated
47
Gopkg.lock
generated
@ -31,6 +31,40 @@
|
||||
]
|
||||
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]]
|
||||
branch = "master"
|
||||
name = "github.com/blakesmith/ar"
|
||||
@ -61,6 +95,12 @@
|
||||
revision = "507f6050b8568533fb3f5504de8e5205fa62a114"
|
||||
version = "v1.6.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/go-ini/ini"
|
||||
packages = ["."]
|
||||
revision = "6529cf7c58879c08d927016dde4477f18a0634cb"
|
||||
version = "v1.36.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = ["proto"]
|
||||
@ -106,6 +146,11 @@
|
||||
revision = "9d5f1277e9a8ed20c3684bda8fde67c05628518c"
|
||||
version = "v0.3.4"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/jmespath/go-jmespath"
|
||||
packages = ["."]
|
||||
revision = "0b12d6b5"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/masterminds/semver"
|
||||
packages = ["."]
|
||||
@ -213,6 +258,6 @@
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "f59fe644e96665a3145d68ef6c134f664ef0b0b4f11c37dd6569cc66ffdee16b"
|
||||
inputs-digest = "a47b30326926a615c574552d71af84d17e5198486ad61bed0d63672ebaba696d"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
@ -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)
|
||||
}
|
2
main.go
2
main.go
@ -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{},
|
||||
}
|
||||
|
103
pipeline/s3/s3.go
Normal file
103
pipeline/s3/s3.go
Normal 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
17
pipeline/s3/s3_test.go
Normal 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{})))
|
||||
}
|
Reference in New Issue
Block a user