mirror of
https://github.com/librekeys/picoforge.git
synced 2026-07-28 08:01:19 -07:00
ci[release]: refactor appimage build script to include appimage auto update info
This commit is contained in:
@@ -1,98 +1,189 @@
|
||||
#!/bin/bash
|
||||
set -eo pipefail
|
||||
|
||||
VARIANT=${1:-"glibc-x86_64"}
|
||||
# ──────────────────────────────────────────────
|
||||
# Utility Functions
|
||||
# ──────────────────────────────────────────────
|
||||
|
||||
echo "=== Building PicoForge AppImage for variant: ${VARIANT} ==="
|
||||
detect_src_dir() {
|
||||
if [ -f "/workspace/Cargo.toml" ]; then
|
||||
echo "/workspace"
|
||||
elif [ -f "/workspace/picoforge/Cargo.toml" ]; then
|
||||
echo "/workspace/picoforge"
|
||||
else
|
||||
echo "Error: Cargo.toml not found in /workspace or /workspace/picoforge"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Locate PicoForge source directory
|
||||
if [ -f "/workspace/Cargo.toml" ]; then
|
||||
SRC_DIR="/workspace"
|
||||
elif [ -f "/workspace/picoforge/Cargo.toml" ]; then
|
||||
SRC_DIR="/workspace/picoforge"
|
||||
else
|
||||
echo "Error: Cargo.toml not found in /workspace or /workspace/picoforge"
|
||||
exit 1
|
||||
fi
|
||||
get_version() {
|
||||
local version
|
||||
version="$(grep -m 1 '^version' Cargo.toml | sed -E 's/.*"([0-9]+\.[0-9]+\.[0-9]+)".*/\1/')"
|
||||
echo "${version:-0.0.0}"
|
||||
}
|
||||
|
||||
cd "$SRC_DIR"
|
||||
get_arch_name() {
|
||||
local arch
|
||||
arch="$(uname -m)"
|
||||
case "${arch}" in
|
||||
x86_64) echo "x86-64" ;;
|
||||
aarch64) echo "aarch64" ;;
|
||||
*) echo "${arch}" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Extract version from Cargo.toml
|
||||
VERSION=$(grep -m 1 '^version' Cargo.toml | sed -E 's/.*"([0-9]+\.[0-9]+\.[0-9]+)".*/\1/')
|
||||
if [ -z "$VERSION" ]; then
|
||||
VERSION="0.0.0"
|
||||
fi
|
||||
echo "PicoForge Version: ${VERSION}"
|
||||
compute_output_name() {
|
||||
local version="$1"
|
||||
local variant="$2"
|
||||
local arch_name="$3"
|
||||
|
||||
# Determine architecture and target naming
|
||||
ARCH=$(uname -m)
|
||||
if [ "$ARCH" == "x86_64" ]; then
|
||||
ARCH_NAME="x86-64"
|
||||
elif [ "$ARCH" == "aarch64" ]; then
|
||||
ARCH_NAME="aarch64"
|
||||
else
|
||||
ARCH_NAME="$ARCH"
|
||||
fi
|
||||
case "${variant}" in
|
||||
glibc-2.28-x86_64|glibc-2.28-aarch64)
|
||||
echo "picoforge_${version}_glibc-2.28_${arch_name}.AppImage"
|
||||
;;
|
||||
musl-x86_64|musl-aarch64)
|
||||
echo "picoforge_${version}_musl_${arch_name}.AppImage"
|
||||
;;
|
||||
*)
|
||||
echo "picoforge_${version}_${variant}_${arch_name}.AppImage"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Define output filename based on variant
|
||||
case "$VARIANT" in
|
||||
glibc-2.28-x86_64|glibc-2.28-aarch64)
|
||||
OUTPUT_NAME="picoforge_${VERSION}_glibc-2.28_${ARCH_NAME}.AppImage"
|
||||
;;
|
||||
musl-x86_64|musl-aarch64)
|
||||
OUTPUT_NAME="picoforge_${VERSION}_musl_${ARCH_NAME}.AppImage"
|
||||
;;
|
||||
*)
|
||||
OUTPUT_NAME="picoforge_${VERSION}_${VARIANT}_${ARCH_NAME}.AppImage"
|
||||
;;
|
||||
esac
|
||||
# ──────────────────────────────────────────────
|
||||
# Build Steps
|
||||
# ──────────────────────────────────────────────
|
||||
|
||||
echo "Building release binary with Cargo..."
|
||||
cargo build --release
|
||||
setup_update_info() {
|
||||
local zsync_glob="$1"
|
||||
|
||||
BINARY_PATH="target/release/picoforge"
|
||||
DESKTOP_FILE="data/in.suyogtandel.picoforge.desktop"
|
||||
ICON_FILE="static/appIcons/in.suyogtandel.picoforge.svg"
|
||||
if [ -z "${GITHUB_REPOSITORY_OWNER}" ] || [ -z "${GITHUB_REPOSITORY}" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ ! -f "$BINARY_PATH" ]; then
|
||||
echo "Error: Binary not found at $BINARY_PATH"
|
||||
exit 1
|
||||
fi
|
||||
local repo_name="${GITHUB_REPOSITORY#*/}"
|
||||
export UPDATE_INFORMATION="gh-releases-zsync|${GITHUB_REPOSITORY_OWNER}|${repo_name}|latest|${zsync_glob}"
|
||||
echo "Set UPDATE_INFORMATION: ${UPDATE_INFORMATION}"
|
||||
}
|
||||
|
||||
if [ ! -f "$DESKTOP_FILE" ]; then
|
||||
echo "Error: Desktop file not found at $DESKTOP_FILE"
|
||||
exit 1
|
||||
fi
|
||||
build_release() {
|
||||
echo "Building release binary with Cargo..."
|
||||
cargo build --release
|
||||
}
|
||||
|
||||
if [ ! -f "$ICON_FILE" ]; then
|
||||
echo "Error: Icon file not found at $ICON_FILE"
|
||||
exit 1
|
||||
fi
|
||||
verify_assets() {
|
||||
local binary="$1"
|
||||
local desktop="$2"
|
||||
local icon="$3"
|
||||
|
||||
echo "Packaging AppImage using linuxdeploy..."
|
||||
export APPIMAGE_EXTRACT_AND_RUN=1
|
||||
if [ ! -f "${binary}" ]; then
|
||||
echo "Error: Binary not found at ${binary}"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f "${desktop}" ]; then
|
||||
echo "Error: Desktop file not found at ${desktop}"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f "${icon}" ]; then
|
||||
echo "Error: Icon file not found at ${icon}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Run linuxdeploy to bundle executable, desktop entry, icon, excluding host daemon libpcsclite
|
||||
rm -rf AppDir
|
||||
linuxdeploy \
|
||||
--appdir AppDir \
|
||||
--executable "$BINARY_PATH" \
|
||||
--desktop-file "$DESKTOP_FILE" \
|
||||
--icon-file "$ICON_FILE" \
|
||||
--exclude-library libpcsclite.so.1 \
|
||||
--output appimage
|
||||
package_appimage() {
|
||||
local output_name="$1"
|
||||
local binary="$2"
|
||||
local desktop="$3"
|
||||
local icon="$4"
|
||||
|
||||
# Find generated AppImage file and rename to standard naming
|
||||
GENERATED_APPIMAGE=$(ls -t *.AppImage 2>/dev/null | head -n 1)
|
||||
echo "Packaging AppImage using linuxdeploy..."
|
||||
export APPIMAGE_EXTRACT_AND_RUN=1
|
||||
|
||||
if [ -z "$GENERATED_APPIMAGE" ]; then
|
||||
echo "Error: AppImage generation failed"
|
||||
exit 1
|
||||
fi
|
||||
if [ -n "${UPDATE_INFORMATION}" ]; then
|
||||
echo "Using UPDATE_INFORMATION: ${UPDATE_INFORMATION}"
|
||||
else
|
||||
echo "UPDATE_INFORMATION not set — AppImage will not support auto-update"
|
||||
fi
|
||||
|
||||
mkdir -p /workspace/target/release
|
||||
mv "$GENERATED_APPIMAGE" "/workspace/target/release/${OUTPUT_NAME}"
|
||||
rm -rf AppDir
|
||||
export LDAI_OUTPUT="${output_name}"
|
||||
|
||||
echo "=== Build Complete! Output: /workspace/target/release/${OUTPUT_NAME} ==="
|
||||
ls -lh "/workspace/target/release/${OUTPUT_NAME}"
|
||||
rm -rf AppDir
|
||||
linuxdeploy \
|
||||
--appdir AppDir \
|
||||
--executable "${binary}" \
|
||||
--desktop-file "${desktop}" \
|
||||
--icon-file "${icon}" \
|
||||
--exclude-library libpcsclite.so.1 \
|
||||
--output appimage
|
||||
}
|
||||
|
||||
move_artifacts() {
|
||||
local output_name="$1"
|
||||
|
||||
local generated_appimage
|
||||
generated_appimage="$(ls -t *.AppImage 2>/dev/null | head -n 1)"
|
||||
if [ -z "${generated_appimage}" ]; then
|
||||
echo "Error: AppImage generation failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p /workspace/target/release
|
||||
mv "${generated_appimage}" "/workspace/target/release/${output_name}"
|
||||
|
||||
local generated_zsync
|
||||
generated_zsync="$(ls -t *.zsync 2>/dev/null | head -n 1)"
|
||||
if [ -n "${generated_zsync}" ]; then
|
||||
mv "${generated_zsync}" "/workspace/target/release/${output_name}.zsync"
|
||||
sed -i "s|^URL:.*|URL: ${output_name}|" "/workspace/target/release/${output_name}.zsync"
|
||||
sed -i "s|^Filename:.*|Filename: ${output_name}|" "/workspace/target/release/${output_name}.zsync"
|
||||
echo "Moved and patched zsync to ${output_name}.zsync"
|
||||
fi
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
rm -rf AppDir
|
||||
}
|
||||
|
||||
print_summary() {
|
||||
local output_name="$1"
|
||||
echo "=== Build Complete! Output: /workspace/target/release/${output_name} ==="
|
||||
ls -lh "/workspace/target/release/${output_name}"
|
||||
}
|
||||
|
||||
# ──────────────────────────────────────────────
|
||||
# Main
|
||||
# ──────────────────────────────────────────────
|
||||
main() {
|
||||
local variant="${1:-glibc-x86_64}"
|
||||
echo "=== Building PicoForge AppImage for variant: ${variant} ==="
|
||||
|
||||
local src_dir
|
||||
src_dir="$(detect_src_dir)"
|
||||
cd "${src_dir}"
|
||||
|
||||
local version
|
||||
version="$(get_version)"
|
||||
echo "PicoForge Version: ${version}"
|
||||
|
||||
local arch_name
|
||||
arch_name="$(get_arch_name)"
|
||||
|
||||
local output_name
|
||||
output_name="$(compute_output_name "${version}" "${variant}" "${arch_name}")"
|
||||
|
||||
local zsync_glob="${output_name/${version}/*}.zsync"
|
||||
setup_update_info "${zsync_glob}"
|
||||
build_release
|
||||
|
||||
local binary="target/release/picoforge"
|
||||
local desktop="data/in.suyogtandel.picoforge.desktop"
|
||||
local icon="static/appIcons/in.suyogtandel.picoforge.svg"
|
||||
|
||||
verify_assets "${binary}" "${desktop}" "${icon}"
|
||||
package_appimage "${output_name}" "${binary}" "${desktop}" "${icon}"
|
||||
move_artifacts "${output_name}"
|
||||
cleanup
|
||||
print_summary "${output_name}"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
Reference in New Issue
Block a user