drone-s3-sync/main.go

162 lines
3.6 KiB
Go
Raw Normal View History

2015-10-16 22:09:45 +02:00
package main
import (
"fmt"
"os"
"os/exec"
"strings"
"github.com/drone/drone-plugin-go/plugin"
)
type S3 struct {
Key string `json:"access_key"`
Secret string `json:"secret_key"`
Bucket string `json:"bucket"`
// us-east-1
// us-west-1
// us-west-2
// eu-west-1
// ap-southeast-1
// ap-southeast-2
// ap-northeast-1
// sa-east-1
Region string `json:"region"`
// Indicates the files ACL, which should be one
// of the following:
// private
// public-read
// public-read-write
// authenticated-read
// bucket-owner-read
// bucket-owner-full-control
Access string `json:"acl"`
// Copies the files from the specified directory.
// Regexp matching will apply to match multiple
// files
//
// Examples:
// /path/to/file
// /path/to/*.txt
// /path/to/*/*.txt
// /path/to/**
Source string `json:"source"`
Target string `json:"target"`
// Include or exclude all files or objects from the command
// that matches the specified pattern.
Include string `json:"include"`
Exclude string `json:"exclude"`
// Files that exist in the destination but not in the source
// are deleted during sync.
Delete bool `json:"delete"`
// Specify an explicit content type for this operation. This
// value overrides any guessed mime types.
ContentType string `json:"content_type"`
}
func main() {
workspace := plugin.Workspace{}
vargs := S3{}
plugin.Param("workspace", &workspace)
plugin.Param("vargs", &vargs)
plugin.MustParse()
// skip if AWS key or SECRET are empty. A good example for this would
// be forks building a project. S3 might be configured in the source
// repo, but not in the fork
if len(vargs.Key) == 0 || len(vargs.Secret) == 0 {
return
}
// make sure a default region is set
if len(vargs.Region) == 0 {
vargs.Region = "us-east-1"
}
// make sure a default access is set
// let's be conservative and assume private
if len(vargs.Access) == 0 {
vargs.Access = "private"
}
// make sure a default source is set
if len(vargs.Source) == 0 {
vargs.Source = "."
}
// if the target starts with a "/" we need
// to remove it, otherwise we might adding
// a 3rd slash to s3://
if strings.HasPrefix(vargs.Target, "/") {
vargs.Target = vargs.Target[1:]
}
vargs.Target = fmt.Sprintf("s3://%s/%s", vargs.Bucket, vargs.Target)
cmd := command(vargs)
cmd.Env = os.Environ()
cmd.Env = append(cmd.Env, "AWS_ACCESS_KEY_ID="+vargs.Key)
cmd.Env = append(cmd.Env, "AWS_SECRET_ACCESS_KEY="+vargs.Secret)
cmd.Dir = workspace.Path
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
trace(cmd)
// run the command and exit if failed.
err := cmd.Run()
if err != nil {
os.Exit(1)
}
}
// command is a helper function that returns the command
// and arguments to upload to aws from the command line.
func command(s S3) *exec.Cmd {
// command line args
args := []string{
"s3",
"sync",
s.Source,
s.Target,
"--acl",
s.Access,
"--region",
s.Region,
}
// append delete flag if specified
if s.Delete {
args = append(args, "--delete")
}
// append include flag if specified
if len(s.Include) != 0 {
args = append(args, "--include")
args = append(args, s.Include)
}
// appends exclude flag if specified
if len(s.Exclude) != 0 {
args = append(args, "--exclude")
args = append(args, s.Exclude)
}
// appends content-type if specified
if len(s.ContentType) != 0 {
args = append(args, "--content-type")
args = append(args, s.ContentType)
}
return exec.Command("aws", args...)
}
// trace writes each command to standard error (preceded by a $ ) before it
// is executed. Used for debugging your build.
func trace(cmd *exec.Cmd) {
fmt.Println("$", strings.Join(cmd.Args, " "))
}