vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
Split repository settings into tabs
e189a23e457b6aa01a35a4586586713cdc2d426d · Keenan Nemetz · 1d ago · parent 87ebcc5a
Split repository settings into tabs One page held four audiences and ten forms. Each part is now its own tab: General for the repository's own fields, Access for the instance-admin rules, Secrets for the values jobs read, and Danger for rename and delete. A tab is offered only to the accounts that may use it, and a viewer with one tab gets no row at all. The Access and Secrets tabs, and the failures on each, keep their own URLs so a redirect and an error land where the form was; the Access and Secrets fragments survive as deep links.
server/web/secrets.go +4−3
| @@ -92,12 +92,12 @@ func (w *Web) DeleteSecret(rw http.ResponseWriter, r *http.Request) { | |||
| 92 | 92 | } | |
| 93 | 93 | ||
| 94 | 94 | func (w *Web) redirectSecrets(rw http.ResponseWriter, r *http.Request, ctx *settingsContext, saved, deleted string) { | |
| 95 | target := "/r/" + ctx.m.Name + "/settings#secrets" | ||
| 95 | target := "/r/" + ctx.m.Name + "/settings?tab=secrets#secrets" | ||
| 96 | 96 | switch { | |
| 97 | 97 | case saved != "": | |
| 98 | target = "/r/" + ctx.m.Name + "/settings?secret_saved=" + url.QueryEscape(saved) + "#secrets" | ||
| 98 | target = "/r/" + ctx.m.Name + "/settings?tab=secrets&secret_saved=" + url.QueryEscape(saved) + "#secrets" | ||
| 99 | 99 | case deleted != "": | |
| 100 | target = "/r/" + ctx.m.Name + "/settings?secret_deleted=" + url.QueryEscape(deleted) + "#secrets" | ||
| 100 | target = "/r/" + ctx.m.Name + "/settings?tab=secrets&secret_deleted=" + url.QueryEscape(deleted) + "#secrets" | ||
| 101 | 101 | } | |
| 102 | 102 | http.Redirect(rw, r, target, http.StatusSeeOther) | |
| 103 | 103 | } | |
| @@ -106,6 +106,7 @@ func (w *Web) redirectSecrets(rw http.ResponseWriter, r *http.Request, ctx *sett | |||
| 106 | 106 | // not echoed back: a refused value is not put into the page that just refused it. | |
| 107 | 107 | func (w *Web) secretFailure(rw http.ResponseWriter, r *http.Request, ctx *settingsContext, msg string) { | |
| 108 | 108 | v := w.settingsView(r, ctx) | |
| 109 | v.focusTab("secrets") | ||
| 109 | 110 | v.SecretError = msg | |
| 110 | 111 | w.render(rw, "settings", v, http.StatusBadRequest) | |
| 111 | 112 | } | |