-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.go
101 lines (85 loc) · 3.02 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
// Copyright 2022 Unknwon. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package main
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"github.com/flamego/flamego"
"github.com/google/go-github/v45/github"
log "unknwon.dev/clog/v2"
"github.com/codenotify/codenotify.run/internal/conf"
"github.com/codenotify/codenotify.run/internal/osutil"
)
func main() {
if err := log.NewConsole(); err != nil {
panic(err)
}
log.Info("Codenotify as a Service!")
if conf.BuildTime != "" {
log.Info("Build time: %s", conf.BuildTime)
log.Info("Build commit: %s", conf.BuildCommit)
}
config, err := conf.Load()
if err != nil {
log.Fatal("Failed to load configuration: %v", err)
}
f := flamego.Classic()
f.Get("/", func(c flamego.Context) {
c.Redirect("https://github.com/codenotify/codenotify.run")
})
f.Get("/runs/{runID}", func(c flamego.Context) ([]byte, error) {
logPath := logPathByRunID(config.Server.LogsRootDir, c.Param("runID"))
if !osutil.IsFile(logPath) {
return []byte("The run log no longer exists"), nil
}
return os.ReadFile(logPath)
})
f.Post("/-/webhook", func(r *http.Request) (int, string) {
event := r.Header.Get("X-GitHub-Event")
log.Trace("Received event: %s", event)
if event != "pull_request" {
return http.StatusOK, fmt.Sprintf("Event %q has been received but nothing to do", event)
}
body, err := io.ReadAll(r.Body)
if err != nil {
return http.StatusInternalServerError, fmt.Sprintf("Failed to read request body: %v", err)
}
if config.GitHubApp.WebhookSecret != "" {
ok, err := validateGitHubWebhookSignature256(r.Header.Get("X-Hub-Signature-256"), config.GitHubApp.WebhookSecret, body)
if err != nil {
return http.StatusInternalServerError, fmt.Sprintf("Failed to validate signature: %v", err)
} else if !ok {
return http.StatusBadRequest, `Mismatched payload signature for "X-Hub-Signature-256"`
}
}
var payload github.PullRequestEvent
err = json.Unmarshal(body, &payload)
if err != nil {
return http.StatusBadRequest, fmt.Sprintf("Failed to decode payload: %v", err)
}
if payload.Installation == nil || payload.Installation.ID == nil {
return http.StatusBadRequest, "No installation or installation ID"
} else if payload.Action == nil {
return http.StatusBadRequest, "No action"
}
if payload.PullRequest.Draft != nil && *payload.PullRequest.Draft {
return http.StatusOK, "Skip draft pull request"
}
switch *payload.Action {
case "opened", "ready_for_review":
go reportCommitStatus(context.Background(), config, &payload, handlePullRequestOpen)
case "synchronize", "reopened":
go reportCommitStatus(context.Background(), config, &payload, handlePullRequestSynchronize)
default:
return http.StatusOK, fmt.Sprintf("Event %q with action %q has been received but nothing to do", event, *payload.Action)
}
return http.StatusAccepted, http.StatusText(http.StatusAccepted)
})
log.Info("Available on %s", config.Server.ExternalURL)
f.Run()
}