| @@ -3,147 +3,141 @@ |
| 3 | 3 | {{define "content"}} |
| 4 | 4 | {{$base := printf "/%s/%s/settings" .Repo.OwnerName .Repo.Name}} |
| 5 | 5 | <h1>Settings</h1> |
| 6 | | {{if .Notice}}<p class="error" role="alert">{{.Notice}}</p>{{end}} |
| 6 | {{if .Notice}}{{if .Saved}}<p class="notice" role="status">{{.Notice}}</p>{{else}}<p class="error" role="alert">{{.Notice}}</p>{{end}}{{end}} |
| 7 | <nav class="sections" aria-label="Sections"><a href="#identity">Identity</a><a href="#access">Access</a><a href="#gates">Merge gates</a><a href="#branches">Protected branches</a><a href="#tags">Protected tags</a>{{if .DepsEnabled}}<a href="#deps">Dependencies</a>{{end}}<a href="#runners">Runners</a><a href="#lifecycle">Lifecycle</a></nav> |
| 7 | 8 | |
| 8 | | <h2>Identity</h2> |
| 9 | <section id="identity"><h2>Identity</h2> |
| 9 | 10 | <form method="post" action="{{$base}}" class="setform"> |
| 10 | 11 | <input type="hidden" name="field" value="description"> |
| 11 | | <label for="description">Description</label> |
| 12 | | <input type="text" id="description" name="description" value="{{.Desc}}" placeholder="one line, shown in listings"> |
| 13 | | <button type="submit" class="btn">Save description</button> |
| 12 | <div><label for="description">Description</label></div> |
| 13 | <div><input type="text" id="description" name="description" value="{{or (index .Submitted "description") .Desc}}" placeholder="one line, shown in listings"></div> |
| 14 | <div><button type="submit">Save</button></div> |
| 14 | 15 | </form> |
| 15 | 16 | <form method="post" action="{{$base}}" class="setform"> |
| 16 | 17 | <input type="hidden" name="field" value="website"> |
| 17 | | <label for="website">Website</label> |
| 18 | | <input type="text" id="website" name="website" value="{{.Repo.Settings.Website}}" placeholder="https://example.org"> |
| 19 | | <button type="submit" class="btn">Save website</button> |
| 18 | <div><label for="website">Website</label></div> |
| 19 | <div><input type="text" id="website" name="website" value="{{or (index .Submitted "website") .Repo.Settings.Website}}" placeholder="https://example.org"></div> |
| 20 | <div><button type="submit" class="btn">Save</button></div> |
| 20 | 21 | </form> |
| 21 | | {{if .Branches}}<form method="post" action="{{$base}}" class="setform"> |
| 22 | | <input type="hidden" name="field" value="default-branch"> |
| 23 | | <label for="default-branch">Default branch</label> |
| 24 | | <select id="default-branch" name="default-branch"> |
| 25 | | {{$cur := .Repo.DefaultBranch}}{{range .Branches}}<option value="{{.Name}}"{{if eq .Name $cur}} selected{{end}}>{{.Name}}</option>{{end}} |
| 26 | | </select> |
| 27 | | <button type="submit" class="btn">Save default branch</button> |
| 28 | | </form> |
| 29 | | {{end}}<form method="post" action="{{$base}}" class="setform stack"> |
| 22 | <form method="post" action="{{$base}}" class="setform"> |
| 30 | 23 | <input type="hidden" name="field" value="topics"> |
| 31 | | <label for="topics-add">Topics to add</label> |
| 32 | | <input type="text" id="topics-add" name="add" placeholder="add, space-separated"> |
| 33 | | <label for="topics-remove">Topics to remove</label> |
| 34 | | <input type="text" id="topics-remove" name="remove" placeholder="remove"> |
| 35 | | <button type="submit" class="btn">Apply</button> |
| 24 | <div><label for="topics">Topics</label><p class="hint">Comma separated, lower case.</p></div> |
| 25 | <div><input type="text" id="topics" name="topics" value="{{or (index .Submitted "topics") (join .Topics ", ")}}"></div> |
| 26 | <div><button type="submit" class="btn">Save</button></div> |
| 36 | 27 | </form> |
| 37 | | {{if .Topics}}<p class="meta">{{range .Topics}}<span class="chip topic">{{.}}</span> {{end}}</p>{{end}} |
| 28 | {{if .Branches}}<form method="post" action="{{$base}}" class="setform"> |
| 29 | <input type="hidden" name="field" value="default-branch"> |
| 30 | <div><label for="default-branch">Default branch</label><p class="hint">What a clone checks out and what CI builds on trigger.</p></div> |
| 31 | <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> |
| 32 | <div><button type="submit" class="btn">Save</button></div> |
| 33 | </form>{{end}} |
| 34 | </section> |
| 38 | 35 | |
| 39 | | <h2>Access</h2> |
| 36 | <section id="access"><h2>Access</h2> |
| 40 | 37 | <form method="post" action="{{$base}}" class="setform"> |
| 41 | 38 | <input type="hidden" name="field" value="visibility"> |
| 42 | | <label for="visibility">Visibility</label> |
| 43 | | <select id="visibility" name="visibility"> |
| 44 | | <option value="public"{{if eq .Repo.Visibility "public"}} selected{{end}}>Public</option> |
| 45 | | <option value="private"{{if eq .Repo.Visibility "private"}} selected{{end}}>Private</option> |
| 46 | | </select> |
| 47 | | <button type="submit" class="btn">Save visibility</button> |
| 39 | <div><label>Visibility</label><p class="hint">Private repositories answer not found to everyone without access, including in search and on your profile.</p></div> |
| 40 | <div class="check"> |
| 41 | <label><input type="radio" name="visibility" value="public"{{if eq .Repo.Visibility "public"}} checked{{end}}> Public</label> |
| 42 | <label><input type="radio" name="visibility" value="private"{{if eq .Repo.Visibility "private"}} checked{{end}}> Private</label> |
| 43 | </div> |
| 44 | <div><button type="submit" class="btn">Save</button></div> |
| 48 | 45 | </form> |
| 49 | 46 | <form method="post" action="{{$base}}" class="setform"> |
| 50 | 47 | <input type="hidden" name="field" value="git-daemon"> |
| 51 | | <label for="git-daemon">Serve over git://</label> |
| 52 | | <input type="checkbox" id="git-daemon" name="git-daemon" value="on"{{if .Repo.Settings.GitDaemon}} checked{{end}}> |
| 53 | | <button type="submit" class="btn">Save git://</button> |
| 48 | <div><label for="git-daemon">Serve over git://</label><p class="hint">Unauthenticated, unencrypted read access on port 9418. Public repositories only.</p></div> |
| 49 | <div class="check"><input type="checkbox" id="git-daemon" name="git-daemon" value="on"{{if .Repo.Settings.GitDaemon}} checked{{end}}></div> |
| 50 | <div><button type="submit" class="btn">Save</button></div> |
| 54 | 51 | </form> |
| 52 | </section> |
| 55 | 53 | |
| 56 | | <h2>Merge gates</h2> |
| 54 | <section id="gates"><h2>Merge gates</h2> |
| 57 | 55 | <p class="meta">Checked before a merge, in this order: checks, approvals, resolved threads, signatures.</p> |
| 58 | 56 | <form method="post" action="{{$base}}" class="setform"> |
| 59 | 57 | <input type="hidden" name="field" value="require-checks"> |
| 60 | | <label for="require-checks">Require green checks</label> |
| 61 | | <input type="checkbox" id="require-checks" name="require-checks" value="on"{{if .Repo.Settings.RequireChecks}} checked{{end}}> |
| 62 | | <button type="submit" class="btn">Save checks</button> |
| 58 | <div><label for="require-checks">Required checks</label><p class="hint">A request waits until every CI job that would report on its head has succeeded.</p></div> |
| 59 | <div class="check"><input type="checkbox" id="require-checks" name="require-checks" value="on"{{if .Repo.Settings.RequireChecks}} checked{{end}}></div> |
| 60 | <div><button type="submit" class="btn">Save</button></div> |
| 63 | 61 | </form> |
| 64 | 62 | <form method="post" action="{{$base}}" class="setform"> |
| 65 | 63 | <input type="hidden" name="field" value="require-approvals"> |
| 66 | | <label for="approvals">Required approvals</label> |
| 67 | | <input type="number" id="approvals" name="approvals" min="0" max="10" value="{{.Repo.Settings.RequireApprovals}}"> |
| 68 | | <button type="submit" class="btn">Save approvals</button> |
| 64 | <div><label for="approvals">Approvals</label><p class="hint">Approvals from people with write access. Zero means none required.</p></div> |
| 65 | <div><input type="number" id="approvals" name="approvals" min="0" max="10" value="{{.Repo.Settings.RequireApprovals}}"></div> |
| 66 | <div><button type="submit" class="btn">Save</button></div> |
| 69 | 67 | </form> |
| 70 | 68 | <form method="post" action="{{$base}}" class="setform"> |
| 71 | 69 | <input type="hidden" name="field" value="require-resolved"> |
| 72 | | <label for="require-resolved">Require resolved threads</label> |
| 73 | | <input type="checkbox" id="require-resolved" name="require-resolved" value="on"{{if .Repo.Settings.RequireResolved}} checked{{end}}> |
| 74 | | <button type="submit" class="btn">Save threads</button> |
| 70 | <div><label for="require-resolved">Review threads</label><p class="hint">Every thread on the diff must be resolved before merging.</p></div> |
| 71 | <div class="check"><input type="checkbox" id="require-resolved" name="require-resolved" value="on"{{if .Repo.Settings.RequireResolved}} checked{{end}}></div> |
| 72 | <div><button type="submit" class="btn">Save</button></div> |
| 75 | 73 | </form> |
| 76 | 74 | <form method="post" action="{{$base}}" class="setform"> |
| 77 | 75 | <input type="hidden" name="field" value="require-codeowners"> |
| 78 | | <label for="require-codeowners">Require CODEOWNERS approval</label> |
| 79 | | <input type="checkbox" id="require-codeowners" name="require-codeowners" value="on"{{if .Repo.Settings.RequireCodeowners}} checked{{end}}> |
| 80 | | <button type="submit" class="btn">Save CODEOWNERS</button> |
| 76 | <div><label for="require-codeowners">CODEOWNERS</label><p class="hint">Owners of every touched path must approve.</p></div> |
| 77 | <div class="check"><input type="checkbox" id="require-codeowners" name="require-codeowners" value="on"{{if .Repo.Settings.RequireCodeowners}} checked{{end}}></div> |
| 78 | <div><button type="submit" class="btn">Save</button></div> |
| 81 | 79 | </form> |
| 82 | 80 | <form method="post" action="{{$base}}" class="setform"> |
| 83 | 81 | <input type="hidden" name="field" value="require-signed"> |
| 84 | | <label for="require-signed">Require signed commits</label> |
| 85 | | <input type="checkbox" id="require-signed" name="require-signed" value="on"{{if .Repo.Settings.RequireSignedCommits}} checked{{end}}> |
| 86 | | <button type="submit" class="btn">Save signing</button> |
| 82 | <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> |
| 83 | <div class="check"><input type="checkbox" id="require-signed" name="require-signed" value="on"{{if .Repo.Settings.RequireSignedCommits}} checked{{end}}></div> |
| 84 | <div><button type="submit" class="btn">Save</button></div> |
| 87 | 85 | </form> |
| 86 | </section> |
| 88 | 87 | |
| 89 | | <h2>Protected branches</h2> |
| 88 | <section id="branches"><h2>Protected branches</h2> |
| 90 | 89 | {{if .Repo.Settings.ProtectedBranches}} |
| 91 | 90 | <ul class="protlist"> |
| 92 | | {{range .Repo.Settings.ProtectedBranches}}<li><code>{{.}}</code> |
| 91 | {{$mr := .Repo.Settings.RequireMR}}{{range .Repo.Settings.ProtectedBranches}}<li><code>{{.}}</code>{{if $mr}} <span class="hint">Direct pushes refused, merge requests only.</span>{{end}} |
| 93 | 92 | <form method="post" action="{{$base}}" class="inline"> |
| 94 | 93 | <input type="hidden" name="field" value="unprotect"> |
| 95 | 94 | <input type="hidden" name="branch" value="{{.}}"> |
| 96 | | <button type="submit" class="linklike">Unprotect</button> |
| 95 | <button type="submit" class="danger">Unprotect</button> |
| 97 | 96 | </form></li> |
| 98 | 97 | {{end}} |
| 99 | 98 | </ul> |
| 100 | 99 | {{else}}<p class="meta">No protected branches. A protected branch refuses deletion and force-pushes.</p>{{end}} |
| 101 | 100 | <form method="post" action="{{$base}}" class="setform"> |
| 102 | 101 | <input type="hidden" name="field" value="protect"> |
| 103 | | <label for="branch">Protect a branch</label> |
| 104 | | <select id="branch" name="branch"> |
| 105 | | {{range .Branches}}<option value="{{.Name}}">{{.Name}}</option>{{end}} |
| 106 | | </select> |
| 107 | | <button type="submit" class="btn">Protect</button> |
| 102 | <div><label for="branch">Protect a branch</label></div> |
| 103 | <div><select id="branch" name="branch">{{range .Branches}}<option value="{{.Name}}">{{.Name}}</option>{{end}}</select></div> |
| 104 | <div><button type="submit" class="btn">Protect</button></div> |
| 108 | 105 | </form> |
| 109 | 106 | <form method="post" action="{{$base}}" class="setform"> |
| 110 | 107 | <input type="hidden" name="field" value="require-mr"> |
| 111 | | <label for="require-mr">Merge requests only</label> |
| 112 | | <input type="checkbox" id="require-mr" name="require-mr" value="on"{{if .Repo.Settings.RequireMR}} checked{{end}}> |
| 113 | | <button type="submit" class="btn">Save merge-only</button> |
| 108 | <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> |
| 109 | <div class="check"><input type="checkbox" id="require-mr" name="require-mr" value="on"{{if .Repo.Settings.RequireMR}} checked{{end}}></div> |
| 110 | <div><button type="submit" class="btn">Save</button></div> |
| 114 | 111 | </form> |
| 115 | | <p class="meta">With merge requests only, a protected branch refuses every direct push once it exists; the merge gates above are then what a change has to pass.</p> |
| 112 | </section> |
| 116 | 113 | |
| 117 | | <h2>Protected tags</h2> |
| 114 | <section id="tags"><h2>Protected tags</h2> |
| 118 | 115 | {{if .Repo.Settings.ProtectedTags}} |
| 119 | 116 | <ul class="protlist"> |
| 120 | 117 | {{range .Repo.Settings.ProtectedTags}}<li><code>{{.}}</code> |
| 121 | 118 | <form method="post" action="{{$base}}" class="inline"> |
| 122 | 119 | <input type="hidden" name="field" value="unprotect-tag"> |
| 123 | 120 | <input type="hidden" name="glob" value="{{.}}"> |
| 124 | | <button type="submit" class="linklike">Unprotect</button> |
| 121 | <button type="submit" class="danger">Unprotect</button> |
| 125 | 122 | </form></li> |
| 126 | 123 | {{end}} |
| 127 | 124 | </ul> |
| 128 | 125 | {{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}} |
| 129 | 126 | <form method="post" action="{{$base}}" class="setform"> |
| 130 | 127 | <input type="hidden" name="field" value="protect-tag"> |
| 131 | | <label for="glob">Protect tags matching</label> |
| 132 | | <input type="text" id="glob" name="glob" placeholder="v*"> |
| 133 | | <button type="submit" class="btn">Protect</button> |
| 128 | <div><label for="glob">Protect tags matching</label></div> |
| 129 | <div><input type="text" id="glob" name="glob" placeholder="v*"></div> |
| 130 | <div><button type="submit" class="btn">Protect</button></div> |
| 134 | 131 | </form> |
| 132 | </section> |
| 135 | 133 | |
| 136 | | <h2>Dependencies</h2> |
| 134 | <section id="deps"><h2>Dependencies</h2> |
| 137 | 135 | <form method="post" action="{{$base}}" class="setform"> |
| 138 | 136 | <input type="hidden" name="field" value="deps"> |
| 139 | | <label for="deps">Check for updates</label> |
| 140 | | <input type="checkbox" id="deps" name="deps" value="on"{{if .DepsEnabled}} checked{{end}}> |
| 141 | | <button type="submit" class="btn">Save dependency checks</button> |
| 142 | | </form> |
| 143 | | <p class="meta">Compares the manifests on <code>{{.Repo.DefaultBranch}}</code> against |
| 144 | | proxy.golang.org, npm, crates.io, and PyPI once a day, and tracks what is behind |
| 145 | | in an issue. Checking a private repository tells those registries what it |
| 146 | | depends on.</p> |
| 137 | <div><label for="deps">Check for updates</label><p class="hint">Compares the manifests on <code>{{.Repo.DefaultBranch}}</code> against proxy.golang.org, npm, crates.io, and PyPI once a day, and tracks what is behind in an issue. Checking a private repository tells those registries what it depends on.</p></div> |
| 138 | <div class="check"><input type="checkbox" id="deps" name="deps" value="on"{{if .DepsEnabled}} checked{{end}}></div> |
| 139 | <div><button type="submit" class="btn">Save</button></div> |
| 140 | </form> |
| 147 | 141 | {{if .DepsEnabled}} |
| 148 | 142 | <p class="meta">Last checked {{if .Deps.LastCheck}}{{when .Deps.LastCheck}}{{else}}never{{end}}{{if .Deps.IssueNumber}} · tracked in <a href="/{{.Repo.OwnerName}}/{{.Repo.Name}}/issues/{{.Deps.IssueNumber}}">#{{.Deps.IssueNumber}}</a>{{end}}</p> |
| 149 | 143 | {{if .Deps.LastError}}<p class="error" role="alert">{{.Deps.LastError}}</p>{{end}} |
| @@ -157,34 +151,37 @@ depends on.</p> |
| 157 | 151 | {{end}}</table></div> |
| 158 | 152 | {{else}}<p class="none">Nothing behind{{if not .Deps.LastCheck}} — the first check has not run yet{{end}}.</p>{{end}} |
| 159 | 153 | {{end}} |
| 154 | </section> |
| 160 | 155 | |
| 161 | | <h2>Runners</h2> |
| 156 | <section id="runners"><h2>Runners</h2> |
| 162 | 157 | {{if .Runners}} |
| 163 | 158 | <ul class="protlist"> |
| 164 | 159 | {{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> |
| 165 | 160 | <form method="post" action="{{$base}}" class="inline"> |
| 166 | 161 | <input type="hidden" name="field" value="runner-remove"> |
| 167 | 162 | <input type="hidden" name="fingerprint" value="{{.Fingerprint}}"> |
| 168 | | <button type="submit" class="linklike">Detach</button> |
| 163 | <button type="submit" class="danger">Detach</button> |
| 169 | 164 | </form></li> |
| 170 | 165 | {{end}} |
| 171 | 166 | </ul> |
| 172 | 167 | {{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}} |
| 173 | | <form method="post" action="{{$base}}" class="setform"> |
| 168 | <form method="post" action="{{$base}}" class="setform stack"> |
| 174 | 169 | <input type="hidden" name="field" value="runner-add"> |
| 175 | 170 | <label for="runner-key">Attach a runner</label> |
| 171 | <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> |
| 176 | 172 | <textarea id="runner-key" name="key" rows="3" placeholder="ssh-ed25519 AAAA… (from gitbay-runner init)"></textarea> |
| 177 | 173 | <button type="submit" class="btn">Attach</button> |
| 178 | 174 | </form> |
| 179 | | <p class="meta">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> |
| 175 | </section> |
| 180 | 176 | |
| 181 | | <h2>Lifecycle</h2> |
| 177 | <section id="lifecycle"><h2>Lifecycle</h2> |
| 182 | 178 | <form method="post" action="{{$base}}" class="setform"> |
| 183 | 179 | <input type="hidden" name="field" value="archive"> |
| 184 | | <label for="archive">Archived (read-only)</label> |
| 185 | | <input type="checkbox" id="archive" name="archive" value="on"{{if .Repo.Settings.Archived}} checked{{end}}> |
| 186 | | <button type="submit" class="btn">Save archive</button> |
| 180 | <div><label for="archive">Archived</label><p class="hint">Read-only for everyone. Issues and requests close to new activity. Reversible.</p></div> |
| 181 | <div class="check"><input type="checkbox" id="archive" name="archive" value="on"{{if .Repo.Settings.Archived}} checked{{end}}></div> |
| 182 | <div>{{template "confirmfield" .Repo.Name}} <button type="submit" class="danger">Save</button></div> |
| 187 | 183 | </form> |
| 188 | 184 | <p class="meta">Deleting or transferring a repository is a CLI operation: |
| 189 | 185 | <code>gitbay repo delete {{.Repo.OwnerName}}/{{.Repo.Name}} --yes</code></p> |
| 186 | </section> |
| 190 | 187 | {{end}} |