diff --git a/.github/scripts/bundle-appimage.sh b/.github/scripts/bundle-appimage.sh new file mode 100755 index 00000000..4f799a36 --- /dev/null +++ b/.github/scripts/bundle-appimage.sh @@ -0,0 +1,86 @@ +#!/bin/bash +# Usage: bundle-appimage.sh +# Package the release binary into a self-contained AppImage: +# dist/tty7--linux-.AppImage +# +# Unlike the bare tarball (bundle-linux.sh), this bundles the x11/wayland/xkb/ +# fontconfig/freetype runtime libraries alongside the binary, so it launches on +# distros that don't ship the exact same set Ubuntu does — Fedora, Arch, etc. +# (glibc itself is NOT bundled — an AppImage still needs the host glibc to be +# >= the build machine's, so the release runner's Ubuntu sets the floor.) +# +# Completion signatures are loaded at runtime relative to the executable +# (/completions — see terminal::signature), so they go beside the +# binary at usr/bin/completions inside the AppDir. +set -euo pipefail + +TARGET="$1" +ARCH="$2" +VERSION="$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"([^"]+)".*/\1/')" +NAME="tty7-${VERSION}-linux-${ARCH}" + +# AppImage tools need FUSE to self-mount; CI runners usually lack it, so extract +# and run instead. Harmless on machines that do have FUSE. +export APPIMAGE_EXTRACT_AND_RUN=1 + +# linuxdeploy is published per-arch; map Rust's arch label to its naming. +case "$ARCH" in + x86_64) LD_ARCH=x86_64 ;; + arm64 | aarch64) LD_ARCH=aarch64 ;; + *) echo "unsupported arch for AppImage: $ARCH" >&2; exit 1 ;; +esac + +TOOLS="$(mktemp -d)" +LINUXDEPLOY="$TOOLS/linuxdeploy-${LD_ARCH}.AppImage" +APPIMAGETOOL="$TOOLS/appimagetool-${LD_ARCH}.AppImage" +curl -fsSL -o "$LINUXDEPLOY" \ + "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-${LD_ARCH}.AppImage" +curl -fsSL -o "$APPIMAGETOOL" \ + "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-${LD_ARCH}.AppImage" +chmod +x "$LINUXDEPLOY" "$APPIMAGETOOL" + +# NB: don't wipe dist/ — the tarball step (bundle-linux.sh) runs first and its +# artifact must survive. Only clean our own AppDir. +APPDIR="dist/AppDir" +rm -rf "$APPDIR" +mkdir -p "$APPDIR/usr/bin" + +cp "target/${TARGET}/release/tty7" "$APPDIR/usr/bin/tty7" +chmod +x "$APPDIR/usr/bin/tty7" + +# A desktop entry + icon are mandatory AppImage metadata; linuxdeploy places +# them and generates AppRun. Icon basename must match the desktop's Icon= key. +cat > "$TOOLS/tty7.desktop" <<'DESKTOP' +[Desktop Entry] +Type=Application +Name=tty7 +Comment=A fast, native terminal +Exec=tty7 +Icon=tty7 +Categories=System;TerminalEmulator; +Terminal=false +StartupWMClass=tty7 +DESKTOP +# linuxdeploy only accepts fixed icon resolutions (…256, 384, 512 — NOT the +# source's 1024), so downscale to 256×256. +convert assets/app-icon.png -resize 256x256 "$TOOLS/tty7.png" + +# Phase 1 — populate the AppDir: copy in dependent libs (ldd + patchelf) and +# install the desktop/icon into their standard locations. +"$LINUXDEPLOY" \ + --appdir "$APPDIR" \ + --executable "$APPDIR/usr/bin/tty7" \ + --desktop-file "$TOOLS/tty7.desktop" \ + --icon-file "$TOOLS/tty7.png" + +# Runtime-loaded completion specs live beside the binary (not bundled by +# linuxdeploy, which only tracks ELF deps), so drop them in after populate. +mkdir -p "$APPDIR/usr/bin/completions" +cp assets/completions/*.json "$APPDIR/usr/bin/completions/" + +# Phase 2 — pack the finished AppDir. Done separately from linuxdeploy so the +# completions added above are included. +"$APPIMAGETOOL" "$APPDIR" "dist/${NAME}.AppImage" +chmod +x "dist/${NAME}.AppImage" +rm -rf "$APPDIR" "$TOOLS" +echo "✅ dist/${NAME}.AppImage" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 40e71101..98bdc9dc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -50,7 +50,8 @@ jobs: sudo apt-get update sudo apt-get install -y pkg-config cmake clang libxkbcommon-dev \ libxkbcommon-x11-dev libfontconfig1-dev libfreetype6-dev \ - libwayland-dev libx11-dev libxcb1-dev libzstd-dev libssl-dev + libwayland-dev libx11-dev libxcb1-dev libzstd-dev libssl-dev \ + libfuse2 file imagemagick - uses: dtolnay/rust-toolchain@stable with: @@ -89,6 +90,14 @@ jobs: working-directory: tty7 run: bash .github/scripts/bundle-linux.sh "${{ matrix.target }}" "${{ matrix.arch }}" + # AppImage bundles the x11/wayland/xkb/font libs so it runs on Fedora/Arch/ + # etc., not just Ubuntu. Kept separate from the tarball step so the tarball + # still ships even if AppImage tooling changes upstream. + - name: Package Linux AppImage + if: matrix.os == 'linux' + working-directory: tty7 + run: bash .github/scripts/bundle-appimage.sh "${{ matrix.target }}" "${{ matrix.arch }}" + - name: Package Windows installer + zip if: matrix.os == 'windows' working-directory: tty7 @@ -104,3 +113,4 @@ jobs: tty7/dist/*.tar.gz tty7/dist/*.zip tty7/dist/*-setup.exe + tty7/dist/*.AppImage diff --git a/README.md b/README.md index aa1d3b84..794a42aa 100644 --- a/README.md +++ b/README.md @@ -43,8 +43,10 @@ Download the build for your platform from - **Windows** — `…-windows-x86_64-setup.exe` (installer: Start Menu shortcut + uninstall entry), or `…-windows-x86_64.zip` (portable: unzip and run `tty7.exe`). -- **Linux** — `…-linux-x86_64.tar.gz`; extract and run `./tty7` (needs the usual - x11/wayland runtime libraries). +- **Linux** — `…-linux-x86_64.AppImage` (recommended: bundles the x11/wayland + libraries, so it runs on Fedora / Arch / etc. with no extra packages — + `chmod +x` and run), or `…-linux-x86_64.tar.gz` (bare binary; extract and run + `./tty7`, needs the usual x11/wayland runtime libraries installed). ## Features diff --git a/README.zh-CN.md b/README.zh-CN.md index 6333f1f0..b3793156 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -39,8 +39,10 @@ macOS、Windows、Linux 三平台原生构建,每个 release 一起打出。 (Intel);打开后把 `tty7.app` 拖进「应用程序」即可。 - **Windows** —— `…-windows-x86_64-setup.exe`(安装包:带开始菜单快捷方式和 卸载入口),或 `…-windows-x86_64.zip`(便携版:解压后运行 `tty7.exe`)。 -- **Linux** —— `…-linux-x86_64.tar.gz`;解压后运行 `./tty7`(需要常见的 - x11/wayland 运行时库)。 +- **Linux** —— `…-linux-x86_64.AppImage`(推荐:已打包 x11/wayland 依赖库, + Fedora / Arch 等发行版免装依赖,`chmod +x` 后直接运行),或 + `…-linux-x86_64.tar.gz`(裸二进制,解压后运行 `./tty7`,需自行装齐常见的 + x11/wayland 运行时库)。 ## 功能