Skip to content

Commit 93f0120

Browse files
MagicalTuxclaude
andcommitted
Make "Check for Updates" report its outcome; fix master publish
Windows users reported "Check for Updates" doing nothing and staying on 0.1.10. Diagnosis: the master channel serves 0.1.13 with a reachable, signature-valid windows_amd64 artifact, and the update path works end to end on Linux from a simulated old version — so the server side is fine. The failure is Windows-client-specific and *invisible*: the GUI build has no console, so update() errors (or a silent no-op) never reach the user. - trigger_update_check now checks first, then reports every outcome via a desktop notification — "up to date", "Updating to vX…", or the actual error. No more silent "nothing happens"; the next attempt reveals the real Windows cause (likely unsigned-exe/SmartScreen or an rsurl issue). - Fix the master publish that 0.1.14 broke: the dist backend keys releases by (project, version), so GUI + server can't share project `decryptd` at one version — the concurrent server publish won and master was rejected as "already published". The server build now updates from its own project `decryptd-server` (separate namespace, same signing identity); publish-server uses `--project decryptd-server`. The two publishes are independent, so a server failure can't block GUI updates. Both feature sets + docs build clean; workflow YAML validated. Bump to 0.1.15. Note: stuck 0.1.10 Windows users need a one-time manual reinstall of 0.1.15 (release zip); after that "Check for Updates" shows the real result. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 8d900e2 commit 93f0120

5 files changed

Lines changed: 57 additions & 31 deletions

File tree

.github/workflows/release.yml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,13 @@ jobs:
5757
RSUPD_IDENTITY: ${{ secrets.RSUPD_IDENTITY }}
5858
run: rsupd publish --ci --run ${{ github.run_id }} --channel master --yes
5959

60-
# The headless -server build tracks its own `server` channel so console workers
61-
# auto-update to another console build, never the GTK-linked GUI binary on
62-
# `master`. Its binary isn't a triple-named CI artifact, so `--ci` can't stage it;
63-
# instead we drop it into target/<triple>/release/ and publish in local mode
64-
# (rsupd packages the existing binary — no recompile).
60+
# The headless -server build updates from its own rsupd project `decryptd-server`
61+
# (the backend keys releases by project+version, so the GUI and server binaries —
62+
# same version, same os_arch — can't share the `decryptd` project). Its binary
63+
# isn't a triple-named CI artifact, so `--ci` can't stage it; instead we drop it
64+
# into target/<triple>/release/ and publish in local mode with an explicit
65+
# --project (rsupd packages the existing binary — no recompile). Independent of
66+
# the master publish, so a failure here never blocks GUI updates.
6567
publish-server:
6668
name: Sign & publish server update
6769
needs: build
@@ -83,7 +85,7 @@ jobs:
8385
mkdir -p target/x86_64-unknown-linux-gnu/release
8486
tar -xzf srv/decryptd-linux-x86_64-server.tar.gz \
8587
-C target/x86_64-unknown-linux-gnu/release decryptd
86-
- name: Sign & publish to the `server` channel
88+
- name: Sign & publish the decryptd-server project
8789
env:
8890
RSUPD_IDENTITY: ${{ secrets.RSUPD_IDENTITY }}
89-
run: rsupd publish --target x86_64-unknown-linux-gnu --channel server --yes
91+
run: rsupd publish --project decryptd-server --target x86_64-unknown-linux-gnu --channel master --yes

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "decryptd"
3-
version = "0.1.14"
3+
version = "0.1.15"
44
edition = "2024"
55
license = "Proprietary"
66
authors = ["Karpeles Lab Inc"]

src/gui.rs

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -184,20 +184,42 @@ fn notify_error(msg: &str) {
184184
.show();
185185
}
186186

