diff --git a/DOCS.md b/DOCS.md index b00ed72..15dabfa 100644 --- a/DOCS.md +++ b/DOCS.md @@ -10,6 +10,7 @@ Use the S3 plugin to upload files and build artifacts to an S3 bucket. The follo * **target** - target location of files in the bucket * **exclude** - glob exclusion patterns * **path_style** - whether path style URLs should be used (true for minio, false for aws) +* **compress** - prior to upload, compress files and use gzip content-encoding The following is a sample S3 configuration in your .drone.yml file: @@ -26,4 +27,5 @@ publish: target: /target/location exclude: - **/*.xml + compress: false ``` diff --git a/README.md b/README.md index a69d716..33e172e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # drone-s3 [![Build Status](http://beta.drone.io/api/badges/drone-plugins/drone-s3/status.svg)](http://beta.drone.io/drone-plugins/drone-s3) -[![Image Size](https://badge.imagelayers.io/plugins/drone-s3:latest.svg)](https://imagelayers.io/?images=plugins/drone-s3:latest 'Get your own badge on imagelayers.io') +[![Image Size](https://badge.imagelayers.io/plugins/s3:latest.svg)](https://imagelayers.io/?images=plugins/s3:latest 'Get your own badge on imagelayers.io') Drone plugin to publish files and artifacts to Amazon S3. For the usage information and a listing of the available options please take a look at [the docs](DOCS.md). diff --git a/main.go b/main.go index 6919a1f..2aa0688 100644 --- a/main.go +++ b/main.go @@ -82,6 +82,11 @@ func main() { Usage: "use path style for bucket paths", EnvVar: "PLUGIN_PATH_STYLE", }, + cli.BoolFlag{ + Name: "compress", + Usage: "prior to upload, compress files and use gzip content-encoding", + EnvVar: "PLUGIN_COMPRESS", + }, } if err := app.Run(os.Args); err != nil { @@ -103,6 +108,7 @@ func run(c *cli.Context) error { Exclude: c.StringSlice("exclude"), PathStyle: c.Bool("path-style"), DryRun: c.Bool("dry-run"), + Compress: c.Bool("compress"), } // normalize the target URL diff --git a/plugin.go b/plugin.go index 866de6f..964ac75 100644 --- a/plugin.go +++ b/plugin.go @@ -1,6 +1,9 @@ package main import ( + "bytes" + "compress/gzip" + "io" "mime" "os" "path/filepath" @@ -65,6 +68,8 @@ type Plugin struct { PathStyle bool // Dry run without uploading/ DryRun bool + // Compress objects and upload with Content-Encoding: gzip + Compress bool } // Exec runs the plugin @@ -138,13 +143,37 @@ func (p *Plugin) Exec() error { } defer f.Close() - _, err = client.PutObject(&s3.PutObjectInput{ - Body: f, + //prepare upload + input := &s3.PutObjectInput{ Bucket: &(p.Bucket), Key: &target, ACL: &(p.Access), ContentType: &content, - }) + } + + //optionally compress + if p.Compress { + //currently buffers entire file into memory + //TODO: convert to on-demand gzip + b := bytes.Buffer{} + gw := gzip.NewWriter(&b) + if _, err := io.Copy(gw, f); err != nil { + log.WithFields(log.Fields{ + "error": err, + "file": match, + }).Error("Problem gzipping file") + return err + } + gw.Close() + input.Body = bytes.NewReader(b.Bytes()) + //set encoding + input.ContentEncoding = aws.String("gzip") + } else { + input.Body = f + } + + //upload + _, err = client.PutObject(input) if err != nil { log.WithFields(log.Fields{