name: Release on: push: tags: - 'v*' permissions: contents: write jobs: # Phase 1: Build in parallel and output artifacts build: name: Build ${{ matrix.platform }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: include: - os: macos-latest platform: darwin/amd64 artifact_name: GoNavi-mac-amd64 asset_ext: .dmg - os: macos-latest platform: darwin/arm64 artifact_name: GoNavi-mac-arm64 asset_ext: .dmg - os: windows-latest platform: windows/amd64 artifact_name: GoNavi-windows-amd64 asset_ext: .exe - os: windows-latest platform: windows/arm64 artifact_name: GoNavi-windows-arm64 asset_ext: .exe - os: ubuntu-22.04 platform: linux/amd64 artifact_name: GoNavi-linux-amd64 steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Go uses: actions/setup-go@v5 with: go-version: '1.24' check-latest: true - name: Setup Node uses: actions/setup-node@v4 with: node-version: '20' # Linux Dependencies (GTK3, WebKit2GTK required by Wails) - name: Install Linux Dependencies if: contains(matrix.platform, 'linux') run: | sudo apt-get update sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libfuse2 # Download linuxdeploy tools for AppImage packaging LINUXDEPLOY_URL="https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage" PLUGIN_URL="https://github.com/linuxdeploy/linuxdeploy-plugin-gtk/releases/download/continuous/linuxdeploy-plugin-gtk-x86_64.AppImage" echo "📥 下载 linuxdeploy..." wget --retry-connrefused --waitretry=1 --read-timeout=20 --timeout=15 --tries=3 \ -O /tmp/linuxdeploy "$LINUXDEPLOY_URL" || { echo "⚠️ linuxdeploy 下载失败,AppImage 打包将跳过" touch /tmp/skip-appimage } echo "📥 下载 linuxdeploy-plugin-gtk..." wget --retry-connrefused --waitretry=1 --read-timeout=20 --timeout=15 --tries=3 \ -O /tmp/linuxdeploy-plugin-gtk "$PLUGIN_URL" || { echo "⚠️ linuxdeploy-plugin-gtk 下载失败,AppImage 打包将跳过" touch /tmp/skip-appimage } if [ ! -f /tmp/skip-appimage ]; then chmod +x /tmp/linuxdeploy /tmp/linuxdeploy-plugin-gtk echo "✅ AppImage 工具准备完成" fi - name: Install Wails run: go install -v github.com/wailsapp/wails/v2/cmd/wails@latest - name: Build shell: bash run: | wails build -platform ${{ matrix.platform }} -clean -o ${{ matrix.artifact_name }} -ldflags "-X GoNavi-Wails/internal/app.AppVersion=${{ github.ref_name }}" # macOS Packaging - name: Package macOS DMG if: contains(matrix.platform, 'darwin') run: | brew install create-dmg cd build/bin APP_PATH=$(find . -maxdepth 1 -name "*.app" | head -n 1) if [ -z "$APP_PATH" ]; then echo "❌ 未找到 .app 应用包!" exit 1 fi APP_NAME=$(basename "$APP_PATH") echo "🔏 正在进行 Ad-hoc 签名..." codesign --force --options runtime --deep --sign - "$APP_NAME" DMG_NAME="${{ matrix.artifact_name }}.dmg" echo "📦 正在生成 DMG: $DMG_NAME..." create-dmg \ --volname "GoNavi Installer" \ --window-pos 200 120 \ --window-size 800 400 \ --icon-size 100 \ --icon "$APP_NAME" 200 190 \ --hide-extension "$APP_NAME" \ --app-drop-link 600 185 \ "$DMG_NAME" \ "$APP_NAME" mv "$DMG_NAME" ../../ # Windows Packaging - name: Prepare Windows Exe if: contains(matrix.platform, 'windows') shell: bash run: | cd build/bin TARGET="${{ matrix.artifact_name }}" if [ -f "$TARGET.exe" ]; then FINAL_EXE="$TARGET.exe" elif [ -f "$TARGET" ]; then mv "$TARGET" "$TARGET.exe" FINAL_EXE="$TARGET.exe" else echo "❌ 未找到构建产物 '$TARGET'!" exit 1 fi echo "📦 正在移动 $FINAL_EXE 到根目录..." mv "$FINAL_EXE" "../../$FINAL_EXE" # Linux Packaging (tar.gz and AppImage) - name: Package Linux if: contains(matrix.platform, 'linux') run: | cd build/bin TARGET="${{ matrix.artifact_name }}" if [ ! -f "$TARGET" ]; then echo "❌ 未找到构建产物 '$TARGET'!" exit 1 fi chmod +x "$TARGET" # 1. Create tar.gz echo "📦 正在打包 $TARGET.tar.gz..." tar -czvf "$TARGET.tar.gz" "$TARGET" mv "$TARGET.tar.gz" ../../ # 2. Create AppImage (skip for ARM64 or if tools unavailable) if [ -f /tmp/skip-appimage ]; then echo "⚠️ 跳过 AppImage 打包" exit 0 fi echo "📦 正在生成 AppImage..." # Create AppDir structure mkdir -p AppDir/usr/bin mkdir -p AppDir/usr/share/applications mkdir -p AppDir/usr/share/icons/hicolor/256x256/apps cp "$TARGET" AppDir/usr/bin/gonavi # Create desktop file printf '%s\n' \ '[Desktop Entry]' \ 'Name=GoNavi' \ 'Exec=gonavi' \ 'Icon=gonavi' \ 'Type=Application' \ 'Categories=Development;Database;' \ 'Comment=Database Management Tool' \ > AppDir/usr/share/applications/gonavi.desktop cp AppDir/usr/share/applications/gonavi.desktop AppDir/gonavi.desktop # Create a simple icon (or use existing if available) if [ -f "../../build/appicon.png" ]; then cp "../../build/appicon.png" AppDir/usr/share/icons/hicolor/256x256/apps/gonavi.png cp "../../build/appicon.png" AppDir/gonavi.png else # Create a placeholder icon convert -size 256x256 xc:#336791 -fill white -gravity center -pointsize 48 -annotate 0 "GoNavi" AppDir/gonavi.png || \ wget -q "https://via.placeholder.com/256/336791/FFFFFF?text=GoNavi" -O AppDir/gonavi.png || \ touch AppDir/gonavi.png cp AppDir/gonavi.png AppDir/usr/share/icons/hicolor/256x256/apps/gonavi.png fi # Build AppImage export DEPLOY_GTK_VERSION=3 /tmp/linuxdeploy --appdir AppDir --plugin gtk --output appimage || { echo "⚠️ AppImage 生成失败,但 tar.gz 已成功生成" exit 0 } # Rename output mv GoNavi*.AppImage "$TARGET.AppImage" 2>/dev/null || { echo "⚠️ AppImage 重命名失败" exit 0 } if [ -f "$TARGET.AppImage" ]; then mv "$TARGET.AppImage" ../../ echo "✅ AppImage 生成成功" fi # Upload to Actions Artifacts (Temporary Storage) - name: Upload Artifact uses: actions/upload-artifact@v4 with: name: build-artifacts-${{ strategy.job-index }} # Unique name per job path: | GoNavi-*.dmg GoNavi-*.exe GoNavi-*.tar.gz GoNavi-*.AppImage retention-days: 1 # Phase 2: Collect all artifacts and Publish Release (Single Job) release: name: Publish Release needs: build runs-on: ubuntu-latest steps: - name: Download All Artifacts uses: actions/download-artifact@v4 with: path: release-assets pattern: build-artifacts-* merge-multiple: true - name: List Assets run: ls -R release-assets - name: Generate SHA256SUMS run: | cd release-assets sha256sum * > SHA256SUMS - name: Create Release uses: softprops/action-gh-release@v2 if: startsWith(github.ref, 'refs/tags/') with: files: release-assets/* draft: true make_latest: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}