From 6bbe31044ab364b5171887acf35bfefa117d6a4e Mon Sep 17 00:00:00 2001 From: Omer Faruk Oruc Date: Sat, 7 Mar 2026 14:22:46 +0300 Subject: [PATCH 1/2] ci: publish Fedora RPM releases --- .../cpp_server_build_test_release.yml | 111 ++++++++++++++++++ src/cpp/CPackRPM.cmake | 8 +- src/cpp/postinst-rpm | 25 ++++ src/cpp/postrm-rpm | 8 ++ src/cpp/prerm-rpm | 8 ++ 5 files changed, 158 insertions(+), 2 deletions(-) create mode 100755 src/cpp/postinst-rpm create mode 100755 src/cpp/postrm-rpm create mode 100755 src/cpp/prerm-rpm diff --git a/.github/workflows/cpp_server_build_test_release.yml b/.github/workflows/cpp_server_build_test_release.yml index f3d29716a..2b96324b2 100644 --- a/.github/workflows/cpp_server_build_test_release.yml +++ b/.github/workflows/cpp_server_build_test_release.yml @@ -351,6 +351,64 @@ jobs: path: build/lemonade-server_${{ env.LEMONADE_VERSION }}_amd64.deb retention-days: 7 + build-lemonade-rpm: + name: Build Lemonade .rpm Package + runs-on: ubuntu-latest + container: + image: fedora:latest + outputs: + version: ${{ steps.get_version.outputs.version }} + steps: + - uses: actions/checkout@v4 + with: + clean: true + fetch-depth: 0 + + - name: Install RPM packaging tools + shell: bash + run: | + set -e + dnf install -y rpm-build + + - name: Get version from CMakeLists.txt + id: get_version + uses: ./.github/actions/get-version + + - name: Build Linux .rpm package + shell: bash + run: | + set -e + + echo "Running setup.sh to configure build environment..." + bash setup.sh + + echo "Building lemonade-router and lemonade-server for Fedora..." + cmake --build --preset default + + RPM_FILE="lemonade-server-${LEMONADE_VERSION}.x86_64.rpm" + + cd build + + echo "Creating .rpm package with CPack..." + cpack -G RPM -V + + if [ ! -f "$RPM_FILE" ]; then + echo "ERROR: .rpm package not created!" + echo "Contents of build directory:" + ls -lR . + exit 1 + fi + + echo "Package information:" + rpm -qip "$RPM_FILE" + + - name: Upload .rpm package + uses: actions/upload-artifact@v4 + with: + name: lemonade-rpm + path: build/lemonade-server-${{ env.LEMONADE_VERSION }}.x86_64.rpm + retention-days: 7 + build-lemonade-macos-dmg: name: Build Lemonade macOS .dmg (with Electron App) runs-on: macos-latest @@ -794,6 +852,49 @@ jobs: if: always() uses: ./.github/actions/cleanup-processes-linux + test-rpm-package: + name: Test .rpm - Fedora + runs-on: ubuntu-latest + needs: build-lemonade-rpm + container: + image: fedora:latest + env: + LEMONADE_VERSION: ${{ needs.build-lemonade-rpm.outputs.version }} + steps: + - name: Download Lemonade .rpm Package + uses: actions/download-artifact@v4 + with: + name: lemonade-rpm + path: . + + - name: Install and verify Lemonade (.rpm) + shell: bash + run: | + set -e + + RPM_FILE="lemonade-server-${LEMONADE_VERSION}.x86_64.rpm" + + if [ ! -f "$RPM_FILE" ]; then + echo "ERROR: .rpm file not found: $RPM_FILE" + ls -la *.rpm 2>/dev/null || echo "No .rpm files found in current directory" + exit 1 + fi + + dnf install -y shadow-utils "$RPM_FILE" + + echo "Installed package information:" + rpm -qi lemonade-server + + echo "Installed file list:" + rpm -ql lemonade-server | sort + + test -f /etc/lemonade/lemonade.conf + test -f /opt/bin/lemonade-server + test -f /opt/bin/lemonade-router + + lemonade-server --version + lemonade-router --version + test-dmg-inference: name: Test .dmg - llamacpp (metal) runs-on: macos-latest @@ -1040,9 +1141,11 @@ jobs: needs: - sign-msi-installers - build-lemonade-deb + - build-lemonade-rpm - build-lemonade-macos-dmg - build-lemonade-appimage - test-cli-endpoints + - test-rpm-package if: startsWith(github.ref, 'refs/tags/v') env: LEMONADE_VERSION: ${{ needs.build-lemonade-deb.outputs.version }} @@ -1064,6 +1167,12 @@ jobs: name: lemonade-deb path: . + - name: Download Lemonade .rpm Package + uses: actions/download-artifact@v4 + with: + name: lemonade-rpm + path: . + - name: Download Lemonade macOS .pkg Package uses: actions/download-artifact@v4 with: @@ -1082,6 +1191,7 @@ jobs: ls -lh lemonade-server-minimal.msi ls -lh lemonade.msi ls -lh lemonade-server_${LEMONADE_VERSION}_amd64.deb + ls -lh lemonade-server-${LEMONADE_VERSION}.x86_64.rpm ls -lh *.pkg ls -lh Lemonade-${LEMONADE_VERSION}-x86_64.AppImage @@ -1102,6 +1212,7 @@ jobs: lemonade-server-minimal.msi lemonade.msi lemonade-server_${{ env.LEMONADE_VERSION }}_amd64.deb + lemonade-server-${{ env.LEMONADE_VERSION }}.x86_64.rpm *.pkg Lemonade-${{ env.LEMONADE_VERSION }}-x86_64.AppImage fail_on_unmatched_files: true diff --git a/src/cpp/CPackRPM.cmake b/src/cpp/CPackRPM.cmake index 4e9d71bcb..e76846623 100644 --- a/src/cpp/CPackRPM.cmake +++ b/src/cpp/CPackRPM.cmake @@ -14,8 +14,12 @@ set(CPACK_RPM_PACKAGE_REQUIRES "libcurl, openssl, zlib") # Architecture and file name set(CPACK_RPM_PACKAGE_ARCHITECTURE "x86_64") set(CPACK_PACKAGE_FILE_NAME "lemonade-server-${CPACK_PACKAGE_VERSION}.${CPACK_RPM_PACKAGE_ARCHITECTURE}") +set(CPACK_PACKAGE_RELOCATABLE OFF) +set(CPACK_RPM_PACKAGE_RELOCATABLE OFF) -# Provide script hooks (optional) -set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/postinst") +# Provide RPM-native script hooks +set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/postinst-rpm") +set(CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/prerm-rpm") +set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/postrm-rpm") # End of RPM config. diff --git a/src/cpp/postinst-rpm b/src/cpp/postinst-rpm new file mode 100755 index 000000000..5b706ece2 --- /dev/null +++ b/src/cpp/postinst-rpm @@ -0,0 +1,25 @@ +#!/bin/bash +set -e + +if ! getent group lemonade > /dev/null 2>&1; then + groupadd -r lemonade > /dev/null 2>&1 || true +fi + +if ! getent passwd lemonade > /dev/null 2>&1; then + useradd -m -r -g lemonade -d /opt/var/lib/lemonade -s /usr/sbin/nologin lemonade > /dev/null 2>&1 || true +fi + +mkdir -p /opt/var/lib/lemonade +chown lemonade:lemonade /opt/var/lib/lemonade > /dev/null 2>&1 || true + +usermod -a -G render lemonade > /dev/null 2>&1 || true + +if getent group systemd-journal > /dev/null 2>&1; then + usermod -a -G systemd-journal lemonade > /dev/null 2>&1 || true +fi + +if command -v systemctl > /dev/null 2>&1 && [ -d /run/systemd/system ]; then + systemctl daemon-reload > /dev/null 2>&1 || true +fi + +exit 0 diff --git a/src/cpp/postrm-rpm b/src/cpp/postrm-rpm new file mode 100755 index 000000000..1985b6fe2 --- /dev/null +++ b/src/cpp/postrm-rpm @@ -0,0 +1,8 @@ +#!/bin/bash +set -e + +if command -v systemctl > /dev/null 2>&1 && [ -d /run/systemd/system ]; then + systemctl daemon-reload > /dev/null 2>&1 || true +fi + +exit 0 diff --git a/src/cpp/prerm-rpm b/src/cpp/prerm-rpm new file mode 100755 index 000000000..7a1cc906e --- /dev/null +++ b/src/cpp/prerm-rpm @@ -0,0 +1,8 @@ +#!/bin/bash +set -e + +if command -v systemctl > /dev/null 2>&1 && [ -d /run/systemd/system ]; then + systemctl stop lemonade-server.service > /dev/null 2>&1 || true +fi + +exit 0 From f7d27b6235006549296cb54b720704622b94989b Mon Sep 17 00:00:00 2001 From: Omer Faruk Oruc Date: Sat, 7 Mar 2026 14:34:05 +0300 Subject: [PATCH 2/2] ci: address RPM review feedback --- .github/workflows/cpp_server_build_test_release.yml | 4 ++-- src/cpp/prerm-rpm | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cpp_server_build_test_release.yml b/.github/workflows/cpp_server_build_test_release.yml index 2b96324b2..914e2c61d 100644 --- a/.github/workflows/cpp_server_build_test_release.yml +++ b/.github/workflows/cpp_server_build_test_release.yml @@ -892,8 +892,8 @@ jobs: test -f /opt/bin/lemonade-server test -f /opt/bin/lemonade-router - lemonade-server --version - lemonade-router --version + /opt/bin/lemonade-server --version + /opt/bin/lemonade-router --version test-dmg-inference: name: Test .dmg - llamacpp (metal) diff --git a/src/cpp/prerm-rpm b/src/cpp/prerm-rpm index 7a1cc906e..20fdfb298 100755 --- a/src/cpp/prerm-rpm +++ b/src/cpp/prerm-rpm @@ -1,7 +1,7 @@ #!/bin/bash set -e -if command -v systemctl > /dev/null 2>&1 && [ -d /run/systemd/system ]; then +if [ "${1:-0}" -eq 0 ] && command -v systemctl > /dev/null 2>&1 && [ -d /run/systemd/system ]; then systemctl stop lemonade-server.service > /dev/null 2>&1 || true fi