github.phpd.cn/goreleaser/goreleaser@v0.92.0/internal/pipe/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/service/s3"
    11  	"github.com/goreleaser/goreleaser/internal/artifact"
    12  	"github.com/goreleaser/goreleaser/internal/pipe"
    13  	"github.com/goreleaser/goreleaser/internal/semerrgroup"
    14  	"github.com/goreleaser/goreleaser/internal/tmpl"
    15  	"github.com/goreleaser/goreleaser/pkg/config"
    16  	"github.com/goreleaser/goreleaser/pkg/context"
    17  )
    18  
    19  // Pipe for Artifactory
    20  type Pipe struct{}
    21  
    22  // String returns the description of the pipe
    23  func (Pipe) String() string {
    24  	return "releasing to s3"
    25  }
    26  
    27  // Default sets the pipe defaults
    28  func (Pipe) Default(ctx *context.Context) error {
    29  	for i := range ctx.Config.S3 {
    30  		s3 := &ctx.Config.S3[i]
    31  		if s3.Bucket == "" {
    32  			continue
    33  		}
    34  		if s3.Folder == "" {
    35  			s3.Folder = "{{ .ProjectName }}/{{ .Tag }}"
    36  		}
    37  		if s3.Region == "" {
    38  			s3.Region = "us-east-1"
    39  		}
    40  		if s3.ACL == "" {
    41  			s3.ACL = "private"
    42  		}
    43  	}
    44  	return nil
    45  }
    46  
    47  // Publish to S3
    48  func (Pipe) Publish(ctx *context.Context) error {
    49  	if len(ctx.Config.S3) == 0 {
    50  		return pipe.Skip("s3 section is not configured")
    51  	}
    52  	var g = semerrgroup.New(ctx.Parallelism)
    53  	for _, conf := range ctx.Config.S3 {
    54  		conf := conf
    55  		g.Go(func() error {
    56  			return upload(ctx, conf)
    57  		})
    58  	}
    59  	return g.Wait()
    60  }
    61  
    62  func upload(ctx *context.Context, conf config.S3) error {
    63  	builder := newSessionBuilder()
    64  	builder.Profile(conf.Profile)
    65  	if conf.Endpoint != "" {
    66  		builder.Endpoint(conf.Endpoint)
    67  		builder.S3ForcePathStyle(true)
    68  	}
    69  	sess := builder.Build()
    70  
    71  	svc := s3.New(sess, &aws.Config{
    72  		Region: aws.String(conf.Region),
    73  	})
    74  	folder, err := tmpl.New(ctx).Apply(conf.Folder)
    75  	if err != nil {
    76  		return err
    77  	}
    78  
    79  	var g = semerrgroup.New(ctx.Parallelism)
    80  	for _, artifact := range ctx.Artifacts.Filter(
    81  		artifact.Or(
    82  			artifact.ByType(artifact.UploadableArchive),
    83  			artifact.ByType(artifact.UploadableBinary),
    84  			artifact.ByType(artifact.Checksum),
    85  			artifact.ByType(artifact.Signature),
    86  			artifact.ByType(artifact.LinuxPackage),
    87  		),
    88  	).List() {
    89  		artifact := artifact
    90  		g.Go(func() error {
    91  			f, err := os.Open(artifact.Path)
    92  			if err != nil {
    93  				return err
    94  			}
    95  			log.WithFields(log.Fields{
    96  				"bucket":   conf.Bucket,
    97  				"folder":   folder,
    98  				"artifact": artifact.Name,
    99  			}).Info("uploading")
   100  			_, err = svc.PutObjectWithContext(ctx, &s3.PutObjectInput{
   101  				Bucket: aws.String(conf.Bucket),
   102  				Key:    aws.String(filepath.Join(folder, artifact.Name)),
   103  				Body:   f,
   104  				ACL:    aws.String(conf.ACL),
   105  			})
   106  			return err
   107  		})
   108  	}
   109  	return g.Wait()
   110  }