+84
-48
knotserver/internal.go
+84
-48
knotserver/internal.go
···
27
)
28
29
type InternalHandle struct {
30
-
db *db.DB
31
-
c *config.Config
32
-
e *rbac.Enforcer
33
-
l *slog.Logger
34
-
n *notifier.Notifier
35
}
36
37
func (h *InternalHandle) PushAllowed(w http.ResponseWriter, r *http.Request) {
···
121
// non-fatal
122
}
123
124
-
if (line.NewSha.String() != line.OldSha.String()) && line.OldSha.IsZero() {
125
-
msg, err := h.replyCompare(line, repoDid, gitRelativeDir, repoName, r.Context())
126
-
if err != nil {
127
-
l.Error("failed to reply with compare link", "err", err, "line", line, "did", gitUserDid, "repo", gitRelativeDir)
128
-
// non-fatal
129
-
} else {
130
-
for msgLine := range msg {
131
-
resp.Messages = append(resp.Messages, msg[msgLine])
132
-
}
133
-
}
134
}
135
136
err = h.triggerPipeline(&resp.Messages, line, gitUserDid, repoDid, repoName, pushOptions)
···
143
writeJSON(w, resp)
144
}
145
146
-
func (h *InternalHandle) replyCompare(line git.PostReceiveLine, repoOwner string, gitRelativeDir string, repoName string, ctx context.Context) ([]string, error) {
147
-
l := h.l.With("handler", "replyCompare")
148
-
userIdent, err := idresolver.DefaultResolver().ResolveIdent(ctx, repoOwner)
149
-
user := repoOwner
150
-
if err != nil {
151
-
l.Error("Failed to fetch user identity", "err", err)
152
-
// non-fatal
153
-
} else {
154
-
user = userIdent.Handle.String()
155
-
}
156
-
gr, err := git.PlainOpen(gitRelativeDir)
157
-
if err != nil {
158
-
l.Error("Failed to open git repository", "err", err)
159
-
return []string{}, err
160
-
}
161
-
defaultBranch, err := gr.FindMainBranch()
162
-
if err != nil {
163
-
l.Error("Failed to fetch default branch", "err", err)
164
-
return []string{}, err
165
-
}
166
-
if line.Ref == plumbing.NewBranchReferenceName(defaultBranch).String() {
167
-
return []string{}, nil
168
-
}
169
-
ZWS := "\u200B"
170
-
var msg []string
171
-
msg = append(msg, ZWS)
172
-
msg = append(msg, fmt.Sprintf("Create a PR pointing to %s", defaultBranch))
173
-
msg = append(msg, fmt.Sprintf("\t%s/%s/%s/compare/%s...%s", h.c.AppViewEndpoint, user, repoName, defaultBranch, strings.TrimPrefix(line.Ref, "refs/heads/")))
174
-
msg = append(msg, ZWS)
175
-
return msg, nil
176
-
}
177
-
178
func (h *InternalHandle) insertRefUpdate(line git.PostReceiveLine, gitUserDid, repoDid, repoName string) error {
179
didSlashRepo, err := securejoin.SecureJoin(repoDid, repoName)
180
if err != nil {
···
220
return errors.Join(errs, h.db.InsertEvent(event, h.n))
221
}
222
223
-
func (h *InternalHandle) triggerPipeline(clientMsgs *[]string, line git.PostReceiveLine, gitUserDid, repoDid, repoName string, pushOptions PushOptions) error {
224
if pushOptions.skipCi {
225
return nil
226
}
···
315
return h.db.InsertEvent(event, h.n)
316
}
317
318
func Internal(ctx context.Context, c *config.Config, db *db.DB, e *rbac.Enforcer, n *notifier.Notifier) http.Handler {
319
r := chi.NewRouter()
320
l := log.FromContext(ctx)
321
l = log.SubLogger(l, "internal")
322
323
h := InternalHandle{
324
db,
···
326
e,
327
l,
328
n,
329
}
330
331
r.Get("/push-allowed", h.PushAllowed)
···
27
)
28
29
type InternalHandle struct {
30
+
db *db.DB
31
+
c *config.Config
32
+
e *rbac.Enforcer
33
+
l *slog.Logger
34
+
n *notifier.Notifier
35
+
res *idresolver.Resolver
36
}
37
38
func (h *InternalHandle) PushAllowed(w http.ResponseWriter, r *http.Request) {
···
122
// non-fatal
123
}
124
125
+
err = h.emitCompareLink(&resp.Messages, line, repoDid, repoName)
126
+
if err != nil {
127
+
l.Error("failed to reply with compare link", "err", err, "line", line, "did", gitUserDid, "repo", gitRelativeDir)
128
+
// non-fatal
129
}
130
131
err = h.triggerPipeline(&resp.Messages, line, gitUserDid, repoDid, repoName, pushOptions)
···
138
writeJSON(w, resp)
139
}
140
141
func (h *InternalHandle) insertRefUpdate(line git.PostReceiveLine, gitUserDid, repoDid, repoName string) error {
142
didSlashRepo, err := securejoin.SecureJoin(repoDid, repoName)
143
if err != nil {
···
183
return errors.Join(errs, h.db.InsertEvent(event, h.n))
184
}
185
186
+
func (h *InternalHandle) triggerPipeline(
187
+
clientMsgs *[]string,
188
+
line git.PostReceiveLine,
189
+
gitUserDid string,
190
+
repoDid string,
191
+
repoName string,
192
+
pushOptions PushOptions,
193
+
) error {
194
if pushOptions.skipCi {
195
return nil
196
}
···
285
return h.db.InsertEvent(event, h.n)
286
}
287
288
+
func (h *InternalHandle) emitCompareLink(
289
+
clientMsgs *[]string,
290
+
line git.PostReceiveLine,
291
+
repoDid string,
292
+
repoName string,
293
+
) error {
294
+
// this is a second push to a branch, don't reply with the link again
295
+
if !line.OldSha.IsZero() {
296
+
return nil
297
+
}
298
+
299
+
// the ref was not updated to a new hash, don't reply with the link
300
+
//
301
+
// NOTE: do we need this?
302
+
if line.NewSha.String() == line.OldSha.String() {
303
+
return nil
304
+
}
305
+
306
+
pushedRef := plumbing.ReferenceName(line.Ref)
307
+
308
+
userIdent, err := h.res.ResolveIdent(context.Background(), repoDid)
309
+
user := repoDid
310
+
if err == nil {
311
+
user = userIdent.Handle.String()
312
+
}
313
+
314
+
didSlashRepo, err := securejoin.SecureJoin(repoDid, repoName)
315
+
if err != nil {
316
+
return err
317
+
}
318
+
319
+
repoPath, err := securejoin.SecureJoin(h.c.Repo.ScanPath, didSlashRepo)
320
+
if err != nil {
321
+
return err
322
+
}
323
+
324
+
gr, err := git.PlainOpen(repoPath)
325
+
if err != nil {
326
+
return err
327
+
}
328
+
329
+
defaultBranch, err := gr.FindMainBranch()
330
+
if err != nil {
331
+
return err
332
+
}
333
+
334
+
// pushing to default branch
335
+
if pushedRef == plumbing.NewBranchReferenceName(defaultBranch) {
336
+
return nil
337
+
}
338
+
339
+
// pushing a tag, don't prompt the user the open a PR
340
+
if pushedRef.IsTag() {
341
+
return nil
342
+
}
343
+
344
+
ZWS := "\u200B"
345
+
*clientMsgs = append(*clientMsgs, ZWS)
346
+
*clientMsgs = append(*clientMsgs, fmt.Sprintf("Create a PR pointing to %s", defaultBranch))
347
+
*clientMsgs = append(*clientMsgs, fmt.Sprintf("\t%s/%s/%s/compare/%s...%s", h.c.AppViewEndpoint, user, repoName, defaultBranch, strings.TrimPrefix(line.Ref, "refs/heads/")))
348
+
*clientMsgs = append(*clientMsgs, ZWS)
349
+
return nil
350
+
}
351
+
352
func Internal(ctx context.Context, c *config.Config, db *db.DB, e *rbac.Enforcer, n *notifier.Notifier) http.Handler {
353
r := chi.NewRouter()
354
l := log.FromContext(ctx)
355
l = log.SubLogger(l, "internal")
356
+
res := idresolver.DefaultResolver()
357
358
h := InternalHandle{
359
db,
···
361
e,
362
l,
363
n,
364
+
res,
365
}
366
367
r.Get("/push-allowed", h.PushAllowed)