internal/httpd/releaseactions.go

v1.32.0
gitbay/internal/httpd/releaseactions.go history · blame · raw

92 lines · 3238 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	// Preview: the page back with the notes rendered, nothing written.
31	// The form name carries the tag, because every release on the page
32	// has an edit box and only the one submitted shows its draft.
33	if wantsPreview(r) {
34		form := "release"
35		if r.FormValue("action") == "edit" {
36			form = "release:" + tag
37		}
38		s.releasesPage(w, r, form)
39		return
40	}
41	back := func(w http.ResponseWriter, r *http.Request, msg string) { s.backTo(w, r, "releases", msg) }
42	// The CLI's --yes guards against a mistyped tag; here the tag comes
43	// from the page, so the browser's own confirm field stands in.
44	if r.FormValue("action") == "delete" {
45		if ok, msg := confirmed(r, tag); !ok {
46			back(w, r, msg)
47			return
48		}
49		_, msg, code := s.runControlCode(u, []string{"release", "delete", repo, tag, "--yes"})
50		s.done(w, r, code, msg, back)
51		return
52	}
53	verb := "create"
54	if r.FormValue("action") == "edit" {
55		verb = "edit"
56	}
57	argv := []string{"release", verb, repo, tag}
58	if title != "" {
59		argv = append(argv, "--title", title)
60	}
61	// edit needs at least one field; create takes the tag alone.
62	if notes != "" || verb == "edit" {
63		argv = append(argv, "--notes", notes)
64	}
65	_, msg, code := s.runControlCode(u, argv)
66	s.done(w, r, code, msg, back)
67}
68
69func (s *Server) buildTriggerSubmit(w http.ResponseWriter, r *http.Request, u store.User) {
70	repo := r.PathValue("owner") + "/" + r.PathValue("repo")
71	job := strings.TrimSpace(r.FormValue("job"))
72	if job == "" {
73		s.backTo(w, r, "builds", "pick a job")
74		return
75	}
76	_, msg, code := s.runControlCode(u, []string{"build", "trigger", repo, job})
77	s.done(w, r, code, msg, func(w http.ResponseWriter, r *http.Request, msg string) { s.backTo(w, r, "builds", msg) })
78}
79
80// buildCancelSubmit withdraws a build. The page only offers the control
81// while a build is still queued; the command decides for real, so a stale
82// page posting against a build that has since finished sees the refusal
83// instead of a silent no-op.
84func (s *Server) buildCancelSubmit(w http.ResponseWriter, r *http.Request, u store.User) {
85	repo := r.PathValue("owner") + "/" + r.PathValue("repo")
86	n := r.PathValue("n")
87	back := func(w http.ResponseWriter, r *http.Request, msg string) {
88		s.backTo(w, r, "builds/"+n, msg)
89	}
90	_, msg, code := s.runControlCode(u, []string{"build", "cancel", repo, n})
91	s.done(w, r, code, msg, back)
92}