diff --git a/.gitignore b/.gitignore index e052d74..65c9bae 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .env release/ - +test/ +run.sh \ No newline at end of file diff --git a/README.md b/README.md index 29bf344..00340c7 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,8 @@ steps: image: itsblue.dev/plugins/codeberg-pages-deploy pull: if-not-exists settings: - param1: foo - param2: bar + folder: public + ssh_key: foo ``` # Building @@ -41,7 +41,7 @@ docker build -t itsblue.dev/plugins/codeberg-pages-deploy -f docker/Dockerfile . Execute the plugin from your current working directory: ```text -docker run --rm -e PLUGIN_PARAM1=foo -e PLUGIN_PARAM2=bar \ +docker run --rm -e PLUGIN_FOLDER=public -e PLUGIN_SSH_KEY=foo \ -e DRONE_COMMIT_SHA=8f51ad7884c5eb69c11d260a31da7a745e6b78e2 \ -e DRONE_COMMIT_BRANCH=master \ -e DRONE_BUILD_NUMBER=43 \ diff --git a/docker/Dockerfile b/docker/Dockerfile index 30bbf4b..72f92d0 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,9 +1,10 @@ -FROM alpine:3.6 as alpine +FROM alpine:3.15 as alpine RUN apk add -U --no-cache ca-certificates -FROM alpine:3.6 +FROM alpine:3.15 ENV GODEBUG netdns=go +RUN apk add -U --no-cache git openssh COPY --from=alpine /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ ADD release/linux/amd64/plugin /bin/ diff --git a/docker/Dockerfile.linux.arm b/docker/Dockerfile.linux.arm deleted file mode 100644 index 993c2e9..0000000 --- a/docker/Dockerfile.linux.arm +++ /dev/null @@ -1,10 +0,0 @@ -FROM alpine:3.6 as alpine -RUN apk add -U --no-cache ca-certificates - -FROM alpine:3.6 -ENV GODEBUG netdns=go - -COPY --from=alpine /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ - -ADD release/linux/arm/plugin /bin/ -ENTRYPOINT ["/bin/plugin"] \ No newline at end of file diff --git a/docker/Dockerfile.linux.arm64 b/docker/Dockerfile.linux.arm64 deleted file mode 100644 index 1223423..0000000 --- a/docker/Dockerfile.linux.arm64 +++ /dev/null @@ -1,10 +0,0 @@ -FROM alpine:3.6 as alpine -RUN apk add -U --no-cache ca-certificates - -FROM alpine:3.6 -ENV GODEBUG netdns=go - -COPY --from=alpine /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ - -ADD release/linux/arm64/plugin /bin/ -ENTRYPOINT ["/bin/plugin"] \ No newline at end of file diff --git a/go.mod b/go.mod index 20b0448..0efdcd5 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module itsblue.dev/plugins/codeberg-pages-deploy go 1.12 require ( + github.com/appleboy/drone-git-push v0.2.1 // indirect github.com/kelseyhightower/envconfig v1.4.0 github.com/sirupsen/logrus v1.4.2 ) diff --git a/go.sum b/go.sum index 282f96f..40a37f9 100644 --- a/go.sum +++ b/go.sum @@ -1,12 +1,25 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/appleboy/drone-git-push v0.2.1 h1:qHVGsyH+W13riH3WVWVUMDhvWuyL39YxS9W8vusyRKc= +github.com/appleboy/drone-git-push v0.2.1/go.mod h1:U8WR++X176gQ6xoWz3dfhKsHBvr0sGDfwcmT5ih5UiU= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/plugin/plugin.go b/plugin/plugin.go index fee9c9d..2d1a071 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -4,7 +4,17 @@ package plugin -import "context" +import ( + "context" + "errors" + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" + + "github.com/appleboy/drone-git-push/repo" +) // Args provides plugin execution arguments. type Args struct { @@ -13,13 +23,136 @@ type Args struct { // Level defines the plugin log level. Level string `envconfig:"PLUGIN_LOG_LEVEL"` - // TODO replace or remove - Param1 string `envconfig:"PLUGIN_PARAM1"` - Param2 string `envconfig:"PLUGIN_PARAM2"` + Folder string `envconfig:"PLUGIN_FOLDER"` + SshKey string `envconfig:"PLUGIN_SSH_KEY"` + GitRemote string `envconfig:"PLUGIN_GIT_REMOTE"` } +const BRANCH_NAME = "pages" + // Exec executes the plugin. func Exec(ctx context.Context, args Args) error { + + if err := checkArgs(args); err != nil { + return err + } + + if err := repo.WriteKey(strings.ReplaceAll(args.SshKey, "\\n", "\n")); err != nil { + return err + } + + if err := writeConfig(args); err != nil { + return err + } + + if err := copyFiles(args); err != nil { + return err + } + + if err := initRepo(args); err != nil { + return err + } + + if err := doCommit(args); err != nil { + return err + } + + if err := push(args); err != nil { + return err + } + // write code here return nil } + +func checkArgs(args Args) error { + if args.Folder == "" { + return errors.New("PLUGIN_FOLDER is required!") + } + + if folderInfo, err := os.Stat(args.Folder); os.IsNotExist(err) || !folderInfo.IsDir() { + return errors.New("PLUGIN_FOLDER is not a folder!") + } + + if args.SshKey == "" { + return errors.New("PLUGIN_SSH_KEY is required!") + } + + if args.GitRemote == "" { + return errors.New("PLUGIN_GIT_REMOTE is required!") + } + + return nil +} + +func writeConfig(args Args) error { + if err := repo.GlobalName("[BOT] pages deployer").Run(); err != nil { + return err + } + + if err := repo.GlobalUser("noreply@pages.bot").Run(); err != nil { + return err + } + + return nil +} + +func copyFiles(args Args) error { + if err := os.MkdirAll("/tmp", 777); err != nil { + return err + } + + folder, err := filepath.Abs(args.Folder) + if err != nil { + return err + } + + cmd := exec.Command("mv", folder, "/tmp/pages") + if err := execute(cmd); err != nil { + return err + } + + if err := os.Chown("/tmp/pages", os.Getuid(), os.Getgid()); err != nil { + return err + } + + return os.Chdir("/tmp/pages") +} + +func initRepo(args Args) error { + cmd := exec.Command( + "git", + "init", "-b", BRANCH_NAME, "/tmp/pages") + + if err := execute(cmd); err != nil { + return err + } + + return nil +} + +func doCommit(args Args) error { + if err := execute(repo.Add()); err != nil { + return err + } + + if err := execute(repo.ForceCommit("Update pages 🚀", true)); err != nil { + return err + } + + return nil +} + +func push(args Args) error { + return execute(repo.RemotePushNamedBranch(args.GitRemote, BRANCH_NAME, BRANCH_NAME, true, false)) +} + +func execute(cmd *exec.Cmd) error { + fmt.Println("+", strings.Join(cmd.Args, " ")) + + cmd.Env = os.Environ() + cmd.Stderr = os.Stderr + cmd.Stdin = os.Stdin + + return cmd.Run() +}