internal/web/templates/settings.html
212 lines · 13160 bytes
1{{define "width"}}wide{{end}}
2{{define "title"}}settings · {{.Repo.OwnerName}}/{{.Repo.Name}}{{end}}
3{{define "content"}}
4{{$base := printf "/%s/%s/settings" .Repo.OwnerName .Repo.Name}}
5<h1>Settings</h1>
6{{if .Notice}}{{if .Saved}}<p class="notice" role="status">{{.Notice}}</p>{{else}}<p class="error" role="alert">{{.Notice}}</p>{{end}}{{end}}
7<div class="withcol narrow">
8<nav class="sidecol" aria-label="Sections">
9<details class="sidedrop">
10<summary><span class="sideword">Sections</span></summary>
11 <div class="grp"><h2 class="colhead">Sections</h2>
12 <ul>
13 <li><a href="#identity">Identity</a></li>
14 <li><a href="#access">Access</a></li>
15 <li><a href="#gates">Merge gates</a></li>
16 <li><a href="#branches">Protected branches</a></li>
17 <li><a href="#tags">Protected tags</a></li>
18 <li><a href="#deps">Dependencies</a></li>
19 <li><a href="#runners">Runners</a></li>
20 <li><a href="#lifecycle">Lifecycle</a></li>
21 </ul></div>
22</details>
23</nav>
24<div class="colmain">
25
26<section id="identity"><h2>Identity</h2>
27<form method="post" action="{{$base}}" class="setform">
28 <input type="hidden" name="field" value="description">
29 <div><label for="description">Description</label></div>
30 <div><input type="text" id="description" name="description" value="{{or (index .Submitted "description") .Desc}}" placeholder="one line, shown in listings"></div>
31 <div><button type="submit">Save</button></div>
32</form>
33<form method="post" action="{{$base}}" class="setform">
34 <input type="hidden" name="field" value="website">
35 <div><label for="website">Website</label></div>
36 <div><input type="text" id="website" name="website" value="{{or (index .Submitted "website") .Repo.Settings.Website}}" placeholder="https://example.org"></div>
37 <div><button type="submit" class="btn">Save</button></div>
38</form>
39<form method="post" action="{{$base}}" class="setform">
40 <input type="hidden" name="field" value="topics">
41 <div><label for="topics">Topics</label><p class="hint">Comma separated, lower case.</p></div>
42 <div><input type="text" id="topics" name="topics" value="{{or (index .Submitted "topics") (join .Topics ", ")}}"></div>
43 <div><button type="submit" class="btn">Save</button></div>
44</form>
45{{if .Branches}}<form method="post" action="{{$base}}" class="setform">
46 <input type="hidden" name="field" value="default-branch">
47 <div><label for="default-branch">Default branch</label></div>
48 <div><select id="default-branch" name="default-branch">{{$cur := .Repo.DefaultBranch}}{{range .Branches}}<option value="{{.Name}}"{{if eq .Name $cur}} selected{{end}}>{{.Name}}</option>{{end}}</select></div>
49 <div><button type="submit" class="btn">Save</button></div>
50</form>{{end}}
51</section>
52
53<section id="access"><h2>Access</h2>
54<form method="post" action="{{$base}}" class="setform">
55 <input type="hidden" name="field" value="visibility">
56 <div><span class="fieldname">Visibility</span></div>
57 <div class="check">
58 <label><input type="radio" name="visibility" value="public"{{if eq .Repo.Visibility "public"}} checked{{end}}> Public</label>
59 <label><input type="radio" name="visibility" value="private"{{if eq .Repo.Visibility "private"}} checked{{end}}> Private</label>
60 </div>
61 <div><button type="submit" class="btn">Save</button></div>
62</form>
63<form method="post" action="{{$base}}" class="setform">
64 <input type="hidden" name="field" value="git-daemon">
65 <div><label for="git-daemon">Serve over git://</label><p class="hint">Public repositories only.</p></div>
66 <div class="check"><input type="checkbox" id="git-daemon" name="git-daemon" value="on"{{if .Repo.Settings.GitDaemon}} checked{{end}}></div>
67 <div><button type="submit" class="btn">Save</button></div>
68</form>
69</section>
70
71<section id="gates"><h2>Merge gates</h2>
72<p class="meta">Checked before a merge, in this order: checks, approvals, resolved threads, signatures.</p>
73<form method="post" action="{{$base}}" class="setform">
74 <input type="hidden" name="field" value="require-checks">
75 <div><label for="require-checks">Required checks</label><p class="hint">Requires CI to succeed.{{with .Repo.Settings.RequiredContexts}} Also waits for {{range $i, $c := .}}{{if $i}}, {{end}}<code>{{$c}}</code>{{end}} until they report{{if not $.Repo.Settings.RequireChecks}}, once this is on{{end}}.{{end}}</p></div>
76 <div class="check"><input type="checkbox" id="require-checks" name="require-checks" value="on"{{if .Repo.Settings.RequireChecks}} checked{{end}}></div>
77 <div><button type="submit" class="btn">Save</button></div>
78</form>
79<form method="post" action="{{$base}}" class="setform">
80 <input type="hidden" name="field" value="require-contexts">
81 <div><label for="contexts">Required contexts</label><p class="hint">Statuses the checks gate waits for until they report, separated by spaces. Saving any turns required checks on; saving none leaves it as it is.</p></div>
82 <div><input type="text" id="contexts" name="contexts" value="{{range $i, $c := .Repo.Settings.RequiredContexts}}{{if $i}} {{end}}{{$c}}{{end}}" autocomplete="off"></div>
83 <div><button type="submit" class="btn">Save</button></div>
84</form>
85<form method="post" action="{{$base}}" class="setform">
86 <input type="hidden" name="field" value="require-approvals">
87 <div><label for="approvals">Approvals</label><p class="hint">Approvals from anyone with write access. Zero means none required.</p></div>
88 <div class="num"><input type="number" id="approvals" name="approvals" min="0" max="10" value="{{.Repo.Settings.RequireApprovals}}"></div>
89 <div><button type="submit" class="btn">Save</button></div>
90</form>
91<form method="post" action="{{$base}}" class="setform">
92 <input type="hidden" name="field" value="require-resolved">
93 <div><label for="require-resolved">Review threads</label><p class="hint">Every thread on the diff must be resolved before merging.</p></div>
94 <div class="check"><input type="checkbox" id="require-resolved" name="require-resolved" value="on"{{if .Repo.Settings.RequireResolved}} checked{{end}}></div>
95 <div><button type="submit" class="btn">Save</button></div>
96</form>
97<form method="post" action="{{$base}}" class="setform">
98 <input type="hidden" name="field" value="require-codeowners">
99 <div><label for="require-codeowners">CODEOWNERS</label><p class="hint">Code owners must approve.</p></div>
100 <div class="check"><input type="checkbox" id="require-codeowners" name="require-codeowners" value="on"{{if .Repo.Settings.RequireCodeowners}} checked{{end}}></div>
101 <div><button type="submit" class="btn">Save</button></div>
102</form>
103<form method="post" action="{{$base}}" class="setform">
104 <input type="hidden" name="field" value="require-signed">
105 <div><label for="require-signed">Signed commits</label><p class="hint">Every commit in the request must carry a verified signature. Squash and merge strategies are refused, since both mint an unsigned commit.</p></div>
106 <div class="check"><input type="checkbox" id="require-signed" name="require-signed" value="on"{{if .Repo.Settings.RequireSignedCommits}} checked{{end}}></div>
107 <div><button type="submit" class="btn">Save</button></div>
108</form>
109</section>
110
111<section id="branches"><h2>Protected branches</h2>
112{{if .Repo.Settings.ProtectedBranches}}
113<ul class="protlist">
114{{$mr := .Repo.Settings.RequireMR}}{{range .Repo.Settings.ProtectedBranches}}<li><code>{{.}}</code>{{if $mr}} <span class="hint">Direct pushes refused, merge requests only.</span>{{end}}
115 <form method="post" action="{{$base}}" class="inline">
116 <input type="hidden" name="field" value="unprotect">
117 <input type="hidden" name="branch" value="{{.}}">
118 <button type="submit" class="danger">Unprotect</button>
119 </form></li>
120{{end}}
121</ul>
122{{else}}<p class="meta">No protected branches. A protected branch refuses deletion and force-pushes.</p>{{end}}
123<form method="post" action="{{$base}}" class="setform">
124 <input type="hidden" name="field" value="protect">
125 <div><label for="branch">Protect a branch</label></div>
126 <div><select id="branch" name="branch">{{range .Branches}}<option value="{{.Name}}">{{.Name}}</option>{{end}}</select></div>
127 <div><button type="submit" class="btn">Protect</button></div>
128</form>
129<form method="post" action="{{$base}}" class="setform">
130 <input type="hidden" name="field" value="require-mr">
131 <div><label for="require-mr">Require merge requests</label><p class="hint">Every protected branch changes through a merge request. A direct push is refused in pre-receive.</p></div>
132 <div class="check"><input type="checkbox" id="require-mr" name="require-mr" value="on"{{if .Repo.Settings.RequireMR}} checked{{end}}></div>
133 <div><button type="submit" class="btn">Save</button></div>
134</form>
135</section>
136
137<section id="tags"><h2>Protected tags</h2>
138{{if .Repo.Settings.ProtectedTags}}
139<ul class="protlist">
140{{range .Repo.Settings.ProtectedTags}}<li><code>{{.}}</code>
141 <form method="post" action="{{$base}}" class="inline">
142 <input type="hidden" name="field" value="unprotect-tag">
143 <input type="hidden" name="glob" value="{{.}}">
144 <button type="submit" class="danger">Unprotect</button>
145 </form></li>
146{{end}}
147</ul>
148{{else}}<p class="meta">No protected tags. A tag matching a protected glob is created once and refuses moves and deletion. A tag a release is anchored to refuses both regardless.</p>{{end}}
149<form method="post" action="{{$base}}" class="setform">
150 <input type="hidden" name="field" value="protect-tag">
151 <div><label for="glob">Protect tags matching</label></div>
152 <div><input type="text" id="glob" name="glob" placeholder="v*"></div>
153 <div><button type="submit" class="btn">Protect</button></div>
154</form>
155</section>
156
157<section id="deps"><h2>Dependencies</h2>
158<form method="post" action="{{$base}}" class="setform">
159 <input type="hidden" name="field" value="deps">
160 <div><label for="deps-enabled">Check for updates</label><p class="hint">Evaluates the manifests on <code>{{.Repo.DefaultBranch}}</code> and opens an issue. Go, NPM, Crates, and PyPI only.</p></div>
161 <div class="check"><input type="checkbox" id="deps-enabled" name="deps" value="on"{{if .DepsEnabled}} checked{{end}}></div>
162 <div><button type="submit" class="btn">Save</button></div>
163</form>
164{{if .DepsEnabled}}
165<p class="meta">Last checked {{if .Deps.LastCheck}}{{when .Deps.LastCheck}}{{else}}never{{end}}{{if .Deps.IssueNumber}} · <a href="/{{.Repo.OwnerName}}/{{.Repo.Name}}/issues/{{.Deps.IssueNumber}}">#{{.Deps.IssueNumber}}</a>{{end}}</p>
166{{if .Deps.LastError}}<p class="error" role="alert">{{.Deps.LastError}}</p>{{end}}
167{{if .Deps.Behind}}<div class="tablewrap"><table class="keys">
168<tr class="cols"><th scope="col">dependency</th><th scope="col">pinned</th><th scope="col">latest</th></tr>
169{{range .Deps.Behind}}<tr>
170 <td class="mono">{{.Ecosystem}} {{.Name}}</td>
171 <td class="mono">{{.Current}}</td>
172 <td class="mono">{{.Latest}}</td>
173</tr>
174{{end}}</table></div>
175{{else}}<p class="none">Nothing behind{{if not .Deps.LastCheck}} — the first check has not run yet{{end}}.</p>{{end}}
176{{end}}
177</section>
178
179<section id="runners"><h2>Runners</h2>
180{{if .Runners}}
181<ul class="protlist">
182{{range .Runners}}<li><code>{{.Fingerprint}}</code> <span class="meta">{{.Username}}{{if .LastSeen}}, last poll {{when .LastSeen}}{{else}}, never polled{{end}}{{if .BuildNumber}}, running {{.BuildRepo}} #{{.BuildNumber}} {{.BuildJob}}{{end}}</span>
183 <form method="post" action="{{$base}}" class="inline">
184 <input type="hidden" name="field" value="runner-remove">
185 <input type="hidden" name="fingerprint" value="{{.Fingerprint}}">
186 <button type="submit" class="danger">Detach</button>
187 </form></li>
188{{end}}
189</ul>
190{{else}}<p class="meta">No runners attached. Builds for this repository run on the runners attached here; a repository with none queues builds nothing claims.</p>{{end}}
191<form method="post" action="{{$base}}" class="setform stack">
192 <input type="hidden" name="field" value="runner-add">
193 <label for="runner-key">Attach a runner</label>
194 <p class="hint">Install <code>gitbay-runner</code>, run <code>gitbay-runner init</code>, and paste the key it prints. The runner builds your commits with the repository's secrets; merge requests from forks wait unless it runs with <code>-untrusted</code>.</p>
195 <textarea id="runner-key" name="key" rows="3" spellcheck="false" placeholder="ssh-ed25519 AAAA… (from gitbay-runner init)">{{index .Submitted "key"}}</textarea>
196 <button type="submit" class="btn">Attach</button>
197</form>
198</section>
199
200<section id="lifecycle"><h2>Lifecycle</h2>
201<form method="post" action="{{$base}}" class="setform">
202 <input type="hidden" name="field" value="archive">
203 <div><label for="archive">Archived</label><p class="hint">Read-only for everyone. Issues and requests close to new activity. Reversible.</p></div>
204 <div class="check"><input type="checkbox" id="archive" name="archive" value="on"{{if .Repo.Settings.Archived}} checked{{end}}></div>
205 <div><button type="submit" {{if .Repo.Settings.Archived}}class="btn"{{else}}class="danger"{{end}}>Save</button></div>
206</form>
207<p class="meta">Deleting or transferring a repository is a CLI operation:
208<code>gitbay repo delete {{.Repo.OwnerName}}/{{.Repo.Name}} --yes</code></p>
209</section>
210</div>
211</div>
212{{end}}