forked from justwatchcom/github-releases-notifier
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
138 lines (116 loc) · 3.4 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package main
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"strings"
"time"
"github.com/alexflint/go-arg"
"github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"
"github.com/joho/godotenv"
"github.com/prometheus/client_golang/prometheus/promhttp"
githubql "github.com/shurcooL/githubql"
"golang.org/x/oauth2"
)
// Repos from JSON file
type Repositories struct {
Names []string `json:"repos"`
}
// Config of env and args
type Config struct {
GithubToken string `arg:"env:GITHUB_TOKEN"`
Interval time.Duration `arg:"env:INTERVAL"`
LogLevel string `arg:"env:LOG_LEVEL"`
SlackHook string `arg:"env:SLACK_HOOK"`
IgnoreNonstable bool `arg:"env:IGNORE_NONSTABLE"`
Repositories []string `arg:"-r,separate"`
ReposFilePath string `arg:"env:REPOS_FILE_PATH"`
MetricsPort int `arg:"env:METRICS_PORT"`
}
// Token returns an oauth2 token or an error.
func (c Config) Token() *oauth2.Token {
return &oauth2.Token{AccessToken: c.GithubToken}
}
func main() {
_ = godotenv.Load()
c := Config{
Interval: time.Hour,
LogLevel: "info",
}
arg.MustParse(&c)
if c.MetricsPort == 0 {
c.MetricsPort = 8080
}
logger := log.NewJSONLogger(log.NewSyncWriter(os.Stdout))
logger = log.With(logger,
"ts", log.DefaultTimestampUTC,
"caller", log.Caller(5),
)
// level.SetKey("severity")
switch strings.ToLower(c.LogLevel) {
case "debug":
logger = level.NewFilter(logger, level.AllowDebug())
case "warn":
logger = level.NewFilter(logger, level.AllowWarn())
case "error":
logger = level.NewFilter(logger, level.AllowError())
default:
logger = level.NewFilter(logger, level.AllowInfo())
}
var repos Repositories
if c.ReposFilePath != "" {
// Reading repos from JSON file
jsonFromFile, err := os.Open(c.ReposFilePath)
if err != nil {
level.Error(logger).Log("Can't load JSON file at path:", c.ReposFilePath)
os.Exit(1)
}
defer jsonFromFile.Close()
content, err := ioutil.ReadAll(jsonFromFile)
if err != nil {
level.Error(logger).Log(err)
os.Exit(1)
}
err = json.Unmarshal(content, &repos)
if err != nil {
level.Error(logger).Log(err)
os.Exit(1)
}
}
if len(c.Repositories) == 0 && len(repos.Names) == 0 {
level.Error(logger).Log("msg", "no repositories to watch")
os.Exit(1)
}
tokenSource := oauth2.StaticTokenSource(c.Token())
client := oauth2.NewClient(context.Background(), tokenSource)
checker := &Checker{
logger: logger,
client: githubql.NewClient(client),
}
level.Info(logger).Log("msg", "Starting Prometheus metrics handler", "port", c.MetricsPort)
http.Handle("/metrics", promhttp.Handler())
go http.ListenAndServe(fmt.Sprintf(":%d", c.MetricsPort), nil)
// TODO: releases := make(chan Repository, len(c.Repositories))
releases := make(chan Repository)
go checker.Run(c.Interval, append(repos.Names, c.Repositories...), releases)
slack := SlackSender{Hook: c.SlackHook}
level.Info(logger).Log("msg", "waiting for new releases")
for repository := range releases {
if c.IgnoreNonstable && repository.Release.IsNonstable() {
level.Debug(logger).Log("msg", "not notifying about non-stable version", "version", repository.Release.Name)
continue
}
if err := slack.Send(repository); err != nil {
metricSlackSendErrorCounter.Inc()
level.Warn(logger).Log(
"msg", "failed to send release to messenger",
"err", err,
)
continue
}
}
}