internal/httpd/releaseactions.go
81 lines · 2883 bytes
1package httpd
2
3import (
4 "fmt"
5 "net/http"
6 "strings"
7
8 "gitbay.org/gitbay/internal/store"
9)
10
11// Release and build actions. As elsewhere, the browser chooses arguments
12// and the command decides: tag existence, access, and the gates around
13// archived repositories all stay in one implementation.
14
15func (s *Server) backTo(w http.ResponseWriter, r *http.Request, page, msg string) {
16 dest := fmt.Sprintf("/%s/%s/%s", r.PathValue("owner"), r.PathValue("repo"), page)
17 s.setFlash(w, msg)
18 http.Redirect(w, r, dest, http.StatusSeeOther)
19}
20
21func (s *Server) releaseSubmit(w http.ResponseWriter, r *http.Request, u store.User) {
22 repo := r.PathValue("owner") + "/" + r.PathValue("repo")
23 tag := strings.TrimSpace(r.FormValue("tag"))
24 title := strings.TrimSpace(r.FormValue("title"))
25 notes := strings.TrimSpace(r.FormValue("notes"))
26 if tag == "" {
27 s.backTo(w, r, "releases", "pick a tag")
28 return
29 }
30 back := func(w http.ResponseWriter, r *http.Request, msg string) { s.backTo(w, r, "releases", msg) }
31 // The CLI's --yes guards against a mistyped tag; here the tag comes
32 // from the page, so the browser's own confirm field stands in.
33 if r.FormValue("action") == "delete" {
34 if ok, msg := confirmed(r, tag); !ok {
35 back(w, r, msg)
36 return
37 }
38 _, msg, code := s.runControlCode(u, []string{"release", "delete", repo, tag, "--yes"})
39 s.done(w, r, code, msg, back)
40 return
41 }
42 verb := "create"
43 if r.FormValue("action") == "edit" {
44 verb = "edit"
45 }
46 argv := []string{"release", verb, repo, tag}
47 if title != "" {
48 argv = append(argv, "--title", title)
49 }
50 // edit needs at least one field; create takes the tag alone.
51 if notes != "" || verb == "edit" {
52 argv = append(argv, "--notes", notes)
53 }
54 _, msg, code := s.runControlCode(u, argv)
55 s.done(w, r, code, msg, back)
56}
57
58func (s *Server) buildTriggerSubmit(w http.ResponseWriter, r *http.Request, u store.User) {
59 repo := r.PathValue("owner") + "/" + r.PathValue("repo")
60 job := strings.TrimSpace(r.FormValue("job"))
61 if job == "" {
62 s.backTo(w, r, "builds", "pick a job")
63 return
64 }
65 _, msg, code := s.runControlCode(u, []string{"build", "trigger", repo, job})
66 s.done(w, r, code, msg, func(w http.ResponseWriter, r *http.Request, msg string) { s.backTo(w, r, "builds", msg) })
67}
68
69// buildCancelSubmit withdraws a build. The page only offers the control
70// while a build is still queued; the command decides for real, so a stale
71// page posting against a build that has since finished sees the refusal
72// instead of a silent no-op.
73func (s *Server) buildCancelSubmit(w http.ResponseWriter, r *http.Request, u store.User) {
74 repo := r.PathValue("owner") + "/" + r.PathValue("repo")
75 n := r.PathValue("n")
76 back := func(w http.ResponseWriter, r *http.Request, msg string) {
77 s.backTo(w, r, "builds/"+n, msg)
78 }
79 _, msg, code := s.runControlCode(u, []string{"build", "cancel", repo, n})
80 s.done(w, r, code, msg, back)
81}