diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2b81788..c8f854a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -50,7 +50,7 @@ jobs: - name: Package installers run: | sudo apt-get update >/dev/null 2>&1 - sudo apt-get install -y zip dpkg-dev xxd rpm >/dev/null 2>&1 || true + sudo apt-get install -y zip dpkg-dev xxd rpm zstd imagemagick >/dev/null 2>&1 || true VER=${{ github.ref_type == 'tag' && github.ref_name || (github.event.inputs.version != '' && github.event.inputs.version || 'dev') }} VER=${VER#v} @@ -109,6 +109,57 @@ jobs: rpmbuild -bb --define "_topdir $PWD/rpms" --define "_sourcedir $PWD/rpms/SOURCES" rpms/SPECS/pmm.spec find rpms -name '*.rpm' -exec mv {} out/ \; rm -rf rpms + + # -- Alpine .apk (gzip'd tar: .PKGINFO + usr/bin/pmm) + rm -rf apk && mkdir -p apk/usr/bin + cp out/pmm apk/usr/bin/pmm + { + echo "pkgname = pmm" + echo "pkgver = $VER" + echo "pkgdesc = ParlzPackageManager (PMM) - cross-platform C package manager" + echo "url = https://pmm.parlz.com" + echo "arch = x86_64" + echo "license = GPL-3.0" + echo "size = $(stat -c%s out/pmm)" + } > apk/.PKGINFO + ( cd apk && tar -czf "../out/pmm-${VER}.apk" .PKGINFO usr ) + rm -rf apk + + # -- Arch .pkg.tar.zst (tar zstd: .PKGINFO + usr/bin/pmm) + rm -rf pk && mkdir -p pk/usr/bin + cp out/pmm pk/usr/bin/pmm + { + echo "pkgname = pmm" + echo "pkgver = $VER-1" + echo "pkgdesc = ParlzPackageManager (PMM)" + echo "url = https://pmm.parlz.com" + echo "arch = x86_64" + echo "license = GPL-3.0" + } > pk/.PKGINFO + ( cd pk && tar --use-compress-program=zstd -cf "../out/pmm-${VER}-1-x86_64.pkg.tar.zst" .PKGINFO usr ) + rm -rf pk + + # -- AppImage (single-file): AppDir + appimagetool + rm -rf AppDir && mkdir -p AppDir/usr/bin AppDir/usr/share/applications AppDir/usr/share/icons/hicolor/256x256/apps + cp out/pmm AppDir/usr/bin/pmm + printf '#!/bin/sh\nSELF=$(readlink -f "$0"); APPDIR=$(dirname "$SELF")\nexec "$APPDIR/usr/bin/pmm" "$@"\n' > AppDir/AppRun + chmod +x AppDir/AppRun + printf '[Desktop Entry]\nName=PMM\nExec=pmm\nType=Application\nIcon=pmm\nCategories=Development;\n' > AppDir/usr/share/applications/pmm.desktop + if command -v convert >/dev/null 2>&1; then + convert -size 256x256 xc:"#111111" -fill white -pointsize 90 -gravity center -annotate 0 "pmm" \ + AppDir/usr/share/icons/hicolor/256x256/apps/pmm.png 2>/dev/null || true + fi + if [ ! -s AppDir/usr/share/icons/hicolor/256x256/apps/pmm.png ]; then + printf 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+M8AAAMBAQDJ/aLvAAAAAElFTkSuQmCC' | base64 -d > AppDir/usr/share/icons/hicolor/256x256/apps/pmm.png 2>/dev/null || true + fi + if [ ! -x /tmp/appimagetool ]; then + curl -fsSL -o /tmp/appimagetool https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage 2>/dev/null || true + chmod +x /tmp/appimagetool 2>/dev/null || true + fi + if [ -x /tmp/appimagetool ]; then + ( cd AppDir && /tmp/appimagetool --appimage-extract-and-run -n . "../out/pmm-${VER}-x86_64.AppImage" 2>/dev/null ) || true + fi + rm -rf AppDir fi - name: Upload artifact diff --git a/src/install.c b/src/install.c index 7772c14..62d109b 100644 --- a/src/install.c +++ b/src/install.c @@ -240,6 +240,16 @@ static int install_path(const char *path, const char *name) { snprintf(cmd, sizeof(cmd), "sudo dpkg -i \"%s\"", path); } else if (has_suffix(bname, ".rpm") && os == OS_LINUX) { snprintf(cmd, sizeof(cmd), "sudo rpm -Uvh \"%s\"", path); + } else if (has_suffix(bname, ".apk") && os == OS_LINUX) { + /* Alpine: apk add if available, else extract */ + snprintf(cmd, sizeof(cmd), + "if command -v apk >/dev/null 2>&1; then sudo apk add --allow-untrusted \"%s\"; " + "else tar -xf \"%s\" -C \"%s\"; fi", path, path, dest); + } else if (has_suffix(bname, ".pkg.tar.zst") && os == OS_LINUX) { + /* Arch: pacman -U if available, else extract */ + snprintf(cmd, sizeof(cmd), + "if command -v pacman >/dev/null 2>&1; then sudo pacman -U --noconfirm \"%s\"; " + "else tar --zstd -xf \"%s\" -C \"%s\"; fi", path, path, dest); } else if (has_suffix(bname, ".appimage") && os == OS_LINUX) { snprintf(cmd, sizeof(cmd), "chmod +x \"%s\" && mv -f \"%s\" \"%s/\"", path, path, dest); } else if ((has_suffix(bname, ".tar.gz") || has_suffix(bname, ".tgz") || diff --git a/src/repo.c b/src/repo.c index 864d750..dacbc47 100644 --- a/src/repo.c +++ b/src/repo.c @@ -215,7 +215,7 @@ static int name_hints_other_os(const char *name, PmmOS os) { int asset_matches_os(const char *filename, PmmOS os) { static const char *win_exts[] = { ".exe", ".msi", ".zip", ".7z", NULL }; - static const char *linux_exts[] = { ".deb", ".rpm", ".appimage", ".tar.gz", ".tgz", ".tar.xz", ".tar.bz2", ".pkg.tar.zst", NULL }; + static const char *linux_exts[] = { ".deb", ".rpm", ".apk", ".appimage", ".tar.gz", ".tgz", ".tar.xz", ".tar.bz2", ".pkg.tar.zst", NULL }; static const char *mac_exts[] = { ".dmg", ".pkg", ".app.zip", ".tar.gz", ".tgz", NULL }; const char **exts = NULL; switch (os) {