From 5d156672e841a7f5bf61c5e422bc75bcf58bb9a6 Mon Sep 17 00:00:00 2001 From: qurious-pixel <62252937+qurious-pixel@users.noreply.github.com> Date: Fri, 4 Nov 2022 14:07:17 +0000 Subject: [PATCH] CI: Add AppImage Build (#452) --- .github/workflows/build.yml | 48 ++++++++++++----- .github/workflows/build_check.yml | 2 +- .../workflows/deploy_experimental_release.yml | 16 +++++- .github/workflows/deploy_stable_release.yml | 20 ++++--- dist/linux/appimage.sh | 50 ++++++++++++++++++ dist/linux/info.cemu.Cemu.png | Bin 0 -> 11984 bytes 6 files changed, 115 insertions(+), 21 deletions(-) create mode 100755 dist/linux/appimage.sh create mode 100644 dist/linux/info.cemu.Cemu.png diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 279fcea6..f5b1fe3b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,34 +22,36 @@ jobs: uses: actions/checkout@v3 with: submodules: "recursive" - + - name: Setup release mode parameters (for deploy) if: ${{ inputs.deploymode == 'release' }} run: | echo "BUILD_MODE=release" >> $GITHUB_ENV echo "BUILD_FLAGS=" >> $GITHUB_ENV echo "Build mode is release" + - name: Setup debug mode parameters (for continous build) if: ${{ inputs.deploymode != 'release' }} run: | echo "BUILD_MODE=debug" >> $GITHUB_ENV echo "BUILD_FLAGS=" >> $GITHUB_ENV echo "Build mode is debug" - + - name: Setup version for experimental if: ${{ inputs.experimentalversion != '' }} run: | echo "[INFO] Experimental version ${{ inputs.experimentalversion }}" echo "BUILD_FLAGS=${{ env.BUILD_FLAGS }} -DEXPERIMENTAL_VERSION=${{ inputs.experimentalversion }}" >> $GITHUB_ENV - + - name: "Install system dependencies" run: | sudo apt update -qq sudo apt install -y clang-12 cmake freeglut3-dev libgcrypt20-dev libgtk-3-dev libpulse-dev libsecret-1-dev libsystemd-dev nasm ninja-build + - name: "Bootstrap vcpkg" run: | bash ./dependencies/vcpkg/bootstrap-vcpkg.sh - + - name: 'Setup NuGet Credentials for vcpkg' shell: 'bash' run: | @@ -66,15 +68,12 @@ jobs: - name: "cmake" run: | - mkdir -p build - cd build - cmake .. ${{ env.BUILD_FLAGS }} -DCMAKE_BUILD_TYPE=${{ env.BUILD_MODE }} -DCMAKE_C_COMPILER=/usr/bin/clang-12 -DCMAKE_CXX_COMPILER=/usr/bin/clang++-12 -G Ninja -DCMAKE_MAKE_PROGRAM=/usr/bin/ninja + cmake -S . -B build ${{ env.BUILD_FLAGS }} -DCMAKE_BUILD_TYPE=${{ env.BUILD_MODE }} -DPORTABLE=OFF -DCMAKE_C_COMPILER=/usr/bin/clang-12 -DCMAKE_CXX_COMPILER=/usr/bin/clang++-12 -G Ninja -DCMAKE_MAKE_PROGRAM=/usr/bin/ninja - name: "Build Cemu" run: | - cd build - ninja - + cmake --build build + - name: Prepare artifact if: ${{ inputs.deploymode == 'release' }} run: mv bin/Cemu_release bin/Cemu @@ -85,8 +84,33 @@ jobs: with: name: cemu-bin-linux-x64 path: ./bin/Cemu - - + + build-appimage: + runs-on: ubuntu-20.04 + needs: build-ubuntu + steps: + - name: Checkout Upstream Repo + uses: actions/checkout@v3 + + - uses: actions/download-artifact@v3 + with: + name: cemu-bin-linux-x64 + path: bin + + - name: "Install system dependencies" + run: | + sudo apt update -qq + sudo apt install -y clang-12 cmake freeglut3-dev libgcrypt20-dev libgtk-3-dev libpulse-dev libsecret-1-dev libsystemd-dev nasm ninja-build + + - name: "Build AppImage" + run: dist/linux/appimage.sh + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: cemu-appimage-x64 + path: artifacts + build-windows: runs-on: windows-2022 steps: diff --git a/.github/workflows/build_check.yml b/.github/workflows/build_check.yml index 49ef79e9..7208db91 100644 --- a/.github/workflows/build_check.yml +++ b/.github/workflows/build_check.yml @@ -11,7 +11,7 @@ on: paths-ignore: - "*.md" branches: - - main + #- main jobs: build: diff --git a/.github/workflows/deploy_experimental_release.yml b/.github/workflows/deploy_experimental_release.yml index 8a5ee0e9..9296c1cc 100644 --- a/.github/workflows/deploy_experimental_release.yml +++ b/.github/workflows/deploy_experimental_release.yml @@ -13,13 +13,18 @@ jobs: runs-on: ubuntu-20.04 needs: call-release-build steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: actions/download-artifact@v3 with: name: cemu-bin-linux-x64 path: cemu-bin-linux-x64 + - uses: actions/download-artifact@v3 + with: + name: cemu-appimage-x64 + path: cemu-appimage-x64 + - uses: actions/download-artifact@v3 with: name: cemu-bin-windows-x64 @@ -53,7 +58,14 @@ jobs: mv cemu-bin-windows-x64/Cemu.exe ./${{ env.CEMU_FOLDER_NAME }}/Cemu.exe zip -9 -r upload/cemu-${{ env.CEMU_VERSION }}-windows-x64.zip ${{ env.CEMU_FOLDER_NAME }} rm -r ./${{ env.CEMU_FOLDER_NAME }} - + + - name: Create appimage + run: | + VERSION=${{ env.CEMU_VERSION }} + echo "Cemu Version is $VERSION" + ls cemu-appimage-x64 + mv cemu-appimage-x64/Cemu-*-x86_64.AppImage upload/Cemu-$VERSION-x86_64.AppImage + - name: Create release from linux-bin run: | ls ./ diff --git a/.github/workflows/deploy_stable_release.yml b/.github/workflows/deploy_stable_release.yml index 9e880218..5be31413 100644 --- a/.github/workflows/deploy_stable_release.yml +++ b/.github/workflows/deploy_stable_release.yml @@ -15,13 +15,18 @@ jobs: runs-on: ubuntu-20.04 needs: call-release-build steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: actions/download-artifact@v3 with: name: cemu-bin-linux-x64 path: cemu-bin-linux-x64 + - uses: actions/download-artifact@v3 + with: + name: cemu-appimage-x64 + path: cemu-appimage-x64 + - uses: actions/download-artifact@v3 with: name: cemu-bin-windows-x64 @@ -44,11 +49,7 @@ jobs: echo "Cemu CI version: $(./getversion)" echo "CEMU_FOLDER_NAME=Cemu_$(./getversion)" >> $GITHUB_ENV echo "CEMU_VERSION=$(./getversion)" >> $GITHUB_ENV - - - name: Create appimage - run: | - echo "to do" - + - name: Create release from windows-bin run: | ls ./ @@ -57,6 +58,13 @@ jobs: mv cemu-bin-windows-x64/Cemu.exe ./${{ env.CEMU_FOLDER_NAME }}/Cemu.exe zip -9 -r upload/cemu-${{ env.CEMU_VERSION }}-windows-x64.zip ${{ env.CEMU_FOLDER_NAME }} rm -r ./${{ env.CEMU_FOLDER_NAME }} + + - name: Create appimage + run: | + VERSION=${{ env.CEMU_VERSION }} + echo "Cemu Version is $VERSION" + ls cemu-appimage-x64 + mv cemu-appimage-x64/Cemu-*-x86_64.AppImage upload/Cemu-$VERSION-x86_64.AppImage - name: Create release from ubuntu-bin run: | diff --git a/dist/linux/appimage.sh b/dist/linux/appimage.sh new file mode 100755 index 00000000..7112c02a --- /dev/null +++ b/dist/linux/appimage.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +if [ -z "${GITHUB_WORKSPACE}" ]; then + export GITHUB_WORKSPACE="." +fi + +curl -sSfLO "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage" +chmod a+x linuxdeploy*.AppImage +curl -sSfL https://github.com$(curl https://github.com/probonopd/go-appimage/releases/expanded_assets/continuous | grep "mkappimage-.*-x86_64.AppImage" | head -n 1 | cut -d '"' -f 2) -o mkappimage.AppImage +chmod a+x mkappimage.AppImage +curl -sSfLO "https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gtk/master/linuxdeploy-plugin-gtk.sh" +chmod a+x linuxdeploy-plugin-gtk.sh + +if [[ ! -e /usr/lib/x86_64-linux-gnu ]]; then + sed -i 's#lib\/x86_64-linux-gnu#lib64#g' linuxdeploy-plugin-gtk.sh +fi + +mkdir -p AppDir/usr/ +cp dist/linux/{info.cemu.Cemu.desktop,info.cemu.Cemu.png} AppDir/ + +mkdir -p AppDir/usr/share/applications +mkdir -p AppDir/usr/share/icons/hicolor/scalable/apps +mkdir -p AppDir/usr/lib + +cp -r bin AppDir/usr/ +cp /usr/lib/x86_64-linux-gnu/{libsepol.so.1,libffi.so.7,libpcre.so.3,libGLU.so.1} AppDir/usr/lib + +chmod +x AppDir/usr/bin/Cemu +#chmod +x AppDir/AppRun + +export UPD_INFO="gh-releases-zsync|cemu-project|Cemu|ci|Cemu.AppImage.zsync" +./linuxdeploy-x86_64.AppImage --appimage-extract-and-run\ + --appdir="$GITHUB_WORKSPACE"/AppDir/ \ + -d "$GITHUB_WORKSPACE"/AppDir/info.cemu.Cemu.desktop \ + -i "$GITHUB_WORKSPACE"/AppDir/info.cemu.Cemu.png \ + -e "$GITHUB_WORKSPACE"/AppDir/usr/bin/Cemu \ + --plugin gtk + +GITVERSION=$(git rev-parse --short HEAD) +echo $GITVERSION +if [[ -z ${GITVERSION} ]]; then + GITVERSION=experimental +fi + +echo "Cemu Version Cemu-${GITVERSION}" +rm AppDir/usr/lib/libwayland-client.so.0 +VERSION=${GITVERSION} ./mkappimage.AppImage --appimage-extract-and-run "$GITHUB_WORKSPACE"/AppDir + +mkdir -p "$GITHUB_WORKSPACE"/artifacts/ +mv Cemu-${GITVERSION}-x86_64.AppImage "$GITHUB_WORKSPACE"/artifacts/ diff --git a/dist/linux/info.cemu.Cemu.png b/dist/linux/info.cemu.Cemu.png new file mode 100644 index 0000000000000000000000000000000000000000..6f65507248160cd5f649d43be8295e90b5aa1622 GIT binary patch literal 11984 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