feat(release): publish a Linux .deb alongside the AppImage - #4887
feat(release): publish a Linux .deb alongside the AppImage#4887NaveDanan wants to merge 1 commit into
Conversation
Linux users can only install T3 Code from an AppImage today, which means no desktop entry, no icon, no dependency resolution, and no package manager integration unless they wire it up themselves. The build script already forwarded `--target` to electron-builder, but a deb build aborted because fpm requires a project homepage and a `Name <email>` maintainer that the generated config never set. Adding those two fields makes `--target deb` work, and the release workflow now repackages the already-compiled Linux app into a .deb and attaches it to the GitHub Release. electron-builder writes update metadata for every fpm target, so the deb build would clobber the AppImage updater manifest. Since Linux auto-update only supports the AppImage, the workflow stashes and restores that manifest around the deb step. Built and verified locally on Ubuntu 24.04: correct control fields, all nine hicolor icon sizes, valid desktop entry, and every declared dependency resolvable. Generated with claude-opus-5 running in opencode.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ApprovabilityVerdict: Approved a37813e This PR adds .deb packaging to the Linux release workflow without modifying runtime behavior. Changes are additive CI/CD configuration with proper manifest handling to preserve AppImage updates, appropriate constants for fpm requirements, and test coverage. You can customize Macroscope's approvability policy. Learn more. |
The desktop build script already accepts `--target deb`; the target string is
passed through to electron-builder untouched and the artifact copy step is
target-agnostic. A deb build fails only because app-builder-lib's FpmTarget
requires two metadata fields the staged package.json omits: `homepage`
(control "Homepage:") and `maintainer` (control "Maintainer:", otherwise
derived from `author`, which carries no email). AppImage needs neither, so
nothing surfaced this.
Rather than add a second Linux matrix entry -- whose upload artifact name
`desktop-linux-x64` would collide with the AppImage entry's -- let the existing
Linux entry emit both targets from one electron-builder run. `--target` now
takes a comma-separated list, and artifactName's ${ext} already keeps the output
files distinct, so there is one artifact name, one runner, and no collision.
The .deb also has to be listed in the collect step and in both
action-gh-release file lists, or it builds and never ships.
Packages declare Electron's shared-library dependencies per format, so a
minimal Debian/Ubuntu install pulls them in instead of the app failing to
start. The same wiring covers `rpm`, exposed as `dist:desktop:rpm` for local
builds; the release workflow stays AppImage+deb because the runners have no
`rpmbuild`.
Consolidates the overlapping .deb work from pingdotgg#4887, pingdotgg#4900 and pingdotgg#5139: the
dependency lists and the rpm target come from @bigpod98's pingdotgg#5139, the docs and
the download-page card from @benthecarman's pingdotgg#4900.
The .deb is not an updater payload -- in-app updates on Linux stay
AppImage-only, so .deb installs upgrade through dpkg/apt. Documented in
docs/operations/release.md.
|
you can just use gear lever to manage appimages, it has desktop integration & supports auto update: https://github.com/mijorus/gearlever |
Problem
Linux is the only platform where T3 Code ships a single artifact. The AppImage works, but installing it leaves users without a desktop entry, an icon, dependency resolution, or any package manager integration unless they wire all of it up by hand.
.debcovers the large majority of Linux desktop users and costs one extra packaging pass over an app we have already compiled.What changed
Made
--target debactually work.scripts/build-desktop-artifact.tsalready forwarded--targetstraight through to electron-builder, sodeblooked supported. It was not: fpm aborts unless it can resolve a project homepage and aName <email>maintainer, and the generated config set neither, because AppImage never needed them.Two fields fix it —
homepageon the stagedpackage.jsonandlinux.maintainer, which becomes both the debMaintainerandVendor.Release workflow builds and publishes it. A platform-gated step reruns packaging with
--skip-build, reusing the app the AppImage step already compiled, then.debis added to the collect and publish globs. This deliberately avoids a second Linux matrix leg, which would have duplicated a ~25 minute compile and collided on thedesktop-linux-x64andresource-monitor-linux-x64artifact names.Guarded the updater manifest.
FpmTargetsetsisWriteUpdateInfo: true, exactly likeAppImageTarget, so the deb build overwriteslatest-linux.yml.DesktopUpdates.tsrefuses to install any Linux update unless the app is running from an AppImage, so an unguarded version of this change would publish a manifest pointing at a.debthe app rejects and silently break auto-update for every existing AppImage user. The workflow stashes the manifest and restores it after packaging.Also adds
vp run dist:desktop:linux:debfor local parity withdist:desktop:linux, and documents the artifact plus the update caveat.Verification
Built end-to-end on Ubuntu 24.04 at v0.0.31:
assets/prod/black-universal-1024.png.StartupWMClass=t3code; postinst registers/usr/bin/t3codeand handleschrome-sandboxpermissions.libgtk-3-0andlibatspi2.0-0via thet64packages thatProvidethem).linux.maintaineris removed, so the build break cannot silently return.vp test run scripts/build-desktop-artifact.test.ts(31 passed),scriptstypecheck, lint, andfmt:checkall clean.set -euo pipefail, including the case where no manifest exists.Notes for reviewers
The maintainer address needs your call. The repo has no packaging contact anywhere, so
support@t3.codesis a placeholder derived from the site. It gets baked permanently into every published package — please replace it if there is a real address.In-app updates are intentionally not enabled for deb. The
.debships bothapp-update.ymland electron-builder'spackage-typemarker, soelectron-updaterwould selectDebUpdater, but T3's own Linux gate blocks it first and deb users will see "Automatic updates on Linux require running the AppImage build." Turning that on means accepting apkexec dpkg -iprompt per update and pointing the feed at the deb, which is a separate decision I did not make here. Most distro-packaged apps leave updates to the package manager.Scope.
.snapwas built and verified alongside this but is deliberately excluded: it needs a Snap Store account, credentials, and manual review for classic confinement, which is a product decision rather than a packaging one. Happy to open it separately if wanted.Per
CONTRIBUTING.mdI recognise this may not be something you want right now — close it freely if so.Generated with claude-opus-5 running in opencode.
Note
Medium Risk
Release workflow changes affect Linux updater metadata and published assets; incorrect manifest handling could break AppImage auto-update, though the backup/restore step mitigates that. Maintainer email is baked into every deb package.
Overview
Adds a Linux
.debto release artifacts so Debian/Ubuntu users can install via the package manager, while in-app auto-update stays AppImage-only.The desktop packager now supplies homepage and
linux.maintainer(fpm requirements fordeb) on the stagedpackage.jsonand Linux build config, plus adist:desktop:linux:debscript and a regression test so deb builds cannot break silently.The release workflow runs a second Linux packaging pass with
--skip-buildafter the AppImage step, backs up and restores*-linux*.ymlupdater manifests (deb packaging would overwrite them with.debmetadata the app refuses to install), and includes.debin collect/publish globs. Docs note the deb vs AppImage update behavior.Reviewed by Cursor Bugbot for commit a37813e. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Publish a Linux .deb package alongside the AppImage in release builds
dist:desktop:artifactwith--target debafter the AppImage is built, stashing and restoring the AppImage update manifest so it isn't overwritten by the.debbuild.maintainerandhomepagemetadata to the Linux build config in build-desktop-artifact.ts, which are required by electron-builder's fpm-backed targets like.deb.dist:desktop:linux:debnpm script inpackage.jsonfor local builds..debpackage; only the AppImage supports update delivery.Macroscope summarized a37813e.