Commit Graph
6 Commits
Author SHA1 Message Date
Mex 0f52d3f305 Resolve MSI package paths before installing or self-updating (#356) 2026-10-17 14:18:17 -06:00
307efcf45a feat(install): choose where Craft apps are installed (#461)
* feat(install): choose where Craft apps are installed

Settings gets a default install folder, and a fresh install asks for the
app's folder (prefilled with the default). Updates stay beside the copy
they replace. Works for MSI (INSTALLFOLDER), DMG bundles, and AppImages;
on Linux a custom folder means AppImage. Flatpak and the web build keep
the system location and skip the prompt.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* feat(windows): integrate portable installs with custom locations

* fix(install): ask before writing over something already in the install folder

Staging used a predictable `.<name>.partial` path beside the destination, so a
file the user kept under that name could be overwritten (AppImage) or deleted
(macOS). Stage in a fresh private folder instead.

A new install whose destination already exists now stops before downloading
and asks "Replace what's there?". Replace installs over it: the AppImage or
.app is swapped in, a portable install writes over same-named files only, and
the MSI installs into the existing folder. Cancel leaves everything as it was.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* test(install): a planted .partial symlink can't redirect AppImage staging

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Skyfuller1303 <[email protected]>
2026-10-15 20:46:32 -06:00
Mex 0f295d4b9c fix(install): preserve unrelated update backups
Reserve an exclusively owned backup directory while replacing an installed app. Preserve neighboring .old files and directories, and retain the old copy with its recovery path if rollback fails.

Includes regression coverage for backup collisions and failed rollback.

PR #332.
2026-10-13 23:40:50 -06:00
648546e942 Add an option to install Craft apps from local builds instead of GitHub (dev builds only) (#64)
* Install and update Craft apps from a local mirror

Add an opt-in developer mode for installing the Craft apps from builds on
this machine instead of GitHub:

- ARTCRAFT_LAUNCHER_DOWNLOAD_BASE (loopback http only) points the launcher
  at a local mirror. While set, every check reads the mirror's
  release_info.json, trusts download links under the mirror, never treats
  entries as stale, and never falls back to GitHub or ArtCraft's API.
- cargo xtask local sync pulls every sibling app checkout (git pull
  --ff-only --recurse-submodules), packages each app whose version isn't
  mirrored yet with its own packaging script, and files the results under
  <mirror>/<app>/<version>/ with SHA256SUMS.txt and notes from git log.
- cargo xtask local serve serves the mirror on 127.0.0.1 (with range
  requests, so paused downloads resume) and writes the feed fresh from the
  mirror's contents on every request.
- cargo xtask local status compares each checkout with what's mirrored.

* Sync the local mirror on an interval while serving it

cargo xtask local serve --sync-every <30m|1h|1d…> runs the same sync as
cargo xtask local sync on a background thread, one after another, so the
mirror follows origin without a second process. Downloads keep being
served during a build, and a version only joins the feed once its build
is complete. Pulls are --no-stat to keep the server's log readable.

* Build every new commit as a dev version with --every-commit

cargo xtask local sync --every-commit (and serve --sync-every … --every-commit)
builds each new commit rather than only new versions. A commit of a 0.4.0
checkout is packaged as 0.4.1-dev.<commit time> through the app's
<APP>_VERSION override, so it orders after 0.4.0, after earlier commits,
and before the real 0.4.1. The full version lands in the bundle's
<App>Version key, which the launcher reads, so it offers each build as an
update and sees it as current once installed.

* Keep the local mirror out of release builds; parse loopback URLs strictly

ARTCRAFT_LAUNCHER_DOWNLOAD_BASE makes the launcher trust the mirror's own
checksums and skip GitHub, so a shipped launcher must not read it: it now
needs the local-mirror cargo feature (cargo run --features local-mirror),
which release builds never enable. The loopback check parsed the URL by
prefix, so http://127.0.0.1:[email protected]/ passed; it now requires the host
to be exactly 127.0.0.1, localhost or [::1] with a numeric port. The same
check guards ARTCRAFT_LAUNCHER_FEED_URL.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: khutchings <[email protected]>
Co-authored-by: Brandon Thomas <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-11 05:03:14 -04:00
Fabio LussiandClaude Opus 5.5 e91d26d99f Verify HTTPS certificates with the OS, not a copy of its root store
On some Windows PCs every app showed "Not available here" / "Offline" and
the tooltip said "invalid peer certificate: UnknownIssuer". We read the
Windows root store once with rustls-native-certs, but Windows only adds
many roots when something asks it to verify a chain. Chrome and Edge
verify on their own, so a PC that only uses them can lack the root
GitHub's certificate needs. Antivirus HTTPS scanning hits the same path.

Use ureq's platform-verifier feature (rustls-platform-verifier) so the OS
checks each chain itself and fetches missing roots. Linux still reads the
system store. No bundled root list comes in.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-10 12:19:31 -04:00
Brandon ThomasandClaude Opus 5.5 ec69f0be2c ArtCraft Launcher: install and update the Craft App Suite
A native Rust/egui launcher for the 12 Craft Apps (7 classic + 5 new).

- Grid (icon cards) or sortable table view, filters and search
- Status per app: available, installed and up to date, or update
  available with version and release date
- Installs where each OS keeps apps, from the official release packages:
  /Applications (DMG), Program Files (MSI), deb/rpm via the system
  package manager (Flatpak/AppImage fallback), /usr/local on FreeBSD
- Detects apps installed by hand; updates keep the installed format
- Every download verified against its published SHA-256; running apps
  are never replaced
- Tray/menu-bar mode, start at login, one notification per new version
- GitHub API with ETag cache, falling back to release pages when
  rate-limited; release source is pluggable for a future catalog API
- Web build lists latest releases with per-platform downloads
- Packaging and release workflows for macOS, Windows (x64/x86/arm64),
  Linux (x86_64/aarch64), FreeBSD and web

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 21:08:24 -04:00