187-
/// Kick off a one-shot self-update from the tray. Reuses [`crate::build_updater`]
188-
/// — the same signed updater the hourly background task uses — so it shares the
189-
/// trust anchor and transport; `update()` fetches the latest signed manifest,
190-
/// installs it if it's a genuinely newer build, and re-execs into it. Runs on
191-
/// its own thread so a slow network never freezes the menu, and is a no-op (bar
192-
/// a log line) when we're already current.
187+
/// Desktop notification about an update-check outcome.
188+
fn notify_update(body: &str) {
189+
let _ = notify_rust::Notification::new()
190+
.summary(&format!("decryptd v{VERSION} — updates"))
191+
.body(body)
192+
.show();
193+
}
194+
195+
/// Run a one-shot self-update from the tray, reporting the outcome via desktop
196+
/// notification. This is the ONLY feedback on the Windows GUI build (no console),
197+
/// so "Check for Updates" must never fail silently: the user always sees
198+
/// up-to-date, installing, or the actual error. Reuses [`crate::build_updater`]
199+
/// (same signed updater the hourly task uses); runs on its own thread so a slow
200+
/// network never freezes the menu.
193201
fn trigger_update_check() {
194-
std::thread::spawn(|| match crate::build_updater() {
195-
Ok(updater) => match updater.update() {
196-
Ok(true) => {} // installed; the process is being replaced
197-
Ok(false) => eprintln!("[decryptd] already up to date"),
198-
Err(e) => eprintln!("[decryptd] update check failed: {e}"),
199-
},
200-
Err(e) => eprintln!("[decryptd] updater unavailable: {e}"),
202+
std::thread::spawn(|| {
203+
let updater = match crate::build_updater() {
204+
Ok(u) => u,
205+
Err(e) => {
206+
notify_update(&format!("Updater unavailable: {e}"));
207+
return;
208+
}
209+
};
210+
// Check first so we can name the target version and surface a fetch/verify
211+
// error, then hand off to update() (re-checks, installs, and restarts).
212+
match updater.check() {
213+
Ok(Some(available)) => {
214+
let v = available.version().to_string();
215+
notify_update(&format!("Updating to v{v} — decryptd will restart."));
216+
if let Err(e) = updater.update() {
217+
notify_update(&format!("Update to v{v} failed: {e}"));
218+
}
219+
}
220+
Ok(None) => notify_update(&format!("decryptd is up to date (v{VERSION}).")),
221+
Err(e) => notify_update(&format!("Update check failed: {e}")),
222+
}
201223
});
202224
}
203225

src/main.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -924,23 +924,25 @@ fn upload_loop(ctx: RestContext, inflight: InFlight, done: Arc<Mutex<Receiver<Fi
924924
/// private identity.
925925
const RSUPD_FINGERPRINT: &str = "80b9edc7e6eaebf10b2a25bb10556b9b7fa6abc9fbe556706a2b680cefa4a0fc";
926926

927-
/// The update channel this build tracks. The GUI build follows `master` (rsupd's
928-
/// default); the headless build follows `server`, a separate channel carrying the
929-
/// no-GUI binary, so a console worker updates to another console build rather than
930-
/// the GTK-linked GUI one. CI publishes each channel from its own binary.
927+
/// The rsupd project this build updates from. The dist backend keys releases by
928+
/// (project, version), so the GUI and headless builds — same version, same
929+
/// os_arch, different binary — must live under different projects, not just
930+
/// different channels. The GUI build is `decryptd`; the headless build is
931+
/// `decryptd-server`, published from the no-GUI binary. Both are signed by the
932+
/// same identity/fingerprint. A console worker thus updates to another console
933+
/// build, never the GTK-linked GUI one (which wouldn't start on a headless box).
931934
#[cfg(feature = "gui")]
932-
const UPDATE_CHANNEL: &str = "master";
935+
const UPDATE_PROJECT: &str = "decryptd";
933936
#[cfg(not(feature = "gui"))]
934-
const UPDATE_CHANNEL: &str = "server";
937+
const UPDATE_PROJECT: &str = "decryptd-server";
935938

936939
/// Build the signed auto-updater. The transport (dist-go over rsurl) defaults from
937-
/// the fingerprint, so the anchor + channel are the only required inputs. The git
940+
/// the fingerprint, so the anchor + project are the only required inputs. The git
938941
/// stamps from `build.rs` let it also spot a newer build of the same version (and
939942
/// never reinstall the identical build).
940943
fn build_updater() -> rsupd::Result<rsupd::Updater> {
941-
rsupd::Updater::builder(env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"))
944+
rsupd::Updater::builder(UPDATE_PROJECT, env!("CARGO_PKG_VERSION"))
942945
.fingerprint_hex(RSUPD_FINGERPRINT)
943-
.channel(UPDATE_CHANNEL)
944946
.git_tag(env!("RSUPD_GIT_TAG"))
945947
.date_tag(rsupd::date_tag_from_unix(env!("RSUPD_BUILD_UNIX")))
946948
.build()

0 commit comments

Comments
 (0)