From 4f70cb1c8bba7ec4824e80b2efef27050f5868a1 Mon Sep 17 00:00:00 2001 From: ZhuchkaTriplesix Date: Mon, 27 Jul 2026 04:23:31 +0300 Subject: [PATCH] feat(ci): publish Linux AppImage on GitHub Releases Add scripts/linux/build_appimage.sh and attach Querya-Desktop-{ver}-linux.AppImage alongside the portable zip. Closes #382 Co-authored-by: Cursor --- .github/workflows/release.yml | 20 +++++++-- .gitignore | 4 ++ docs/tags-and-releases.md | 15 ++++++- scripts/linux/build_appimage.sh | 75 +++++++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+), 6 deletions(-) create mode 100755 scripts/linux/build_appimage.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 57e05ec2..7f8f924f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -119,15 +119,20 @@ jobs: - name: Build Linux (release) run: flutter build linux --release - - name: Zip Linux artifact + - name: Zip Linux artifact (portable) run: | cd build/linux/x64/release/bundle zip -r "${GITHUB_WORKSPACE}/Querya-Desktop-${{ steps.version.outputs.version }}-linux.zip" . + - name: Build Linux AppImage (installable) + run: ./scripts/linux/build_appimage.sh + - uses: actions/upload-artifact@v4 with: name: bundle-linux - path: Querya-Desktop-${{ steps.version.outputs.version }}-linux.zip + path: | + Querya-Desktop-${{ steps.version.outputs.version }}-linux.zip + Querya-Desktop-${{ steps.version.outputs.version }}-linux.AppImage if-no-files-found: error build-macos: @@ -241,10 +246,11 @@ jobs: run: | set -euo pipefail mkdir -p dist - find artifacts -name '*.zip' -exec mv -t dist/ {} + + find artifacts \( -name '*.zip' -o -name '*.AppImage' \) -exec mv -t dist/ {} + test "$(find dist -name '*.zip' | wc -l)" -eq 3 + test "$(find dist -name '*.AppImage' | wc -l)" -eq 1 cd dist - sha256sum *.zip | tee SHA256SUMS.txt + sha256sum *.zip *.AppImage | tee SHA256SUMS.txt - name: Build release notes from CHANGELOG.md run: | @@ -256,10 +262,15 @@ jobs: echo "---" echo "" echo "### Downloads" + echo "" + echo "#### Portable (zip — run from folder)" echo "- **Linux**: \`Querya-Desktop-${VERSION}-linux.zip\`" echo "- **Windows**: \`Querya-Desktop-${VERSION}-windows.zip\`" echo "- **macOS**: \`Querya-Desktop-${VERSION}-macos.zip\` (signed, notarized and stapled \`.app\` when Apple Developer secrets are configured; otherwise unsigned)" echo "" + echo "#### Installable" + echo "- **Linux AppImage**: \`Querya-Desktop-${VERSION}-linux.AppImage\` (\`chmod +x\` then run)" + echo "" echo "Verify checksums: \`SHA256SUMS.txt\`" echo "" echo "### Build info" @@ -285,6 +296,7 @@ jobs: fail_on_unmatched_files: true files: | dist/*.zip + dist/*.AppImage dist/SHA256SUMS.txt env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index dfdc4895..4738764b 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,7 @@ coverage/ *.exe design-front/ docker/sqlite/data/ + +# Local packaging outputs +Querya-Desktop-*.AppImage +Querya-Desktop-*.zip diff --git a/docs/tags-and-releases.md b/docs/tags-and-releases.md index 362912c6..85543e71 100644 --- a/docs/tags-and-releases.md +++ b/docs/tags-and-releases.md @@ -22,8 +22,19 @@ ## Что внутри релиза -- Имена архивов: `Querya-Desktop-X.Y.Z-linux.zip`, `Querya-Desktop-X.Y.Z-windows.zip`, `Querya-Desktop-X.Y.Z-macos.zip` (внутри неподписанный `.app`). -- Версия для имён и тега — **semver из pubspec**; build `+N` попадает в текст релиза как **полный pubspec version**. +### Portable + +- `Querya-Desktop-X.Y.Z-linux.zip`, `…-windows.zip`, `…-macos.zip` (Flutter bundles / `.app`) + +### Installable (Linux) + +- `Querya-Desktop-X.Y.Z-linux.AppImage` — built by [`scripts/linux/build_appimage.sh`](../scripts/linux/build_appimage.sh) in Release CI (`chmod +x` then run) + +Also attached: `SHA256SUMS.txt` (all artifacts). + +Версия для имён и тега — **semver из pubspec**; build `+N` попадает в текст релиза как **полный pubspec version**. + +Другие installable форматы (Windows setup, deb/rpm/Flatpak): epic [#379](https://github.com/QueryaHub/Querya-Desktop/issues/379). ## Changelog в GitHub Release diff --git a/scripts/linux/build_appimage.sh b/scripts/linux/build_appimage.sh new file mode 100755 index 00000000..0f974619 --- /dev/null +++ b/scripts/linux/build_appimage.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash +# Build Querya-Desktop-*.AppImage from a Flutter linux release bundle. +# +# Usage: +# ./scripts/linux/build_appimage.sh [bundle_dir] [output_appimage] +# +# Defaults: +# bundle_dir = build/linux/x64/release/bundle +# output = Querya-Desktop--linux.AppImage +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +BUNDLE="${1:-$ROOT/build/linux/x64/release/bundle}" +BINARY_NAME="querya_desktop" +ICON_SRC="$ROOT/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png" + +if [[ ! -d "$BUNDLE" ]]; then + echo "error: Flutter linux bundle not found: $BUNDLE" >&2 + echo "Run: flutter build linux --release" >&2 + exit 1 +fi +if [[ ! -x "$BUNDLE/$BINARY_NAME" ]]; then + echo "error: missing executable: $BUNDLE/$BINARY_NAME" >&2 + exit 1 +fi +if [[ ! -f "$ICON_SRC" ]]; then + echo "error: icon not found: $ICON_SRC" >&2 + exit 1 +fi + +VERSION="$(grep '^version:' "$ROOT/pubspec.yaml" | sed 's/^version: //; s/+.*//')" +OUT="${2:-$ROOT/Querya-Desktop-${VERSION}-linux.AppImage}" + +WORKDIR="$(mktemp -d "${TMPDIR:-/tmp}/querya-appimage.XXXXXX")" +cleanup() { rm -rf "$WORKDIR"; } +trap cleanup EXIT + +APPDIR="$WORKDIR/AppDir" +mkdir -p "$APPDIR" +cp -a "$BUNDLE"/. "$APPDIR/" + +cp "$ICON_SRC" "$APPDIR/${BINARY_NAME}.png" + +cat > "$APPDIR/${BINARY_NAME}.desktop" < "$APPDIR/AppRun" <<'EOF' +#!/bin/bash +set -euo pipefail +HERE="$(dirname "$(readlink -f "$0")")" +export LD_LIBRARY_PATH="${HERE}/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" +cd "$HERE" +exec "$HERE/querya_desktop" "$@" +EOF +chmod +x "$APPDIR/AppRun" "$APPDIR/$BINARY_NAME" + +TOOL="$WORKDIR/appimagetool" +# Prefer type-2 continuous tool; --appimage-extract-and-run avoids FUSE on CI. +curl -fsSL -o "$TOOL" \ + "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage" +chmod +x "$TOOL" + +ARCH=x86_64 "$TOOL" --appimage-extract-and-run "$APPDIR" "$OUT" +chmod +x "$OUT" +echo "Wrote $OUT"