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.
Create and edit releases from the browser
ec34301375902f6b08c0171bf91b98cbcc55c63c · Keenan Nemetz · 15d ago · parent 09b15120
Create and edit releases from the browser Maintainers get a New release form that writes the same annotated tag the CLI writes: tag name, target commit, and notes become the tag message, with the account as tagger. Edit notes rewrites the tag message only while no artifact is attached, matching the release-immutability rule; lightweight tags and releases with files stay locked. Tag names are validated, existing tags are refused, reserved page names are rejected, and both actions are audited.
server/web/templates/release_form.html +35
| @@ -0,0 +1,35 @@ | |||
| 1 | {{define "release_form"}} | ||
| 2 | {{template "header" .}} | ||
| 3 | {{template "repohead" (nav .Name "releases" .CanAdmin)}} | ||
| 4 | |||
| 5 | <div class="page-head"> | ||
| 6 | <div class="page-head-main"> | ||
| 7 | <h1>{{if .Editing}}Edit release {{.Tag}}{{else}}New release{{end}}</h1> | ||
| 8 | <p class="page-sub">{{if .Editing}}The tag name and commit are fixed. Notes become the annotated tag's message.{{else}}A release is an annotated tag: its notes are the tag message and its code is the tagged tree.{{end}}</p> | ||
| 9 | </div> | ||
| 10 | </div> | ||
| 11 | |||
| 12 | {{if .Error}}<div class="flash bad">{{.Error}}</div>{{end}} | ||
| 13 | |||
| 14 | <form method="post" action="{{if .Editing}}/r/{{.Name}}/releases/edit{{else}}/r/{{.Name}}/releases{{end}}" class="form-block"> | ||
| 15 | <input type="hidden" name="csrf" value="{{.CSRF}}"> | ||
| 16 | <div class="card form-card"> | ||
| 17 | {{if .Editing}}<input type="hidden" name="tag" value="{{.Tag}}">{{end}} | ||
| 18 | <label>Tag | ||
| 19 | <input type="text" name="tag" value="{{.Tag}}" {{if .Editing}}readonly{{else}}required autocomplete="off" placeholder="v1.0.0"{{end}}> | ||
| 20 | </label> | ||
| 21 | <label>Target | ||
| 22 | <input type="text" name="target" value="{{.Target}}" {{if .Editing}}readonly{{else}}required list="release-refs" autocomplete="off"{{end}}> | ||
| 23 | {{if not .Editing}}<datalist id="release-refs">{{range .Refs}}<option value="{{.}}">{{.}}</option>{{end}}</datalist>{{end}} | ||
| 24 | </label> | ||
| 25 | <label>Release notes | ||
| 26 | <textarea name="notes" required rows="12" placeholder="What changed in this release?">{{.Notes}}</textarea> | ||
| 27 | </label> | ||
| 28 | </div> | ||
| 29 | <div class="form-actions"> | ||
| 30 | <a class="button secondary" href="/r/{{.Name}}/releases">Cancel</a> | ||
| 31 | {{if not .Locked}}<button type="submit">{{icon "tag"}}{{if .Editing}}Save notes{{else}}Create release{{end}}</button>{{end}} | ||
| 32 | </div> | ||
| 33 | </form> | ||
| 34 | {{template "footer" .}} | ||
| 35 | {{end}} | ||