// Copyright 2020 the Drone Authors. All rights reserved. // Use of this source code is governed by the Blue Oak Model License // that can be found in the LICENSE file. package main import ( "errors" "fmt" "log" "os" "os/exec" "path/filepath" "strings" "github.com/kelseyhightower/envconfig" "github.com/appleboy/drone-git-push/repo" ) // Args provides plugin execution arguments. type Args struct { Folder string `required:"true" envconfig:"INPUT_FOLDER"` SshKey string `envconfig:"INPUT_SSH_KEY"` GitRemote string `envconfig:"INPUT_GIT_REMOTE"` GitBranch string `envconfig:"INPUT_GIT_BRANCH"` Token string `envconfig:"INPUT_TOKEN"` Username string `envconfig:"INPUT_USERNAME"` GithubToken string `envconfig:"GITHUB_TOKEN"` GithubTokenActor string `envconfig:"GITHUB_ACTOR"` GithubRepository string `envconfig:"GITHUB_REPOSITORY"` GithubServerUrl string `envconfig:"GITHUB_SERVER_URL"` } const BRANCH_NAME = "pages" func main() { var args Args if err := envconfig.Process("", &args); err != nil { log.Fatalln(err) } if err := Exec(args); err != nil { log.Fatalln(err) } } // Exec executes the plugin. func Exec(args Args) error { if err := checkArgs(&args); err != nil { return err } if args.SshKey != "" { if err := repo.WriteKey(strings.ReplaceAll(args.SshKey, "\\n", "\n") + "\n"); err != nil { return err } } else { var err error args.GitRemote, err = repo.WriteToken(args.GitRemote, args.Username, args.Token) if err != nil { return err } } if err := copyFiles(args); err != nil { return err } if err := initRepo(args); err != nil { return err } if err := writeConfig(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.Token == "" && args.GithubToken != "" { args.Token = args.GithubToken } if args.Username == "" && args.GithubTokenActor != "" { args.Username = args.GithubTokenActor } if (args.Token == "" || args.Username == "") && args.SshKey == "" { return errors.New("(INPUT_TOKEN and INPUT_USERNAME) or INPUT_SSH_KEY is required!") } if folderInfo, err := os.Stat(args.Folder); os.IsNotExist(err) || !folderInfo.IsDir() { return errors.New("INPUT_FOLDER is not a folder!") } if args.GitRemote == "" && (args.GithubServerUrl == "" || args.GithubRepository == "") { return errors.New("INPUT_GIT_REMOTE is required!") } if args.GitRemote == "" { args.GitRemote = fmt.Sprintf("%s/%s.git", args.GithubServerUrl, args.GithubRepository) } if args.GitBranch == "" { args.GitBranch = BRANCH_NAME } return nil } func writeConfig(args Args) error { if err := execute(exec.Command("git", "config", "user.name", "[BOT] pages deployer")); err != nil { return err } if err := execute(exec.Command("git", "config", "user.email", "noreply@pages.bot")); err != nil { return err } return nil } func copyFiles(args Args) error { if err := os.RemoveAll("/tmp/pages"); err != nil { return err } if err := os.MkdirAll("/tmp", 777); err != nil { return err } folder, err := filepath.Abs(args.Folder) if err != nil { return err } cmd := exec.Command("cp", "-r", 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 } if err := os.RemoveAll("/tmp/pages/.git"); err != nil { return err } return os.Chdir("/tmp/pages") } func initRepo(args Args) error { cmd := exec.Command( "git", "init", "-b", args.GitBranch, "/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, "[BOT] pages deployer", "noreply@pages.bot")); err != nil { return err } return nil } func push(args Args) error { return execute(repo.RemotePushNamedBranch(args.GitRemote, args.GitBranch, args.GitBranch, 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() }