From e3102256374f297e8c8ec2ad6f2cb978690e774d Mon Sep 17 00:00:00 2001 From: Urko Date: Sat, 25 Feb 2023 22:32:10 +0100 Subject: [PATCH] feat: parameterize CI pipeline --- cfg/config.go | 44 ++++++++++++++++++++++++++++ go.mod | 11 +++++++ go.sum | 8 +++++ main .go | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 144 insertions(+) create mode 100644 cfg/config.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main .go diff --git a/cfg/config.go b/cfg/config.go new file mode 100644 index 0000000..1e59942 --- /dev/null +++ b/cfg/config.go @@ -0,0 +1,44 @@ +package cfg + +import ( + "log" + "os/exec" + "strings" + + "github.com/joho/godotenv" + "github.com/kelseyhightower/envconfig" +) + +type Config struct { + ScriptBinaryPath string `required:"true" split_words:"true"` + WebhookScriptPath string `required:"true" split_words:"true"` + FileToWatchPath string `required:"true" split_words:"true"` +} + +func rootDir() string { + cmdOut, err := exec.Command("git", "rev-parse", "--show-toplevel").Output() + if err != nil { + log.Fatalf("exec.Command: %s", err) + return "" + } + + rootDir := strings.TrimSpace(string(cmdOut)) + return rootDir +} + +func NewConfig(isProd bool) *Config { + if !isProd { + err := godotenv.Load(rootDir() + "/.env") + if err != nil { + log.Fatalf("environment variable ENV is empty and an error occurred while loading the .env file\n") + } + } + + cfg := &Config{} + err := envconfig.Process("", cfg) + if err != nil { + log.Fatalf("envconfig.Process: %s\n", err) + } + + return cfg +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..3ba4b49 --- /dev/null +++ b/go.mod @@ -0,0 +1,11 @@ +module filelistener + +go 1.19 + +require ( + github.com/fsnotify/fsnotify v1.6.0 + github.com/joho/godotenv v1.5.1 + github.com/kelseyhightower/envconfig v1.4.0 +) + +require golang.org/x/sys v0.0.0-20220908164124-27713097b956 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..f93a8d5 --- /dev/null +++ b/go.sum @@ -0,0 +1,8 @@ +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= +github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956 h1:XeJjHH1KiLpKGb6lvMiksZ9l0fVUh+AmGcm0nOMEBOY= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/main .go b/main .go new file mode 100644 index 0000000..a349009 --- /dev/null +++ b/main .go @@ -0,0 +1,81 @@ +package main + +import ( + "fmt" + "log" + "os" + "os/exec" + + "filelistener/cfg" + + "github.com/fsnotify/fsnotify" +) + +func main() { + isProd := os.Getenv("ENV") == "prod" + config := cfg.NewConfig(isProd) + + // Create new watcher. + watcher, err := fsnotify.NewWatcher() + if err != nil { + log.Fatal(err) + } + defer watcher.Close() + + // Start listening for events. + go func() { + for { + select { + case event, ok := <-watcher.Events: + if !ok { + log.Printf("<-watcher.Events: %s\n", err) + return + } + if !event.Has(fsnotify.Write) { + log.Printf("is not Write: %s\n", event.Name) + continue + } + + if err := deploy(config.ScriptBinaryPath, config.WebhookScriptPath); err != nil { + log.Printf("deploy: %s\n", err) + continue + } + case err, ok := <-watcher.Errors: + if !ok { + return + } + log.Printf("<-watcher.Errors: %s\n", err) + } + } + }() + + // Add a path. + err = watcher.Add(config.FileToWatchPath) + if err != nil { + log.Fatal(err) + } + + // Block main goroutine forever. + <-make(chan struct{}) +} + +func deploy(binaryPath, scriptPath string) error { + err := execute(binaryPath, scriptPath) + if err != nil { + return fmt.Errorf("execute: %s", err) + } + log.Println("deploy done") + return nil +} + +func execute(binaryPath, scriptPath string) error { + cmd := exec.Command(binaryPath, scriptPath) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + if err := cmd.Run(); err != nil { + return fmt.Errorf("cmd.Run %s", err) + } + + return nil +}