diff --git a/.drone.yml b/.drone.yml index 53cd1f2..f01266f 100644 --- a/.drone.yml +++ b/.drone.yml @@ -3,8 +3,18 @@ type: docker name: build steps: +- name: Build Go app + image: registry.cuzo.dev/library/golang + volumes: + - name: deps + path: /go + commands: + - 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 + when: + branch: + - main privileged: true volumes: - name: manifest @@ -18,26 +28,14 @@ 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 volumes: - name: manifest path: docker @@ -52,25 +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_pull_secrets: - custom_mirror_registry @@ -94,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: @@ -102,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/.gitignore b/.gitignore new file mode 100644 index 0000000..2fe15e4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.vscode/ +bin/ +.env 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 new file mode 100644 index 0000000..103da37 --- /dev/null +++ b/cmd/drone-ntfy/config/config.go @@ -0,0 +1,29 @@ +package config + +type App struct { + BaseUrl string `env:"PLUGIN_URL" envDefault:"https://ntfy.sh"` + Topic string `env:"PLUGIN_TOPIC,required"` + 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 { + BuildStatus string `env:"DRONE_BUILD_STATUS"` + 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 { + 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 new file mode 100644 index 0000000..185c65f --- /dev/null +++ b/cmd/drone-ntfy/main.go @@ -0,0 +1,113 @@ +package main + +import ( + "fmt" + "log" + "net/http" + "os" + "strings" + + "git.parravidales.es/parra/drone-ntfy/cmd/drone-ntfy/config" + "github.com/caarlos0/env/v7" + "github.com/joho/godotenv" +) + +type Config struct { + App config.App + Drone config.Drone + Ci config.Ci +} + +func main() { + + fmt.Printf("Topic: %s\n", os.Environ()) + cfg := loadCfg() + + updateAppConfig(&cfg) + addTagsBasedOnResult(&cfg) + + fmt.Printf("App Config: %+v\n", cfg) + sendNotification(&cfg) +} + +func loadCfg() Config { + + envErr := godotenv.Load() + 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, cfg.Drone.RepoName+"/"+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", getActions(cfg)) + 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) + } +} + +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 +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..b2ec15a --- /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 + github.com/joho/godotenv v1.5.1 +) 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=