internal/httpd/releaseactions.go

353f68a2e57ac692964b73ae1f9acd91fcdcae20
gitbay/internal/httpd/releaseactions.go history · blame · raw

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}