ff6e99eb6269b28d5e374bf09704f77961851578
9
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
1aca294b95 |
Bump to 0.2.0 — a release at 0.1.0 would have been a downgrade
CI & Build / Build now, or wait for Android? (push) Successful in 3s
CI & Build / Python lint (push) Successful in 4s
CI & Build / TypeScript typecheck (push) Successful in 7s
CI & Build / Build & push image (push) Skipped
CI & Build / Python tests (push) Successful in 10s
CI & Build / integration (push) Successful in 14s
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 2m59s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 5m9s
Desktop (Tauri) / Update manifest (push) Successful in 4s
Android / Kotlin + Rust (APK) (push) Successful in 8m0s
Found while preparing the release, and it would have quietly defeated the point of cutting one. The version does NOT come from the tag. `desktop/packaging/build-version.sh` reads `desktop/src-tauri/Cargo.toml`, and on `dev` it appends the CI run number (`0.1.269`) while on a tag or `main` it ships the file's value verbatim — which was still `0.1.0`. So tagging today would have published a "release" numbered BELOW every dev build already out there, and below the 0.1.227 on the operator's phone. The desktop updater compares semver: an installed build would have read the stable manifest, seen a version older than its own, and correctly concluded it was already current. The APK would have installed (versionCode is the run number and keeps rising) while displaying a version that reads as going backwards. build-version.sh predicted this in its own comment: "Bumping the minor in Cargo.toml still wins over any dev build on the old line, which is the ordering you want: 0.2.0 > 0.1.2932." Bumped in four places, which is every one that can be read by something: - `desktop/src-tauri/Cargo.toml` — the actual source; everything else derives - `tauri.conf.json` — overridden at build time by `--config`, but a checked-in value that lies is exactly how issue 2183 happened - `pyproject.toml` + `__init__.py` — the server's APP_VERSION fallback when no BUILD_VERSION is injected `core` and `android/ffi` stay at 0.1.0 deliberately: internal library crates whose version reaches no surface, and versioning workspace libs independently of the app is normal. Cargo.lock regenerated with `cargo fetch` per ci-requirements — one line, the version itself. Verified: a tag build now yields 0.2.0 and a dev build 0.2.270, so stable is an upgrade for every existing install and dev stays ahead of stable. |
||
|
|
c883fd2eb6 |
desktop: one name across all three install channels (issue 2075)
The app answered to three different names depending on how it arrived, and the
part that actually hurt was WM_CLASS. Reading tauri-bundler settles what it is:
the generated .desktop template writes StartupWMClass={{exec}} where exec is
main_binary_name, and tao creates its GtkApplication with a NULL app id
(enableGTKAppId defaults off), so GTK falls back to the program name. WM_CLASS
is the binary name, nothing else.
Which inverts this issue's premise. The rename could not break grouping,
because two channels weren't grouping in the first place: pacman ships
/usr/bin/thoughtsync and the AppImage's AppRun execs thoughtsync-desktop, while
all three hand-written entries hardcoded StartupWMClass=ThoughtSync — a string
no binary in any channel has ever reported. Only the .deb worked, and only
because Tauri generates its entry from the binary and never consulted us.
So: thoughtsync everywhere, carried by the build target itself via Cargo [[bin]]
plus mainBinaryName rather than by the install path, since the target name is
what the desktop reads. The pacman package sheds its -desktop suffix and
declares conflict+replaces so an upgrade retires the old one instead of landing
beside it and fighting over /usr/bin/thoughtsync.
The .deb verifier now asserts binary path, Exec and StartupWMClass all agree,
which is the part that keeps this fixed: the .deb's entry is the one no human
writes, so it's the one that drifts silently.
Package: thought-sync stays. tauri-bundler derives it as kebab-case(productName)
with no override, and rewriting a control archive on every build is a poor trade
for one uninstall command.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
02c932260e |
Updater signing key, a rising dev version, and a production compose
Three things, all needed before the update loop can be tested. The public signing key is committed. Verified before trusting it: algorithm `Ed`, key ID 90E96FEA2F6D9B6A matching its own comment, 32-byte Ed25519 key. Dev builds now carry a version that RISES. Every build took its version from Cargo.toml, so each one was 0.1.0 — an installed 0.1.0 would read a manifest advertising 0.1.0, conclude it was current, and never update. The rolling channel would have looked broken while working exactly as written. Dev builds are now 0.1.<ci-run-number>, from one helper shared by both bundle jobs and the manifest writer, because three separate derivations of "what version is this" is three chances for the binary and the manifest to disagree. Plain semver, not a `-dev.N` prerelease: prerelease versions sort BELOW the release they qualify, so a tagged build would never update to a newer dev one, and Windows installer metadata wants a numeric X.Y.Z regardless. Bumping the minor still beats any dev build on the old line — 0.2.0 > 0.1.2932. The Windows job also gets the signing environment it was missing, so its NSIS installer is signed too. Without that the manifest would have had a Linux entry and nothing for the platform actually being tested. docker-compose.yml is now the production stack, per request: it pulls the published image instead of building, keeps Postgres OFF the host network, sets restart policies, health checks and log rotation, and refuses to start without a POSTGRES_PASSWORD rather than shipping a known one. Volume names are deliberately unchanged so an existing deployment upgrades in place instead of silently coming up against an empty database. Development keeps its own clearly-named file. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SreJkbxB4gx8pPsu8QbLPi |
||
|
|
d6734cf7a0 |
desktop: in-app updates, two channels, signed, fed by fixed-tag releases
CI & Build / Python lint (push) Successful in 3s
CI & Build / TypeScript typecheck (push) Successful in 6s
CI & Build / Python tests (push) Successful in 10s
CI & Build / Build & push image (push) Successful in 30s
Desktop (Tauri) / Tauri desktop (Linux) (push) Failing after 1m59s
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 2m23s
Desktop (Tauri) / Update manifest (push) Has been skipped
There was no in-place update anywhere. The app never checked, downloaded or applied anything, and the only published release predates the whole sync arc — so `install.sh` would hand out a build with no sync in it. Installing from per-run CI artifacts, which is what's been happening, is not something an updater can point at: ephemeral, auth-gated, no stable URL. Two channels, switchable in the app: `stable` follows tagged releases, `dev` follows every green push. The feed is a Fabled-Git release asset, not a ThoughtSync server route. This reverses the lean recorded in task 1998, and the reason matters — a server-hosted feed can only reach a desktop that has linked a server, and local-first-with-no-server is the whole premise. An unlinked install has to be able to update itself. Each channel reads a `latest.json` on a release whose TAG NEVER MOVES. That's forced, not stylistic: Forgejo has no /releases/latest/download/<asset> route (verified — it 404s with no redirect), so "newest" cannot be named in a URL. `dev` carries the rolling bundles; `stable` is a pointer release holding only the manifest, whose URLs aim at the versioned release's assets, so nothing is duplicated. The manifest is written by a third job that runs after both bundle jobs. They build in separate workspaces and neither can see the other's output, but one manifest has to describe both platforms — generating it inside either job would silently omit the other, and a missing platform reads to a user as "no update available" rather than as a broken feed. It reads what actually landed on the release, so it can never advertise a bundle that failed to upload. Signing is gated on the secret existing, in the script rather than an `if:` (the secrets context isn't reliably available to step conditions). No key means no updater artifacts and no publish: a feed the app would refuse to verify is worse than no feed, because it looks like it works. CI stays green until the key lands. On Linux the updater can only replace an AppImage — a deb or pacman install is owned by its package manager and must never be overwritten underneath it. The app detects that case up front and says so, instead of failing halfway through with a permissions error nobody can read. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SreJkbxB4gx8pPsu8QbLPi |
||
|
|
85ca7c2a2d |
desktop: drop the redundant deb depends, correct the pacman docs
CI & Build / Python lint (push) Successful in 2s
CI & Build / TypeScript typecheck (push) Successful in 7s
CI & Build / Python tests (push) Successful in 8s
CI & Build / Build & push image (push) Successful in 17s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 3m28s
Follow-up to
|
||
|
|
8a8b2b17e6 |
desktop: prebuilt pacman package + verified .deb (tasks 2022, 2074)
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 3m41s
Native packages the installer can actually fetch, before task 2014 wires up the fetching. Arch (task 2022, re-scoped): the source PKGBUILD is gone — asking every user to install rust+node and compile for minutes isn't distribution. Replaced by desktop/packaging/arch/package-prebuilt.sh, which wraps the binary the Linux job already built into a .pkg.tar.zst. No second Rust build, no Arch CI image: the binary bundles nothing and resolves webkit/gtk/soup by soname, identical on both distros, with SQLite compiled in and glibc used in the safe built-old/run-new direction. CI is Debian and has no pacman, so the step logs .PKGINFO plus the full file listing for audit instead of pretending to verify. Debian (task 2074): install.sh hands the .deb to every Debian/Ubuntu user and nothing had ever inspected it. tauri.conf.json now declares libwebkit2gtk-4.1-0 + libgtk-3-0 explicitly rather than trusting inference — and deliberately declares no appindicator or sqlite dep, since tauri is built with features=[] and rusqlite is "bundled". desktop/packaging/deb/verify.sh prints the generated control file, cross-checks it against what the ELF actually needs via dpkg-shlibdeps, confirms every declared dep exists in apt, and clean-container installs when a docker CLI is available. Both artifacts join the run artifact and the tagged release; install.sh grows a pacman branch so Arch/CachyOS gets a native install instead of the AppImage fallback. Still no release cut (rule 2). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SreJkbxB4gx8pPsu8QbLPi |
||
|
|
98d918dda2 |
M10 (task 2022, issue 2021): Arch pacman package + commit icon set (native, system libs)
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 3m27s
Native-first fix for the AppImage black window: a PKGBUILD that builds from source,
linked against SYSTEM graphics libs, so it renders on the host driver.
- desktop/packaging/arch/{PKGBUILD,thoughtsync.desktop,README.md}: `makepkg -si`
installs /usr/bin/thoughtsync + .desktop + icon; deps webkit2gtk-4.1/gtk3/...;
builds the frontend + `cargo build --release` (no tauri-cli). Uses the host
graphics stack -> avoids EGL_BAD_PARAMETER.
- Commit the icon set (desktop/src-tauri/icons/*.png, un-gitignored) so BOTH
`cargo build` (pacman) and `cargo tauri build` (deb/appimage) work without a
generate step; bundle.icon -> the 4 committed PNGs; drop the `cargo tauri icon`
step from desktop.yml.
- Broaden the WebKit software-render hardening (lib.rs) to ALL Linux (was
AppImage-scoped) so the native build also renders if system WebKit is finicky.
Can't CI-test the PKGBUILD (Arch-only; CI is Debian) -- operator builds locally.
desktop.yml re-verifies the deb+AppImage build with the committed icons.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm
|
||
|
|
877a6a572f |
M10 (task 2013): integrated AppImage — app self-integration (OOBE + Account toggle)
CI & Build / Python lint (push) Successful in 3s
CI & Build / TypeScript typecheck (push) Successful in 6s
CI & Build / Python tests (push) Successful in 9s
Desktop (Tauri) / Tauri desktop (Linux) (push) Failing after 26s
CI & Build / Build & push image (push) Successful in 33s
The Linux AppImage can now install itself into the applications menu, so it behaves like an installed app instead of a loose file. - Rust (desktop/src-tauri/src/integration.rs): integration_status / integrate_desktop / unintegrate_desktop commands — detect $APPIMAGE, copy the AppImage to ~/Applications, write ~/.local/share/applications/thoughtsync.desktop + embedded icon, update-desktop-database. Registered in lib.rs. - Frontend: withGlobalTauri exposes window.__TAURI__.core.invoke; desktop/bridge.ts (isDesktop + typed invoke, NO @tauri-apps/api dep -> web bundle unaffected); DesktopIntegrationPrompt (first-run OOBE, remembered) mounted in App.vue; AccountView "Desktop app" add/remove control. All desktop-guarded -> no-ops on web. - desktop.yml: upload the .deb + .AppImage as a run artifact (continue-on-error) so the build is downloadable for hand-testing. Verified by CI: ci.yml (vue-tsc) for the frontend, desktop.yml (cargo + tauri build) for the Rust + AppImage. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm |
||
|
|
db24d7ea18 |
M10.2: Tauri v2 desktop scaffold (desktop/) — Vue frontend as the webview
New desktop/ Tauri v2 project (Linux-first, cross-platform-ready): - src-tauri: Cargo.toml (lib + thin main.rs shim), build.rs, lib.rs (Builder entry point), tauri.conf.json (frontendDist -> ../../frontend/dist, devUrl :5173, deb+appimage bundles), capabilities/default.json (core:default), .gitignore. - The shared Vue 3 frontend is the sibling ../frontend; before-commands cd via "$(git rev-parse --show-toplevel)/frontend" since frontend and src-tauri are siblings, not nested. - Icons generated from frontend/public/icon.svg via `cargo tauri icon` in CI (M10.8), not committed. Boots the shared UI in a native window. The local data adapter (M10.3/M10.5) and CI build verification (M10.8) follow. desktop/** is not yet in the CI paths filter — added with the desktop lane in M10.8. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm |