repos
/ orchard main

orchard

mirror

Every site I host, in one repo, along with the Cloudflare Tunnel and Caddy that front them. It's all Go, Vite, and SQLite, and it runs on a desktop at home with nothing listening on an inbound port.

blogbuncaddycloudflare-tunneldockergogolanghomelabhtml-templatemonorepoself-hostedseosqlitestatic-sitetypstuptime-monitoringviteweb-analytics

3.7 KB · 105 lines · HTML Raw History
  1{{define "content"}}
  2{{$d := .Data}}
  3<h1 class="pagetitle">Settings</h1>
  4
  5{{if $d.NewToken}}
  6<div class="notice tokennew">
  7  <strong>New push token. This is the only time it is shown.</strong>
  8  <input type="text" readonly value="{{$d.NewToken}}" onclick="this.select()">
  9  <p>Use it as the password. The username is ignored, so type anything:</p>
 10  <pre class="cmd">git remote add origin {{$d.CloneURL}}/&lt;name&gt;.git
 11git push -u origin main</pre>
 12  <p class="hint">
 13    To avoid retyping it, let git remember it:
 14    <pre class="cmd">git config --global credential.helper store</pre>
 15    The token is stored in clear in <code>~/.git-credentials</code>, so treat that file as the secret it is.
 16  </p>
 17</div>
 18{{end}}
 19
 20{{if $d.Notice}}
 21<div class="notice">{{$d.Notice}}</div>
 22{{end}}
 23
 24<section>
 25  <h2>What gets mirrored</h2>
 26  <p class="hint">
 27    A source is a whole GitHub account, or one repository on it. Everything
 28    public it finds is cloned here and kept in step; forks and private
 29    repositories are skipped, though naming a fork outright mirrors it anyway.
 30    {{if $d.MirrorEnabled}}Syncs every {{$d.MirrorEvery}}.{{else}}<strong>The mirror lane is disabled.</strong>{{end}}
 31  </p>
 32
 33  <form method="post" action="/settings/mirrors" class="inline">
 34    <input type="text" name="source" placeholder="overshard or overshard/newtab" maxlength="201" required>
 35    <button type="submit">Add source</button>
 36  </form>
 37
 38  <table class="tokens">
 39    <tbody>
 40    {{range $d.Sources}}
 41      <tr>
 42        <td class="name"><a href="{{.URL}}" rel="noreferrer">{{.Label}}</a></td>
 43        <td>{{if eq .Kind "account"}}entire account{{else}}single repository{{end}}</td>
 44        <td>{{.Repos}} mirrored{{if .Failing}}, <strong>{{.Failing}} failing</strong>{{end}}</td>
 45        <td>{{if .LastSync.IsZero}}never synced{{else}}synced {{humanTime .LastSync}}{{end}}</td>
 46        <td>
 47          <form method="post" action="/settings/mirrors/{{.ID}}/delete" class="inline">
 48            <button type="submit" class="danger">Remove</button>
 49          </form>
 50        </td>
 51      </tr>
 52    {{else}}
 53      <tr><td colspan="5">No sources. Nothing is being mirrored.</td></tr>
 54    {{end}}
 55    </tbody>
 56  </table>
 57
 58  <form method="post" action="/settings/mirrors/sync" class="inline">
 59    <button type="submit">Sync now</button>
 60  </form>
 61  <p class="hint">
 62    Removing a source stops the syncing and leaves every repository it brought
 63    in exactly where it is. Nothing here is deleted because a setting changed.
 64  </p>
 65</section>
 66
 67<section>
 68  <h2>Push tokens</h2>
 69  <p class="hint">
 70    A token is the password half of an HTTP Basic credential, which is the only
 71    scheme git natively stores and replays. It is a random value, not a
 72    password, and only its hash is kept here. Revoking one takes effect on the
 73    next push.
 74  </p>
 75
 76  <form method="post" action="/settings/tokens" class="inline">
 77    <input type="text" name="label" placeholder="laptop, desktop, CI" maxlength="60" required>
 78    <button type="submit">Mint token</button>
 79  </form>
 80
 81  <table class="tokens">
 82    <tbody>
 83    {{range $d.Tokens}}
 84      <tr>
 85        <td class="name">{{.Label}}</td>
 86        <td><code>{{.Prefix}}&hellip;</code></td>
 87        <td>created {{humanTime .Created}}</td>
 88        <td>{{if .LastUsed.IsZero}}never used{{else}}used {{humanTime .LastUsed}}{{end}}</td>
 89        <td>
 90          <form method="post" action="/settings/tokens/{{.ID}}/revoke" class="inline">
 91            <button type="submit" class="danger">Revoke</button>
 92          </form>
 93        </td>
 94      </tr>
 95    {{end}}
 96    </tbody>
 97  </table>
 98</section>
 99
100<section>
101  <h2>Pushing a large repository</h2>
102  {{template "pushlimit" (dict "Bridge" $d.Bridge "Name" "<name>")}}
103</section>
104{{end}}