source: Klonkt/src/views/pages/admin-updates.ejs@ 7a235bc

main
Last change on this file since 7a235bc was 7a235bc, checked in by Robin Genis <roboburr@…>, 3 months ago

feat(updates): make the in-app updater GitHub/upstream-aware for self-hosters

The Updates page checked a hardcoded bare repo (KLONKT_GIT_DIR) that only exists on
Robin's VPS fleet, so a GitHub-clone install logged 'fatal: not a git repository' and
couldn't show its version. Now it auto-detects topology: a git CHECKOUT (app dir has
.git, origin=GitHub) checks origin/<branch> (fetched on view); the BARE-repo fleet is
unchanged. git stderr is ignored so a foreign/missing repo never spams the console.
External installs can't self-update in-app (klonkt-update needs root for systemd), so
the page shows the 'sudo klonkt-update' command instead of a button. Fleet keeps the
detached-script button.

Co-Authored-By: Claude <noreply@…>

  • Property mode set to 100644
File size: 4.6 KB
Line 
1<div class="container admin-page">
2 <h1><%= t('aupd.title') %></h1>
3 <p><a href="/admin" class="btn">&larr; <%= t('aupd.back_admin') %></a></p>
4
5 <% if (success) { %><div class="alert alert-success"><%= success %></div><% } %>
6 <% if (error) { %><div class="alert alert-error"><%= error %></div><% } %>
7
8 <section class="set-card">
9 <h2><%= t('aupd.version_heading') %></h2>
10
11 <div class="upd-row">
12 <span class="upd-label"><%= t('aupd.app_version') %></span>
13 <span class="upd-val"><%= appVersion || '—' %></span>
14 </div>
15 <div class="upd-row">
16 <span class="upd-label"><%= t('aupd.current') %></span>
17 <span class="upd-val">
18 <% if (currentSha) { %><code><%= currentSha %></code> <span class="upd-desc"><%= currentDesc %></span>
19 <% } else { %><em><%= t('aupd.current_unknown') %></em><% } %>
20 </span>
21 </div>
22 <div class="upd-row">
23 <span class="upd-label"><%= t('aupd.latest') %></span>
24 <span class="upd-val">
25 <% if (latestSha) { %><code><%= latestSha %></code> <span class="upd-desc"><%= latestDesc %></span>
26 <% } else { %><em><%= t('aupd.latest_failed') %></em><% } %>
27 </span>
28 </div>
29
30 <div class="upd-status">
31 <% if (!canCheck) { %>
32 <span class="upd-badge warn">&#9888; <%= t('aupd.no_source') %></span>
33 <% } else if (upToDate) { %>
34 <span class="upd-badge ok">&#10003; <%= t('aupd.uptodate') %></span>
35 <% } else { %>
36 <span class="upd-badge new">&#8635; <%= t('aupd.update_available') %><% if (behind) { %> (<%= behind === '1' ? t('aupd.behind_one', { n: behind }) : t('aupd.behind_many', { n: behind }) %>)<% } %></span>
37 <% } %>
38 </div>
39
40 <% if (canCheck && canSelfUpdate) { %>
41 <form method="post" action="/admin/updates/run" class="set-form"
42 onsubmit="return confirm('<%= t('aupd.run_confirm') %>');">
43 <button type="submit" class="btn btn-primary">
44 <%= upToDate ? '↻ ' + t('aupd.redeploy') : '⬆ ' + t('aupd.update_now') %>
45 </button>
46 </form>
47 <% } else if (typeof manualCommand !== 'undefined' && manualCommand && !upToDate) { %>
48 <p class="set-help" style="margin:.2rem 0 .45rem"><%= t('aupd.manual_hint') %></p>
49 <pre class="upd-cmd"><code><%= manualCommand %></code></pre>
50 <% } %>
51
52 <p class="set-help" style="margin-top:1rem">
53 <%= t('aupd.help') %>
54 </p>
55 </section>
56
57 <% if (changes && changes.length) { %>
58 <section class="set-card" style="margin-top:1rem">
59 <h2><%= t('aupd.changes_heading') %></h2>
60 <ul class="upd-changes">
61 <% changes.forEach(function (c) { %>
62 <li><span class="upd-ch-date"><%= c.date %></span> <span class="upd-ch-msg"><%= c.msg %></span></li>
63 <% }) %>
64 </ul>
65 </section>
66 <% } %>
67</div>
68
69<style>
70.admin-page { max-width: 700px; margin: 3rem auto; padding: 0 1rem; }
71.admin-page h1 { font-family: var(--font-display, serif); font-size: 2rem; margin: 0 0 .25rem; }
72.set-card { background: var(--paper-2); border: 1px solid var(--rule); border-radius: 12px; padding: 1.25rem; }
73.set-card h2 { font-family: var(--font-display, serif); font-size: 1.25rem; margin: 0 0 1rem; }
74.set-help { color: var(--ink-muted); font-size: .9rem; }
75.upd-row { display: flex; gap: 1rem; padding: .55rem 0; border-bottom: 1px solid var(--rule); align-items: baseline; }
76.upd-label { width: 90px; flex-shrink: 0; font-size: .8rem; font-weight: 600; color: var(--ink-muted); }
77.upd-val { font-size: .9rem; }
78.upd-val code { background: var(--paper); padding: .1rem .4rem; border-radius: 4px; font-size: .85em; }
79.upd-desc { color: var(--ink-muted); }
80.upd-status { margin: 1.1rem 0; }
81.upd-cmd { background: var(--paper); border: 1px solid var(--rule); border-radius: 6px; padding: .6rem .8rem; margin: 0; overflow-x: auto; }
82.upd-cmd code { font-size: .9em; }
83.upd-badge { font-size: .8rem; font-weight: 700; padding: .25rem .7rem; border-radius: 20px; }
84.upd-badge.ok { background: #d1fae5; color: #065f46; }
85.upd-badge.new { background: #fef3c7; color: #92400e; }
86.upd-badge.warn { background: #fee2e2; color: #991b1b; }
87.alert { padding: .75rem 1rem; border-radius: 6px; margin-bottom: 1rem; }
88.alert-success { background: #d1fae5; color: #065f46; border: 1px solid #a7f3d0; }
89.alert-error { background: #fee2e2; color: #991b1b; border: 1px solid #fca5a5; }
90.upd-changes { list-style: none; padding: 0; margin: 0; }
91.upd-changes li { display: flex; gap: .7rem; padding: .45rem 0; border-bottom: 1px solid var(--rule); font-size: .9rem; align-items: baseline; }
92.upd-changes li:last-child { border-bottom: 0; }
93.upd-ch-date { color: var(--ink-muted); flex-shrink: 0; font-size: .8rem; font-variant-numeric: tabular-nums; }
94.upd-ch-msg { word-break: break-word; }
95</style>
Note: See TracBrowser for help on using the repository browser.