github.com/szyn/goreleaser@v0.76.1-0.20180517112710-333da09a1297/pipeline/s3/s3.go (about) 1 // Package s3 provides a Pipe that push artifacts to s3/minio 2 package s3 3 4 import ( 5 "os" 6 "path/filepath" 7 8 "github.com/apex/log" 9 "github.com/aws/aws-sdk-go/aws" 10 "github.com/aws/aws-sdk-go/aws/credentials" 11 "github.com/aws/aws-sdk-go/aws/session" 12 "github.com/aws/aws-sdk-go/service/s3" 13 "github.com/goreleaser/goreleaser/config" 14 "github.com/goreleaser/goreleaser/context" 15 "github.com/goreleaser/goreleaser/internal/artifact" 16 "github.com/goreleaser/goreleaser/internal/nametemplate" 17 "golang.org/x/sync/errgroup" 18 ) 19 20 // Pipe for Artifactory 21 type Pipe struct{} 22 23 // String returns the description of the pipe 24 func (Pipe) String() string { 25 return "releasing to s3" 26 } 27 28 // Default sets the pipe defaults 29 func (Pipe) Default(ctx *context.Context) error { 30 for i := range ctx.Config.S3 { 31 s3 := &ctx.Config.S3[i] 32 if s3.Bucket == "" { 33 continue 34 } 35 if s3.Folder == "" { 36 s3.Folder = "{{ .ProjectName }}/{{ .Tag }}" 37 } 38 if s3.Region == "" { 39 s3.Region = "us-east-1" 40 } 41 } 42 return nil 43 } 44 45 // Run the pipe 46 func (Pipe) Run(ctx *context.Context) error { 47 var g errgroup.Group 48 sem := make(chan bool, ctx.Parallelism) 49 for _, conf := range ctx.Config.S3 { 50 conf := conf 51 sem <- true 52 g.Go(func() error { 53 defer func() { 54 <-sem 55 }() 56 return upload(ctx, conf) 57 }) 58 } 59 return g.Wait() 60 } 61 62 func upload(ctx *context.Context, conf config.S3) error { 63 var awsConfig = aws.NewConfig() 64 // TODO: add a test for this 65 if conf.Endpoint != "" { 66 awsConfig.Endpoint = aws.String(conf.Endpoint) 67 awsConfig.S3ForcePathStyle = aws.Bool(true) 68 } 69 // TODO: add a test for this 70 if conf.Profile != "" { 71 awsConfig.Credentials = credentials.NewSharedCredentials("", conf.Profile) 72 } 73 sess := session.Must(session.NewSession(awsConfig)) 74 svc := s3.New(sess, &aws.Config{ 75 Region: aws.String(conf.Region), 76 }) 77 folder, err := nametemplate.Apply(ctx, conf.Folder) 78 if err != nil { 79 return err 80 } 81 82 var g errgroup.Group 83 sem := make(chan bool, ctx.Parallelism) 84 for _, artifact := range ctx.Artifacts.Filter( 85 artifact.Or( 86 artifact.ByType(artifact.UploadableArchive), 87 artifact.ByType(artifact.UploadableBinary), 88 artifact.ByType(artifact.Checksum), 89 artifact.ByType(artifact.Signature), 90 artifact.ByType(artifact.LinuxPackage), 91 ), 92 ).List() { 93 sem <- true 94 artifact := artifact 95 g.Go(func() error { 96 defer func() { 97 <-sem 98 }() 99 f, err := os.Open(artifact.Path) 100 if err != nil { 101 return err 102 } 103 log.WithFields(log.Fields{ 104 "bucket": conf.Bucket, 105 "folder": folder, 106 "artifact": artifact.Name, 107 }).Info("uploading") 108 _, err = svc.PutObjectWithContext(ctx, &s3.PutObjectInput{ 109 Bucket: aws.String(conf.Bucket), 110 Key: aws.String(filepath.Join(folder, artifact.Name)), 111 Body: f, 112 }) 113 return err 114 }) 115 } 116 return g.Wait() 117 }