name: Build Linux on: workflow_dispatch: inputs: version: description: "Version to build (e.g. 0.9.0)" required: true permissions: contents: write jobs: frontend: name: Build frontend runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 with: { version: latest } - uses: actions/setup-node@v4 with: { node-version: 22, cache: pnpm } - run: pnpm install --frozen-lockfile - run: pnpm build:static - uses: actions/upload-artifact@v4 with: name: frontend-dist-linux path: dist/ retention-days: 1 tauri: name: Tauri (Linux x64) needs: frontend runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 with: { name: frontend-dist-linux, path: dist/ } - name: Read versions run: | source .github/read_versions.sh echo "MOKU_VERSION=$MOKU_VERSION" >> $GITHUB_ENV echo "SUWA_VERSION=$SUWA_VERSION" >> $GITHUB_ENV echo "SUWA_HASH=$SUWA_HASH_LINUX" >> $GITHUB_ENV - name: Install system dependencies run: | sudo apt-get update sudo apt-get install -y \ libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libfuse2 - uses: dtolnay/rust-toolchain@stable with: { targets: x86_64-unknown-linux-gnu } - uses: Swatinem/rust-cache@v2 with: { workspaces: src-tauri } - uses: pnpm/action-setup@v4 with: { version: latest } - uses: actions/setup-node@v4 with: { node-version: 22, cache: pnpm } - run: pnpm install --frozen-lockfile - name: Download Suwayomi (Linux x64) run: | curl -fsSL \ "https://github.com/Suwayomi/Suwayomi-Server-preview/releases/download/v${SUWA_VERSION}/Suwayomi-Server-v${SUWA_VERSION}-linux-x64.tar.gz" \ -o suwayomi-linux.tar.gz echo "${SUWA_HASH} suwayomi-linux.tar.gz" | sha256sum -c - mkdir -p suwayomi-extracted tar -xzf suwayomi-linux.tar.gz -C suwayomi-extracted --strip-components=1 - name: Stage Suwayomi bundle run: | mkdir -p src-tauri/binaries for f in suwayomi-extracted/bin/Suwayomi-Server.jar \ suwayomi-extracted/jre/bin/java \ suwayomi-extracted/bin/catch_abort.so; do [ -e "$f" ] || { echo "ERROR: missing $f"; find suwayomi-extracted -type f | head -40; exit 1; } done cp -r suwayomi-extracted src-tauri/binaries/suwayomi-bundle chmod +x src-tauri/binaries/suwayomi-bundle/jre/bin/java - name: Stage Linux launcher sidecar run: | cp src-tauri/binaries/suwayomi-launcher-linux.sh \ src-tauri/binaries/suwayomi-launcher-linux-x86_64-unknown-linux-gnu chmod +x src-tauri/binaries/suwayomi-launcher-linux-x86_64-unknown-linux-gnu - name: Patch tauri.conf.json for CI run: sed -i 's/"beforeBuildCommand": "pnpm build"/"beforeBuildCommand": ""/' src-tauri/tauri.conf.json - name: Build Tauri app run: pnpm tauri build --target x86_64-unknown-linux-gnu --config src-tauri/tauri.linux.conf.json --verbose env: { NO_STRIP: "true" } - name: Upload Linux artifacts to release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | for i in $(seq 1 12); do RELEASE_ID=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \ "https://api.github.com/repos/moku-project/Moku/releases" \ | jq -r '.[] | select(.tag_name == "v${{ github.event.inputs.version }}") | .id' | head -1) [ -n "$RELEASE_ID" ] && break echo "Waiting for release... attempt $i"; sleep 15 done [ -z "$RELEASE_ID" ] && { echo "ERROR: release not found"; exit 1; } upload() { curl -s -X POST \ -H "Authorization: Bearer $GITHUB_TOKEN" \ -H "Content-Type: application/octet-stream" \ --data-binary @"$1" \ "https://uploads.github.com/repos/moku-project/Moku/releases/$RELEASE_ID/assets?name=$2" } APPIMAGE=$(find src-tauri/target/x86_64-unknown-linux-gnu/release/bundle/appimage -name "*.AppImage" | head -1) DEB=$(find src-tauri/target/x86_64-unknown-linux-gnu/release/bundle/deb -name "*.deb" | head -1) [ -n "$APPIMAGE" ] && upload "$APPIMAGE" "moku-linux-x64-${{ github.event.inputs.version }}.AppImage" [ -n "$DEB" ] && upload "$DEB" "moku-linux-x64-${{ github.event.inputs.version }}.deb"