Linux: AppImage, deb, rpm and Arch packages from one AppDir, installed to /opt/ely-office (L1.5)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-11 11:55:14 -04:00
1 parent e3bfe8ade4
commit 15106b641f
15 files changed
+251 -21

No files matched your search

+1 -1
View File
@@ -17,7 +17,7 @@ command -v desktop-file-validate >/dev/null || {
count=0
while IFS=$'\t' read -r slug name _; do
file=$work/$slug.desktop
"$root/packaging/linux/appimage.sh" --desktop "$slug" >"$file"
"$root/packaging/linux/package.sh" --desktop "$slug" >"$file"
report=$(desktop-file-validate "$file" 2>&1) || fail "$slug.desktop is not valid: $report"
[ -z "$report" ] || fail "$slug.desktop has hints: $report"
grep -qx "Name=$name" "$file" || fail "$slug.desktop has the wrong name"
+65
View File
@@ -0,0 +1,65 @@
#!/usr/bin/env bash
# deb, rpm and Arch packages install cleanly and link.
set -euo pipefail
root=$(cd "$(dirname "$0")/../.." && pwd)
dist=${ELY_DIST:-$root/dist}
fail() {
echo "FAIL: $*" >&2
exit 1
}
command -v docker >/dev/null || {
echo "SKIP: no docker"
exit 0
}
version=$(awk -F'"' '/^version = / { print $2; exit }' "$root/Cargo.toml")
batch=$(awk -F'\t' '$4 == 1 { print $1 }' "$root/packaging/apps.tsv")
# Entry points exist; every ELF file finds its libraries.
check='set -euo pipefail
slug=$1
entry=/opt/ely-office/$slug/bin/$slug
[ -x "/usr/bin/$slug" ] || { echo "no /usr/bin/$slug"; exit 1; }
[ "$(readlink -f "/usr/bin/$slug")" = "$entry" ] || { echo "bad /usr/bin/$slug"; exit 1; }
[ -f "/usr/share/applications/$slug.desktop" ] || { echo "no desktop entry"; exit 1; }
[ -f "/usr/share/icons/hicolor/512x512/apps/$slug.png" ] || { echo "no icon"; exit 1; }
for lib in libvulkan.so.1 libwayland-client.so.0; do
ldconfig -p | grep "$lib" >/dev/null || { echo "no $lib"; exit 1; }
done
ldd "$entry" >/dev/null || { echo "$entry is not a dynamic executable"; exit 1; }
find "/opt/ely-office/$slug" -type f -print0 >/tmp/files || { echo "cannot list files"; exit 1; }
checked=0
while IFS= read -r -d "" file; do
magic=$(head -c 4 "$file" | od -An -c | tr -d " ") || { echo "cannot read $file"; exit 1; }
[ "$magic" = 177ELF ] || continue
checked=$((checked + 1))
if ! out=$(ldd "$file" 2>&1); then
# git-lfs is static Go: it must run.
[ "${file##*/}" = git-lfs ] && "$file" version >/dev/null && continue
echo "$file: $out"; exit 1
fi
if [[ $out == *"not found"* ]]; then
echo "$file:"; printf "%s\n" "$out" | grep "not found"; exit 1
fi
done </tmp/files
[ "$checked" -gt 0 ] || { echo "no ELF files"; exit 1; }
echo "$slug: $checked ELF files link"'
run() { # image, install command, package file, slug
docker run --rm -v "$dist:/dist:ro" "$1" bash -c "{ $2 /dist/${3##*/}; } >/tmp/install.log 2>&1 ||
{ tail -20 /tmp/install.log; exit 1; }; bash -c '$check' _ $4" ||
fail "$3 does not install or link in $1"
}
ubuntu=ubuntu:26.04@sha256:f144425ff09be612d6d9ad965196e9cdc23dae1f42110a8a11a3e9a8198759f7
fedora=fedora:44@sha256:43b29f65a41eb9c35e1cd5323e3bdf3b655c2357a9f4f1ff2f9c2798e5045d80
arch=archlinux@sha256:4e77cf2ea5f410e6f8be5abf93ccf17ce2436e87a138c167208356711a405dbd
for slug in $batch; do
deb=$dist/${slug}_$version-1_amd64.deb
rpm=$dist/$slug-$version-1.x86_64.rpm
pkg=$dist/$slug-$version-1-x86_64.pkg.tar.zst
for file in "$deb" "$rpm" "$pkg"; do
[ -f "$file" ] || fail "no $file; run packaging/linux/package.sh $slug"
done
run "$ubuntu" "apt-get update -q && apt-get install -y -q" "$deb" "$slug"
run "$fedora" "dnf install -y -q" "$rpm" "$slug"
run "$arch" "pacman -Sy --noconfirm && pacman -U --noconfirm" "$pkg" "$slug"
done
echo "linux-packages: deb, rpm and Arch packages install and link"
@@ -1,9 +1,9 @@
#!/usr/bin/env bash
# Every AppImage tool the recipe downloads matches its pinned hash.
# Every Linux packaging tool downloaded matches its pinned hash.
set -euo pipefail
root=$(cd "$(dirname "$0")/../.." && pwd)
script=$root/packaging/linux/appimage.sh
script=$root/packaging/linux/package.sh
fail() {
echo "FAIL: $*" >&2
exit 1
@@ -12,18 +12,22 @@ fail() {
pack=https://github.com/AppImage/appimagetool/releases/download/1.9.1
deploy=https://github.com/linuxdeploy/linuxdeploy/releases/download/1-alpha-20251107-1
runtime=https://github.com/AppImage/type2-runtime/releases/download/20251108
nfpm=https://github.com/goreleaser/nfpm/releases/download/v2.47.0
curl -fsSI --max-time 20 "$pack/appimagetool-x86_64.AppImage" >/dev/null 2>&1 || {
echo "SKIP appimage-pins: GitHub is not reachable"
echo "SKIP linux-pins: GitHub is not reachable"
exit 0
}
grep -q "$pack/appimagetool-\$arch.AppImage" "$script" || fail "the script downloads another appimagetool"
grep -q "$deploy/linuxdeploy-\$arch.AppImage" "$script" || fail "the script downloads another linuxdeploy"
grep -q "$runtime/runtime-\$arch" "$script" || fail "the script downloads another runtime"
grep -q "$nfpm/nfpm_2.47.0_Linux_\$nfpm_arch.tar.gz" "$script" || fail "the script downloads another nfpm"
grep -q -- '--runtime-file "\$runtime"' "$script" || fail "appimagetool fetches its own runtime"
for arch in x86_64 aarch64; do
for url in "$pack/appimagetool-$arch.AppImage" "$deploy/linuxdeploy-$arch.AppImage" "$runtime/runtime-$arch"; do
for pair in x86_64:x86_64 aarch64:arm64; do
arch=${pair%:*}
for url in "$pack/appimagetool-$arch.AppImage" "$deploy/linuxdeploy-$arch.AppImage" "$runtime/runtime-$arch" \
"$nfpm/nfpm_2.47.0_Linux_${pair#*:}.tar.gz"; do
sha=$(curl -fsSL "$url" | shasum -a 256 | cut -d' ' -f1)
grep -q "$sha" "$script" || fail "$url has sha256 $sha, which the script does not pin"
done
done
echo "appimage-pins: 6 downloads match their pins"
echo "linux-pins: 8 downloads match their pins"
+1 -1
View File
@@ -10,7 +10,7 @@ fail() {
}
count=0
for slug in $(cut -f1 "$types" | sort -u); do
desktop=$("$root/packaging/linux/appimage.sh" --desktop "$slug")
desktop=$("$root/packaging/linux/package.sh" --desktop "$slug")
windows=$("$root/packaging/windows/types.sh" "$slug")
rows=$(awk -F'\t' -v slug="$slug" '$1 == slug' "$types")
while IFS=$'\t' read -r _ ext mime; do