From c4495beb39cc002cca39493b1bffab8707343ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Sat, 10 Oct 2026 19:16:13 -0400 Subject: [PATCH] Windows installer and Linux AppImage carry their engines; a runner probe Both build on packaging/stage.sh. The NSIS installer takes the staged folder and removes only what it laid out; installer.sh drives it. The AppImage gives linuxdeploy the app, the workers and libcef.so. ElyPDF's test window installs the app's menus first, as ElyTree's does. probe.yml reports what each Gitea runner holds. Co-Authored-By: Claude Opus 5.5 --- .gitea/workflows/probe.yml | 18 ++++++++++++++++++ apps/ely-pdf/src/tests.rs | 6 ++++++ packaging/linux/appimage.sh | 28 ++++++++++++++++++++++------ packaging/stage.sh | 0 packaging/windows/installer.nsi | 23 +++++++++++++++++------ packaging/windows/installer.sh | 29 +++++++++++++++++++++++++++++ 6 files changed, 92 insertions(+), 12 deletions(-) create mode 100644 .gitea/workflows/probe.yml mode change 100644 => 100755 packaging/stage.sh create mode 100755 packaging/windows/installer.sh diff --git a/.gitea/workflows/probe.yml b/.gitea/workflows/probe.yml new file mode 100644 index 0000000..dc607d3 --- /dev/null +++ b/.gitea/workflows/probe.yml @@ -0,0 +1,18 @@ +name: probe +on: workflow_dispatch +jobs: + probe: + strategy: + matrix: + os: [macos-arm64, windows, linux] + runs-on: ${{ matrix.os }} + steps: + - name: Where this runner is + shell: bash + run: | + uname -a; echo "home=$HOME pwd=$PWD"; whoami + for d in "$HOME/Documents/GitHub/ElyOffice" "$HOME/Documents/Github/ElyOffice" /c/Users/zhang/Documents/Github/ElyOffice; do + [ -d "$d" ] && { echo "clone: $d"; ls "$d/engines" 2>/dev/null | tr '\n' ' '; echo; git -C "$d" log --oneline -1; } + done + which cargo rustc git python3 cmake ninja makensis 2>/dev/null || true + df -h . | tail -1 diff --git a/apps/ely-pdf/src/tests.rs b/apps/ely-pdf/src/tests.rs index 40ba2c9..458f0de 100644 --- a/apps/ely-pdf/src/tests.rs +++ b/apps/ely-pdf/src/tests.rs @@ -72,6 +72,12 @@ pub(crate) fn windowed<'a>( ely_ui::i18n::install(cx); }); cx.update(crate::keys::bind); + cx.update(|cx| { + // As document_root does: menus before the window. + let menus = crate::keys::menus(cx); + let file = &ely_ui::commands::FILE; + cx.set_menus(ely_ui::commands::menus(ely_platform::AppId::Pdf, file, true, menus, cx)); + }); let held = match worker { true => Mupdf::with(Worker::spawn().expect("the worker")), false => Mupdf::default(), diff --git a/packaging/linux/appimage.sh b/packaging/linux/appimage.sh index b5aed2e..dac4056 100755 --- a/packaging/linux/appimage.sh +++ b/packaging/linux/appimage.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Builds dist/-.AppImage. Usage: appimage.sh | --desktop +# Builds dist/--linux-.AppImage. Usage: appimage.sh [--desktop] set -euo pipefail root=$(cd "$(dirname "$0")/../.." && pwd) @@ -72,15 +72,31 @@ fetch_tool "$pack" "https://github.com/AppImage/appimagetool/releases/download/1 fetch_tool "$deploy" "https://github.com/linuxdeploy/linuxdeploy/releases/download/1-alpha-20251107-1/linuxdeploy-$arch.AppImage" "$deploy_sha" fetch_tool "$runtime" "https://github.com/AppImage/type2-runtime/releases/download/20251108/runtime-$arch" "$runtime_sha" -cargo build --manifest-path "$root/Cargo.toml" --release -p "$slug" +stage=$root/target/stage/$slug +"$root/packaging/stage.sh" "$slug" "$stage" work=$(mktemp -d) trap 'rm -rf "$work"' EXIT desktop_entry >"$work/$slug.desktop" +appdir=$work/$name.AppDir +bin=$appdir/usr/bin +mkdir -p "$bin" +cp -R "$stage"/. "$bin/" +deployed=(--executable "$bin/$slug") +for helper in ely-lok-worker ely-pdf-worker; do + if [ -f "$bin/$helper" ]; then + deployed+=(--executable "$bin/$helper") + fi +done +if [ -f "$bin/libcef.so" ]; then + deployed+=(--library "$bin/libcef.so") +fi # linuxdeploy bundles libraries and fails on a missing one. -"$deploy" --appimage-extract-and-run --appdir "$work/$name.AppDir" \ - --executable "$root/target/release/$slug" --desktop-file "$work/$slug.desktop" --icon-file "$icon" +"$deploy" --appimage-extract-and-run --appdir "$appdir" "${deployed[@]}" \ + --desktop-file "$work/$slug.desktop" --icon-file "$icon" mkdir -p "$dist" -ARCH=$arch "$pack" --appimage-extract-and-run --runtime-file "$runtime" "$work/$name.AppDir" "$dist/$name-$arch.AppImage" -echo "$dist/$name-$arch.AppImage" +version=$(awk -F'"' '/^version = / { print $2; exit }' "$root/Cargo.toml") +out=$dist/$name-$version-linux-$arch.AppImage +ARCH=$arch "$pack" --appimage-extract-and-run --runtime-file "$runtime" "$appdir" "$out" +echo "$out" diff --git a/packaging/stage.sh b/packaging/stage.sh old mode 100644 new mode 100755 diff --git a/packaging/windows/installer.nsi b/packaging/windows/installer.nsi index 9d1e195..14d1a58 100644 --- a/packaging/windows/installer.nsi +++ b/packaging/windows/installer.nsi @@ -1,4 +1,4 @@ -; Per-user installer; pass APP_NAME, APP_SLUG, VERSION, EXE, ICON, TYPES. +; Per-user installer; pass APP_NAME, APP_SLUG, VERSION, STAGE, ICON, TYPES. Unicode true !include "MUI2.nsh" @@ -11,8 +11,8 @@ Unicode true !ifndef VERSION !error "pass -DVERSION" !endif -!ifndef EXE - !error "pass -DEXE" +!ifndef STAGE + !error "pass -DSTAGE, a folder from packaging/stage.sh" !endif !ifndef ICON !error "pass -DICON" @@ -47,7 +47,7 @@ LangString DeleteData ${LANG_ENGLISH} "Also delete the cache, accounts and local Section "Install" SetOutPath "$INSTDIR" - File "/oname=${APP_SLUG}.exe" "${EXE}" + File /r "${STAGE}\*.*" File "/oname=${APP_SLUG}.ico" "${ICON}" WriteUninstaller "$INSTDIR\uninstall.exe" CreateShortcut "$SMPROGRAMS\${APP_NAME}.lnk" "$INSTDIR\${APP_SLUG}.exe" "" "$INSTDIR\${APP_SLUG}.ico" @@ -63,9 +63,20 @@ Section "Install" SectionEnd Section "Uninstall" - Delete "$INSTDIR\${APP_SLUG}.exe" + ; What stage.sh lays out, and nothing else. + RMDir /r "$INSTDIR\libreoffice" + RMDir /r "$INSTDIR\tessdata" + RMDir /r "$INSTDIR\git" + RMDir /r "$INSTDIR\content" + RMDir /r "$INSTDIR\locales" + RMDir /r "$INSTDIR\licenses" + Delete "$INSTDIR\*.exe" + Delete "$INSTDIR\*.dll" + Delete "$INSTDIR\*.pak" + Delete "$INSTDIR\*.bin" + Delete "$INSTDIR\*.dat" + Delete "$INSTDIR\*.json" Delete "$INSTDIR\${APP_SLUG}.ico" - Delete "$INSTDIR\uninstall.exe" RMDir "$INSTDIR" Delete "$SMPROGRAMS\${APP_NAME}.lnk" DeleteRegKey HKCU "Software\Ely Office\${APP_NAME}" diff --git a/packaging/windows/installer.sh b/packaging/windows/installer.sh new file mode 100755 index 0000000..dca2e99 --- /dev/null +++ b/packaging/windows/installer.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# Builds dist/--windows-x86_64-setup.exe. Usage: installer.sh +set -euo pipefail + +root=$(cd "$(dirname "$0")/../.." && pwd) +slug=${1:?app slug, such as ely-doc} +dist=${ELY_DIST:-$root/dist} +name=$(awk -F'\t' -v slug="$slug" '$1 == slug { print $2 }' "$root/packaging/apps.tsv") +[ -n "$name" ] || { + echo "installer.sh: unknown app $slug" >&2 + exit 1 +} +version=$(awk -F'"' '/^version = / { print $2; exit }' "$root/Cargo.toml") +makensis=${MAKENSIS:-"/c/Program Files (x86)/NSIS/makensis.exe"} +[ -x "$makensis" ] || { + echo "installer.sh: no makensis at $makensis; install NSIS" >&2 + exit 1 +} +stage=$root/target/stage/$slug +"$root/packaging/stage.sh" "$slug" "$stage" +types=$root/target/stage/$slug-types.nsh +"$root/packaging/windows/types.sh" "$slug" >"$types" +mkdir -p "$dist" +out=$dist/$name-$version-windows-x86_64-setup.exe +"$makensis" -V2 -DAPP_NAME="$name" -DAPP_SLUG="$slug" -DVERSION="$version" \ + -DSTAGE="$(cygpath -w "$stage")" -DICON="$(cygpath -w "$root/assets/icons/$slug.ico")" \ + -DTYPES="$(cygpath -w "$types")" -DOUTFILE="$(cygpath -w "$out")" \ + "$(cygpath -w "$root/packaging/windows/installer.nsi")" +echo "$out"