From 2900a3d40848b94d4621ec8d96d4a848f5a24155 Mon Sep 17 00:00:00 2001 From: parra Date: Thu, 23 Feb 2023 16:31:35 +0100 Subject: [PATCH 1/5] Migrate script to Go --- .drone.yml | 36 ++++++++++++++++++++++++++++-- .gitignore | 2 ++ cmd/drone-ntfy/main.go | 50 ++++++++++++++++++++++++++++++++++++++++++ go.mod | 8 +++++++ go.sum | 4 ++++ 5 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 cmd/drone-ntfy/main.go create mode 100644 go.mod create mode 100644 go.sum diff --git a/.drone.yml b/.drone.yml index 53cd1f2..3706bf5 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,11 +1,39 @@ kind: pipeline type: docker -name: build +name: build-go + +steps: +- name: Build service + image: registry.cuzo.dev/library/golang + volumes: + - name: deps + path: /go + commands: + - go build -o bin/ cmd/drone-ntfy/main.go + - go run cmd/drone-ntfy/main.go + +image_pull_secrets: +- custom_mirror_registry + +trigger: + event: + - push + - tag + exclude: + - pull_request + +--- +kind: pipeline +type: docker +name: build-image steps: - name: Build docker image image: registry.cuzo.dev/plugins/docker privileged: true + when: + branch: + - main volumes: - name: manifest path: docker @@ -38,6 +66,9 @@ steps: - name: Upload manifest image: registry.cuzo.dev/plugins/manifest privileged: true + when: + branch: + - main volumes: - name: manifest path: docker @@ -70,7 +101,8 @@ steps: from_secret: ntfy_password depends_on: -- build +- build-image +- build-go image_pull_secrets: - custom_mirror_registry diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..662f6d5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.vscode/ +bin/ diff --git a/cmd/drone-ntfy/main.go b/cmd/drone-ntfy/main.go new file mode 100644 index 0000000..141e51a --- /dev/null +++ b/cmd/drone-ntfy/main.go @@ -0,0 +1,50 @@ +package main + +import ( + "fmt" + "log" + "os" + + "github.com/caarlos0/env/v7" +) + +type Config struct { + BaseUrl string `env:"PLUGIN_BASE_URL" envDefault:"https://ntfy.sh"` + Topic string `env:"PLUGIN_TOPIC,required"` + Title string `env:"PLUGIN_TITLE" envDefault:"Drone notification"` + Priority string `env:"PLUGIN_PRIORITY" envDefault:"default"` + Tags []string `env:"PLUGIN_TAGS" envSeparator:","` +} + +type DroneConfig struct { + BuildNumber string `envPrefix:"DRONE_"` + StageName string `envPrefix:"DRONE_"` + StageStatus string `envPrefix:"DRONE_"` +} + +type CiConfig struct { + RepoName string `envPrefix:"CI_"` + CommitMessage string `envPrefix:"CI_"` +} + +const DEFAULT_PRIORITY = "default" + +const BASE_URL = "https://ntfy.sh" +const TOPIC = "" +const TITLE = "" +const PRIORITY = "" +const TAGS = "" + +const MESSAGE = "Build $DRONE_BUILD_NUMBER of $CI_REPO_NAME at stage $DRONE_STAGE_NAME $DRONE_STAGE_STATUS.\n\nCommit: $CI_COMMIT_MESSAGE" + +func main() { + + fmt.Printf("Topic: %s\n", os.Environ()) + cfg := Config{} + err := env.Parse(&cfg) + if err != nil { + log.Fatalf("unable to parse environment variables: %e", err) + } + + fmt.Printf("Config: %v\n", cfg) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..0f35684 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module git.parravidales.es/parra/drone-ntfy + +go 1.19 + +require ( + github.com/caarlos0/env/v7 v7.0.0 // indirect + github.com/joho/godotenv v1.5.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..daef734 --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +github.com/caarlos0/env/v7 v7.0.0 h1:cyczlTd/zREwSr9ch/mwaDl7Hse7kJuUY8hvHfXu5WI= +github.com/caarlos0/env/v7 v7.0.0/go.mod h1:LPPWniDUq4JaO6Q41vtlyikhMknqymCLBw0eX4dcH1E= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -- 2.40.1 From dc2ab0dcd0431728c731aa029b25e51e5eb3596f Mon Sep 17 00:00:00 2001 From: parra Date: Thu, 23 Feb 2023 16:55:28 +0100 Subject: [PATCH 2/5] Load configs --- .gitignore | 1 + cmd/drone-ntfy/config/config.go | 32 ++++++++ cmd/drone-ntfy/main.go | 129 +++++++++++++++++++++++--------- 3 files changed, 125 insertions(+), 37 deletions(-) create mode 100644 cmd/drone-ntfy/config/config.go diff --git a/.gitignore b/.gitignore index 662f6d5..2fe15e4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .vscode/ bin/ +.env diff --git a/cmd/drone-ntfy/config/config.go b/cmd/drone-ntfy/config/config.go new file mode 100644 index 0000000..803249d --- /dev/null +++ b/cmd/drone-ntfy/config/config.go @@ -0,0 +1,32 @@ +package config + +type App struct { + BaseUrl string `env:"PLUGIN_URL" envDefault:"https://ntfy.sh"` + Topic string `env:"PLUGIN_TOPIC" envDefault:"undefined"` + Username string `env:"PLUGIN_USERNAME"` + Password string `env:"PLUGIN_PASSWORD"` + Token string `env:"PLUGIN_TOKEN"` + Title string `env:"PLUGIN_TITLE" envDefault:"Drone notification"` + Priority string `env:"PLUGIN_PRIORITY" envDefault:"default"` + Tags []string `env:"PLUGIN_TAGS" envSeparator:","` + DefaultTags []string `env:"PLUGIN_DEFAULT_TAGS" envDefault:"drone"` + Message string `env:"PLUGIN_MESSAGE"` +} + +type Drone struct { + BuildNumber string `env:"DRONE_BUILD_NUMBER"` + BuildStatus string `env:"DRONE_BUILD_STATUS"` + StageName string `env:"DRONE_STAGE_NUMBER"` + StageStatus string `env:"DRONE_STAGE_STATUS"` + Tag string `env:"DRONE_TAG"` + BuildLink string `env:"DRONE_BUILD_LINK"` + CommitLink string `env:"DRONE_COMMIT_LINK"` +} + +type Ci struct { + RepoName string `env:"CI_REPO_NAME"` + CommitMessage string `env:"CI_COMMIT_MESSAGE"` + CommitSha string `env:"CI_COMMIT_SHA"` + CommitBranch string `env:"CI_COMMIT_BRANCH"` + CommitRef string `env:"CI_COMMIT_REF"` +} diff --git a/cmd/drone-ntfy/main.go b/cmd/drone-ntfy/main.go index 141e51a..48c9400 100644 --- a/cmd/drone-ntfy/main.go +++ b/cmd/drone-ntfy/main.go @@ -1,50 +1,105 @@ package main import ( - "fmt" - "log" - "os" + "fmt" + "log" + "net/http" + "os" + "strings" - "github.com/caarlos0/env/v7" + "git.parravidales.es/parra/drone-ntfy/cmd/drone-ntfy/config" + "github.com/caarlos0/env/v7" + "github.com/joho/godotenv" ) type Config struct { - BaseUrl string `env:"PLUGIN_BASE_URL" envDefault:"https://ntfy.sh"` - Topic string `env:"PLUGIN_TOPIC,required"` - Title string `env:"PLUGIN_TITLE" envDefault:"Drone notification"` - Priority string `env:"PLUGIN_PRIORITY" envDefault:"default"` - Tags []string `env:"PLUGIN_TAGS" envSeparator:","` + App config.App + Drone config.Drone + Ci config.Ci } -type DroneConfig struct { - BuildNumber string `envPrefix:"DRONE_"` - StageName string `envPrefix:"DRONE_"` - StageStatus string `envPrefix:"DRONE_"` -} - -type CiConfig struct { - RepoName string `envPrefix:"CI_"` - CommitMessage string `envPrefix:"CI_"` -} - -const DEFAULT_PRIORITY = "default" - -const BASE_URL = "https://ntfy.sh" -const TOPIC = "" -const TITLE = "" -const PRIORITY = "" -const TAGS = "" - -const MESSAGE = "Build $DRONE_BUILD_NUMBER of $CI_REPO_NAME at stage $DRONE_STAGE_NAME $DRONE_STAGE_STATUS.\n\nCommit: $CI_COMMIT_MESSAGE" - func main() { - fmt.Printf("Topic: %s\n", os.Environ()) - cfg := Config{} - err := env.Parse(&cfg) - if err != nil { - log.Fatalf("unable to parse environment variables: %e", err) - } + fmt.Printf("Topic: %s\n", os.Environ()) + cfg := loadCfg() - fmt.Printf("Config: %v\n", cfg) + updateAppConfig(&cfg) + addTagsBasedOnResult(&cfg) + + fmt.Printf("App Config: %+v\n", cfg) + sendNotification(&cfg) +} + +func loadCfg() Config { + + envErr := godotenv.Load(".env") + if envErr != nil { + fmt.Printf("unable to load .env file: %e\n", envErr) + } + + conf := Config{ + App: config.App{}, + Drone: config.Drone{}, + Ci: config.Ci{}, + } + loadConfig(&conf.App) + loadConfig(&conf.Drone) + loadConfig(&conf.Ci) + + conf.App.Tags = append(conf.App.DefaultTags, conf.App.Tags...) + + return conf +} + +func loadConfig(cfg any) { + err := env.Parse(cfg) + if err != nil { + log.Fatalf("unable to parse environment variables: %e", err) + } +} + +func updateAppConfig(cfg *Config) { + + if strings.Contains(cfg.Ci.CommitRef, "refs/tags/") { + cfg.App.Tags = append(cfg.App.Tags, cfg.Drone.Tag) + cfg.App.Message = "Tag " + cfg.Drone.Tag + " created" + } else { + cfg.App.Tags = append(cfg.App.Tags, "branch "+cfg.Ci.CommitBranch) + cfg.App.Message = "[" + cfg.Ci.CommitSha[0:8] + "] " + cfg.Ci.CommitMessage + } +} + +func addTagsBasedOnResult(cfg *Config) { + + if cfg.Drone.BuildStatus == "success" { + cfg.App.Tags = append(cfg.App.Tags, "white_check_mark") + } else if cfg.Drone.BuildStatus == "failure" { + cfg.App.Tags = append(cfg.App.Tags, "x") + } else { + cfg.App.Tags = append(cfg.App.Tags, "grey_question") + } +} + +func sendNotification(cfg *Config) { + + req, _ := http.NewRequest("POST", + cfg.App.BaseUrl + "/" + cfg.App.Topic, + strings.NewReader(cfg.App.Message)) + + if cfg.App.Token != "" { + req.Header.Add("Authorization", "Bearer "+cfg.App.Token) + } else { + req.SetBasicAuth(cfg.App.Username, cfg.App.Password) + } + req.Header.Set("Title", cfg.App.Title) + req.Header.Set("Priority", cfg.App.Priority) + req.Header.Set("Tags", strings.Join(cfg.App.Tags, ",")) + req.Header.Set("Actions", "view, Build, "+cfg.Drone.BuildLink+"; view, Changes, "+cfg.Drone.CommitLink) + res, err := http.DefaultClient.Do(req) + if err != nil { + log.Fatalf("error trying to notify the result. Error: %+v", err) + } + if res.StatusCode != 200 { + log.Fatalf("error from server. HTTP status: %d. Error: %e", res.StatusCode, err) + } } -- 2.40.1 From 6aed1611564de93788366c6f7e0ccea49dc1357a Mon Sep 17 00:00:00 2001 From: parra Date: Thu, 23 Feb 2023 20:10:14 +0100 Subject: [PATCH 3/5] Prepare Docker image --- .drone.yml | 98 ++++++++++----------------------- Dockerfile | 7 +-- cmd/drone-ntfy/config/config.go | 3 +- cmd/drone-ntfy/main.go | 16 ++++-- 4 files changed, 45 insertions(+), 79 deletions(-) diff --git a/.drone.yml b/.drone.yml index 3706bf5..f01266f 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,39 +1,21 @@ kind: pipeline type: docker -name: build-go +name: build steps: -- name: Build service +- name: Build Go app image: registry.cuzo.dev/library/golang volumes: - name: deps path: /go commands: - - go build -o bin/ cmd/drone-ntfy/main.go - - go run cmd/drone-ntfy/main.go - -image_pull_secrets: -- custom_mirror_registry - -trigger: - event: - - push - - tag - exclude: - - pull_request - ---- -kind: pipeline -type: docker -name: build-image - -steps: + - GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o bin/ cmd/drone-ntfy/main.go - name: Build docker image image: registry.cuzo.dev/plugins/docker - privileged: true when: branch: - main + privileged: true volumes: - name: manifest path: docker @@ -46,26 +28,11 @@ steps: from_secret: docker_hub_user password: from_secret: docker_hub_pass - -image_pull_secrets: -- custom_mirror_registry - -trigger: - event: - - push - - tag - exclude: - - pull_request - ---- -kind: pipeline -type: docker -name: manifest - -steps: - name: Upload manifest image: registry.cuzo.dev/plugins/manifest privileged: true + depends_on: + - Build docker image when: branch: - main @@ -83,26 +50,6 @@ steps: from_secret: docker_hub_pass platforms: - linux/amd64 -- name: send ntfy notification - image: registry.cuzo.dev/parrazam/drone-ntfy - when: - status: [success, failure] - ref: - exclude: - - refs/tags/* - settings: - url: https://ntfy.parravidales.es - topic: pipelines - priority: low - tags: manifest - username: - from_secret: ntfy_user - password: - from_secret: ntfy_password - -depends_on: -- build-image -- build-go image_pull_secrets: - custom_mirror_registry @@ -126,6 +73,23 @@ steps: api_key: from_secret: drone_api_key base_url: https://git.parravidales.es + +depends_on: +- build + +image_pull_secrets: +- custom_mirror_registry + +trigger: + event: + - tag + +--- +kind: pipeline +type: docker +name: notify + +steps: - name: send ntfy notification image: registry.cuzo.dev/parrazam/drone-ntfy when: @@ -134,18 +98,12 @@ steps: url: https://ntfy.parravidales.es topic: pipelines priority: low - tags: release - username: - from_secret: ntfy_user - password: - from_secret: ntfy_password - -depends_on: -- manifest + token: + from_secret: ntfy_token image_pull_secrets: - custom_mirror_registry -trigger: - event: - - tag +depends_on: +- build +- release diff --git a/Dockerfile b/Dockerfile index 2325933..3f9d75a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,4 @@ FROM alpine -ADD script.sh /bin/ -RUN chmod +x /bin/script.sh -RUN apk -Uuv add curl ca-certificates -ENTRYPOINT /bin/script.sh +ADD bin/main /bin/main +RUN apk -Uuv add ca-certificates +ENTRYPOINT /bin/main diff --git a/cmd/drone-ntfy/config/config.go b/cmd/drone-ntfy/config/config.go index 803249d..d63380b 100644 --- a/cmd/drone-ntfy/config/config.go +++ b/cmd/drone-ntfy/config/config.go @@ -2,7 +2,7 @@ package config type App struct { BaseUrl string `env:"PLUGIN_URL" envDefault:"https://ntfy.sh"` - Topic string `env:"PLUGIN_TOPIC" envDefault:"undefined"` + Topic string `env:"PLUGIN_TOPIC,required"` Username string `env:"PLUGIN_USERNAME"` Password string `env:"PLUGIN_PASSWORD"` Token string `env:"PLUGIN_TOKEN"` @@ -21,6 +21,7 @@ type Drone struct { Tag string `env:"DRONE_TAG"` BuildLink string `env:"DRONE_BUILD_LINK"` CommitLink string `env:"DRONE_COMMIT_LINK"` + RepoName string `env:"DRONE_REPO_NAME"` } type Ci struct { diff --git a/cmd/drone-ntfy/main.go b/cmd/drone-ntfy/main.go index 48c9400..185c65f 100644 --- a/cmd/drone-ntfy/main.go +++ b/cmd/drone-ntfy/main.go @@ -32,7 +32,7 @@ func main() { func loadCfg() Config { - envErr := godotenv.Load(".env") + envErr := godotenv.Load() if envErr != nil { fmt.Printf("unable to load .env file: %e\n", envErr) } @@ -64,7 +64,7 @@ func updateAppConfig(cfg *Config) { cfg.App.Tags = append(cfg.App.Tags, cfg.Drone.Tag) cfg.App.Message = "Tag " + cfg.Drone.Tag + " created" } else { - cfg.App.Tags = append(cfg.App.Tags, "branch "+cfg.Ci.CommitBranch) + cfg.App.Tags = append(cfg.App.Tags, cfg.Drone.RepoName+"/"+cfg.Ci.CommitBranch) cfg.App.Message = "[" + cfg.Ci.CommitSha[0:8] + "] " + cfg.Ci.CommitMessage } } @@ -83,7 +83,7 @@ func addTagsBasedOnResult(cfg *Config) { func sendNotification(cfg *Config) { req, _ := http.NewRequest("POST", - cfg.App.BaseUrl + "/" + cfg.App.Topic, + cfg.App.BaseUrl+"/"+cfg.App.Topic, strings.NewReader(cfg.App.Message)) if cfg.App.Token != "" { @@ -94,7 +94,7 @@ func sendNotification(cfg *Config) { req.Header.Set("Title", cfg.App.Title) req.Header.Set("Priority", cfg.App.Priority) req.Header.Set("Tags", strings.Join(cfg.App.Tags, ",")) - req.Header.Set("Actions", "view, Build, "+cfg.Drone.BuildLink+"; view, Changes, "+cfg.Drone.CommitLink) + req.Header.Set("Actions", getActions(cfg)) res, err := http.DefaultClient.Do(req) if err != nil { log.Fatalf("error trying to notify the result. Error: %+v", err) @@ -103,3 +103,11 @@ func sendNotification(cfg *Config) { log.Fatalf("error from server. HTTP status: %d. Error: %e", res.StatusCode, err) } } + +func getActions(cfg *Config) string { + var buildLink = "view, Build, " + cfg.Drone.BuildLink + if strings.Contains(cfg.Ci.CommitRef, "refs/tags/") { + return buildLink + } + return buildLink + "; view, Changes, " + cfg.Drone.CommitLink +} -- 2.40.1 From c2046b1770a98c30069069dd5ac779c81ce49894 Mon Sep 17 00:00:00 2001 From: parra Date: Thu, 23 Feb 2023 20:55:42 +0100 Subject: [PATCH 4/5] Remove unused config vars --- cmd/drone-ntfy/config/config.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cmd/drone-ntfy/config/config.go b/cmd/drone-ntfy/config/config.go index d63380b..103da37 100644 --- a/cmd/drone-ntfy/config/config.go +++ b/cmd/drone-ntfy/config/config.go @@ -14,10 +14,7 @@ type App struct { } type Drone struct { - BuildNumber string `env:"DRONE_BUILD_NUMBER"` BuildStatus string `env:"DRONE_BUILD_STATUS"` - StageName string `env:"DRONE_STAGE_NUMBER"` - StageStatus string `env:"DRONE_STAGE_STATUS"` Tag string `env:"DRONE_TAG"` BuildLink string `env:"DRONE_BUILD_LINK"` CommitLink string `env:"DRONE_COMMIT_LINK"` @@ -25,7 +22,6 @@ type Drone struct { } type Ci struct { - RepoName string `env:"CI_REPO_NAME"` CommitMessage string `env:"CI_COMMIT_MESSAGE"` CommitSha string `env:"CI_COMMIT_SHA"` CommitBranch string `env:"CI_COMMIT_BRANCH"` -- 2.40.1 From 54b1e30f7cc91ec55c3e612bbf64b1e125a038e2 Mon Sep 17 00:00:00 2001 From: parra Date: Thu, 23 Feb 2023 20:59:25 +0100 Subject: [PATCH 5/5] Update go.mod --- go.mod | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 0f35684..b2ec15a 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,6 @@ module git.parravidales.es/parra/drone-ntfy go 1.19 require ( - github.com/caarlos0/env/v7 v7.0.0 // indirect - github.com/joho/godotenv v1.5.1 // indirect + github.com/caarlos0/env/v7 v7.0.0 + github.com/joho/godotenv v1.5.1 ) -- 2.40.1