Skip to content

Ship the v2 CPU tier as a delta, and bundle deps in the AppImage (deps 1.13.0) - #119

Merged
StuartCameronCode merged 2 commits into
mainfrom
deps-v2-delta-appimage-bundle
Oct 18, 2026
Merged

StuartCameronCode merged 2 commits into
mainfrom
deps-v2-delta-appimage-bundle

Conversation

@StuartCameronCode

Copy link
Copy Markdown
Owner

Why

The AppImage catalog picked up the 1.2.0 AppImage on its own and its test failed (AppImage/appimage.github.io#9839). The catalog launches each AppImage with firejail --net=none and OCRs a screenshot for error text. VapourBox's first act on a fresh machine is to download its deps, so it showed "Installation Failed" and the OCR read that as an error. It also warned about "linux" in the file name and the missing AppStream metadata.

This makes the AppImage carry its deps so first launch needs no network. To do that without shipping two 236 MB bundles, the older-CPU (v2) tier becomes a small delta over the main bundle.

What changes

Deps 1.13.0 (packaging only; same sources as 1.12.0)

  • Each x64 platform publishes its v3 bundle under the plain name plus …-x64-v2-delta.zip (2–3 MB): the files listed under _tierFiles in Scripts/deps-expected-plugins.json, extracted over the bundle. There is no longer a full …-x64-v2.zip.
  • Scripts/make-deps-delta.py cuts the delta. It fails if the two builds hold different sets of paths, or if a tier file is identical in both.
  • The build-deps-* workflows build both tiers, cut the delta, gate the composed tree (SDE on Linux/Windows, load-time check on macOS), then upload.
  • app/assets/deps-version.json points at 1.13.0 with "tierFormat": "delta".

App (DependencyManager)

  • Each zip comes from bundled-deps/ beside the executable (sidecar hash required), then the download cache, then the network.
  • On a v2 CPU it extracts the bundle, then the delta; a delta cut against a different bundle (baseSha256) is refused.
  • No zip's own version.json is extracted; the app's copy stays the commit marker.
  • Extraction no longer spawns a chmod per file or awaits three calls per file (a917731): first launch of the bundled AppImage went from ~130 s to ~16–22 s on linux-arm64.

Linux package

  • The AppImage carries the deps zips (package-linux.sh --bundle-deps); the tarball does not.
  • Renamed VapourBox-X-x86_64.AppImage / -aarch64.AppImage. The tarball keeps linux-<arch>.
  • A copy of each .zsync is also published under the old name (VapourBox-X-linux-<arch>.AppImage.zsync) so 1.2.0 AppImages can still find their update.
  • AppStream metadata in packaging/linux/app.vapourbox.VapourBox.appdata.xml, stamped with version, date and a tag-pinned screenshot at package time.

CI: .github/scripts/install-deps-bundle.sh composes bundle plus delta for -v2 rows, the same way the app does.

Verified

  • build-deps-macos / -windows / -linux on this branch: all jobs green, including the new delta and gate jobs. Assets are on the draft release deps-v1.13.0.
  • ci-test.yml and nightly.yml on this branch against those unpublished artifacts (deps_run_id): all green. The nightly -v2 rows installed bundle plus delta and ran real encodes on all three x64 platforms.
  • Bundled-deps AppImage first launch, on a linux-arm64 VM (a917731).
  • Local non-heavy Flutter suite.

Not yet verified

  • build-linux.yml: it fetches the deps with anonymous curl, so it cannot run until deps-v1.13.0 is published. First real run is the next app release.
  • The offline first launch on x86_64, on both tiers.
  • The bridge .zsync: AppImageUpdate from a real 1.2.0 AppImage.
  • appstreamcli on ubuntu-22.04 accepting the appdata file (the package step validates it).

Merge order

Normal CI on this PR will fail until the deps release is published, because it downloads deps-v1.13.0 by tag and the release is still a draft (the push-triggered probe-cpu-compat run failed for the same reason).

  1. gh release edit deps-v1.13.0 --target main --draft=false --latest=false
  2. Re-run CI on this PR, then merge.
  3. Cut the next app release; both .zsync files must be uploaded beside each AppImage.
  4. /retest on the catalog PR.

Before the app release, check docs/images/screenshot.png is current; it becomes the catalog's screenshot.

🤖 Generated with Claude Code

StuartCameronCode and others added 2 commits October 10, 2026 16:27
…ppImage

The AppImage catalog's test launches an AppImage with no network, and
VapourBox's first act was to download its deps, so the listing failed on
an "Installation Failed" dialog (AppImage/appimage.github.io#9839).

Deps 1.13.0 (packaging only; same sources as 1.12.0):
- Each x64 platform publishes its v3 bundle plus a small
  <platform>-v2-delta.zip of the files in _tierFiles, extracted over it,
  instead of a second full bundle. Scripts/make-deps-delta.py cuts it and
  the build-deps-* workflows gate the composed v2 tree before uploading.
- deps-version.json gains "tierFormat": "delta".

App:
- DependencyManager takes each zip from bundled-deps/ beside the
  executable, then the cache, then the network; applies the delta over
  the bundle on a v2 CPU and refuses one cut against a different bundle.
- A zip's own version.json is never extracted; the app's copy stays the
  commit marker.

Linux package:
- The AppImage carries the deps zips (--bundle-deps); the tarball does not.
- Renamed to VapourBox-X-x86_64.AppImage / -aarch64.AppImage, with a copy
  of the .zsync under the old name so 1.2.0 can still update.
- AppStream metadata (app.vapourbox.VapourBox.appdata.xml).

CI installs a v2 tier the way the app does, through
.github/scripts/install-deps-bundle.sh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
First launch of the bundled-deps AppImage took ~130 s on linux-arm64 under
Xvfb, nearly all of it parked at 28% of "Extracting...". Two causes, both in
extractBundle:

- one `chmod +x` process per file whose name has no dot. The bundled Python's
  terminfo matches that test: 2,847 spawns for the 1.13.0 linux-arm64 bundle,
  2,798 of them terminfo entries. Now collected and run in batches of 500.
- three awaited async calls per file on the UI isolate, ~14 ms a file under
  software rendering. Writes are now synchronous, yielding to the UI at each
  2 MB progress tick.

The same launch now reaches the main window in ~16-22 s. The set of files
made executable is unchanged.

Also ignore bundled-deps/, where the --bundle-deps zips are downloaded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@StuartCameronCode
StuartCameronCode merged commit 1c561f8 into main Oct 18, 2026
4 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant