name: Build Multi-Platform on: push: branches: - main tags: - 'v*' pull_request: branches: - main workflow_dispatch: env: GO_VERSION: '1.25.4' NODE_VERSION: '20' jobs: build-windows: name: Build Windows runs-on: windows-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Get version from tag id: version shell: bash run: | if [[ "${{ github.ref }}" == refs/tags/* ]]; then VERSION=${GITHUB_REF#refs/tags/} else VERSION="dev" fi echo "version=$VERSION" >> $GITHUB_OUTPUT - name: Setup Go uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} - name: Install pnpm uses: pnpm/action-setup@v4 with: version: 9 - name: Get pnpm store directory shell: bash run: | echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - name: Setup pnpm cache uses: actions/cache@v4 with: path: ${{ env.STORE_PATH }} key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm-store- - name: Install Wails CLI run: go install github.com/wailsapp/wails/v2/cmd/wails@latest - name: Install frontend dependencies working-directory: frontend run: | pnpm install pnpm run generate-icon - name: Build application run: wails build -platform windows/amd64 - name: Prepare artifacts run: | mkdir -p dist Copy-Item -Path "build\bin\SpotiFLAC.exe" -Destination "dist\SpotiFLAC-${{ steps.version.outputs.version }}.exe" - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: windows-portable path: dist/SpotiFLAC-${{ steps.version.outputs.version }}.exe retention-days: 7 build-macos: name: Build macOS runs-on: macos-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Get version from tag id: version run: | if [[ "${{ github.ref }}" == refs/tags/* ]]; then VERSION=${GITHUB_REF#refs/tags/} else VERSION="dev" fi echo "version=$VERSION" >> $GITHUB_OUTPUT - name: Setup Go uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} - name: Install pnpm uses: pnpm/action-setup@v4 with: version: 9 - name: Get pnpm store directory run: | echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - name: Setup pnpm cache uses: actions/cache@v4 with: path: ${{ env.STORE_PATH }} key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm-store- - name: Install Wails CLI run: go install github.com/wailsapp/wails/v2/cmd/wails@latest - name: Install frontend dependencies working-directory: frontend run: | pnpm install pnpm run generate-icon - name: Build application run: wails build -platform darwin/universal - name: Create DMG run: | mkdir -p dist # Install create-dmg if not available brew install create-dmg || true # Create DMG create-dmg \ --volname "SpotiFLAC" \ --window-pos 200 120 \ --window-size 600 400 \ --icon-size 100 \ --icon "SpotiFLAC.app" 175 120 \ --hide-extension "SpotiFLAC.app" \ --app-drop-link 425 120 \ "dist/SpotiFLAC-${{ steps.version.outputs.version }}.dmg" \ "build/bin/SpotiFLAC.app" || \ # Fallback to hdiutil if create-dmg fails hdiutil create -volname SpotiFLAC -srcfolder build/bin/SpotiFLAC.app -ov -format UDZO dist/SpotiFLAC-${{ steps.version.outputs.version }}.dmg - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: macos-portable path: dist/SpotiFLAC-${{ steps.version.outputs.version }}.dmg retention-days: 7 build-linux: name: Build Linux runs-on: ubuntu-24.04 steps: - name: Checkout code uses: actions/checkout@v4 - name: Get version from tag id: version run: | if [[ "${{ github.ref }}" == refs/tags/* ]]; then VERSION=${GITHUB_REF#refs/tags/} else VERSION="dev" fi echo "version=$VERSION" >> $GITHUB_OUTPUT - name: Setup Go uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} - name: Install pnpm uses: pnpm/action-setup@v4 with: version: 9 - name: Get pnpm store directory run: | echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - name: Setup pnpm cache uses: actions/cache@v4 with: path: ${{ env.STORE_PATH }} key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm-store- - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev libfuse2 imagemagick # Create symlink for webkit2gtk-4.0 -> webkit2gtk-4.1 (Ubuntu 24.04 compatibility) sudo ln -sf /usr/lib/x86_64-linux-gnu/pkgconfig/webkit2gtk-4.1.pc /usr/lib/x86_64-linux-gnu/pkgconfig/webkit2gtk-4.0.pc - name: Install Wails CLI run: go install github.com/wailsapp/wails/v2/cmd/wails@latest - name: Install frontend dependencies working-directory: frontend run: | pnpm install pnpm run generate-icon - name: Build application run: wails build -platform linux/amd64 - name: Download linuxdeploy and appimagetool run: | wget -O linuxdeploy https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage chmod +x linuxdeploy - name: Create AppImage run: | mkdir -p AppDir # Create desktop file cat > spotiflac.desktop << 'EOF' [Desktop Entry] Name=SpotiFLAC Exec=spotiflac Icon=spotiflac Type=Application Categories=Audio;AudioVideo; Comment=Get Spotify tracks in true FLAC from Tidal/Deezer EOF # Create icon in multiple sizes for better compatibility if [ -f "build/appicon.png" ]; then cp build/appicon.png spotiflac-256.png elif [ -f "frontend/public/icon.svg" ]; then convert -background none -size 256x256 frontend/public/icon.svg spotiflac-256.png else echo "Warning: No icon found, building without icon" touch spotiflac-256.png # Create empty file to prevent errors fi # Create additional icon sizes only if icon exists if [ -s spotiflac-256.png ]; then convert spotiflac-256.png -resize 128x128 spotiflac-128.png convert spotiflac-256.png -resize 64x64 spotiflac-64.png convert spotiflac-256.png -resize 48x48 spotiflac-48.png convert spotiflac-256.png -resize 32x32 spotiflac-32.png convert spotiflac-256.png -resize 16x16 spotiflac-16.png fi # Use linuxdeploy to create AppImage # Bundle only uncommon libraries (webkit2gtk), exclude common ones (GTK, glib) mkdir -p dist ./linuxdeploy \ --appdir AppDir \ --executable build/bin/SpotiFLAC \ --desktop-file spotiflac.desktop \ --icon-file spotiflac-256.png \ --icon-file spotiflac-128.png \ --icon-file spotiflac-64.png \ --icon-file spotiflac-48.png \ --icon-file spotiflac-32.png \ --icon-file spotiflac-16.png \ --exclude-library "libgtk-3.so*" \ --exclude-library "libgdk-3.so*" \ --exclude-library "libglib-2.0.so*" \ --exclude-library "libgobject-2.0.so*" \ --exclude-library "libgio-2.0.so*" \ --exclude-library "libpango-1.0.so*" \ --exclude-library "libcairo.so*" \ --exclude-library "libX11.so*" \ --exclude-library "libXext.so*" \ --exclude-library "libXrender.so*" \ --exclude-library "libfontconfig.so*" \ --exclude-library "libfreetype.so*" \ --exclude-library "libpthread.so*" \ --exclude-library "libdl.so*" \ --exclude-library "libm.so*" \ --exclude-library "libc.so*" \ --output appimage # Rename to match version mv SpotiFLAC*.AppImage dist/SpotiFLAC-${{ steps.version.outputs.version }}.AppImage - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: linux-portable path: dist/SpotiFLAC-${{ steps.version.outputs.version }}.AppImage retention-days: 7 create-release: name: Create Release needs: [build-windows, build-macos, build-linux] runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/v') permissions: contents: write steps: - name: Checkout code uses: actions/checkout@v4 - name: Get version from tag id: version run: | VERSION=${GITHUB_REF#refs/tags/} echo "version=$VERSION" >> $GITHUB_OUTPUT - name: Download all artifacts uses: actions/download-artifact@v4 with: path: artifacts - name: Display structure of downloaded files run: ls -R artifacts - name: Create Release uses: softprops/action-gh-release@v2 with: draft: true prerelease: false generate_release_notes: false body: | ## Changelog ## Downloads - `SpotiFLAC-${{ steps.version.outputs.version }}.exe` - Windows - `SpotiFLAC-${{ steps.version.outputs.version }}.dmg` - macOS - `SpotiFLAC-${{ steps.version.outputs.version }}.AppImage` - Linux files: | artifacts/windows-portable/*.exe artifacts/macos-portable/*.dmg artifacts/linux-portable/*.AppImage env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}