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 asset_ext: .tar.gz - os: ubuntu-22.04 platform: linux/arm64 artifact_name: GoNavi-linux-arm64 asset_ext: .tar.gz - os: ubuntu-22.04 platform: linux/amd64 artifact_name: GoNavi-linux-amd64 asset_ext: .AppImage build_appimage: true - os: ubuntu-22.04 platform: linux/arm64 artifact_name: GoNavi-linux-arm64 asset_ext: .AppImage build_appimage: true 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 # Cross-compile dependencies for ARM64 if [ "${{ matrix.platform }}" = "linux/arm64" ]; then sudo dpkg --add-architecture arm64 sudo apt-get update sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu sudo apt-get install -y libgtk-3-dev:arm64 libwebkit2gtk-4.0-dev:arm64 || true fi # AppImage tools if [ "${{ matrix.build_appimage }}" = "true" ]; then sudo apt-get install -y libfuse2 if [ "${{ matrix.platform }}" = "linux/arm64" ]; then wget -q https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-aarch64.AppImage -O /tmp/linuxdeploy wget -q https://github.com/linuxdeploy/linuxdeploy-plugin-gtk/releases/download/continuous/linuxdeploy-plugin-gtk-aarch64.AppImage -O /tmp/linuxdeploy-plugin-gtk else wget -q https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage -O /tmp/linuxdeploy wget -q https://github.com/linuxdeploy/linuxdeploy-plugin-gtk/releases/download/continuous/linuxdeploy-plugin-gtk-x86_64.AppImage -O /tmp/linuxdeploy-plugin-gtk fi chmod +x /tmp/linuxdeploy /tmp/linuxdeploy-plugin-gtk fi - name: Install Wails run: go install -v github.com/wailsapp/wails/v2/cmd/wails@latest - name: Build shell: bash run: | # Set cross-compile environment for Linux ARM64 if [ "${{ matrix.platform }}" = "linux/arm64" ]; then export CC=aarch64-linux-gnu-gcc export CXX=aarch64-linux-gnu-g++ export CGO_ENABLED=1 export GOOS=linux export GOARCH=arm64 fi wails build -platform ${{ matrix.platform }} -clean -o ${{ matrix.artifact_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 - name: Package Linux tar.gz if: contains(matrix.platform, 'linux') && matrix.build_appimage != true run: | cd build/bin TARGET="${{ matrix.artifact_name }}" if [ -f "$TARGET" ]; then chmod +x "$TARGET" echo "📦 正在打包 $TARGET.tar.gz..." tar -czvf "$TARGET.tar.gz" "$TARGET" mv "$TARGET.tar.gz" ../../ else echo "❌ 未找到构建产物 '$TARGET'!" exit 1 fi # Linux AppImage Packaging - name: Package Linux AppImage if: matrix.build_appimage == true run: | cd build/bin TARGET="${{ matrix.artifact_name }}" if [ ! -f "$TARGET" ]; then echo "❌ 未找到构建产物 '$TARGET'!" exit 1 fi chmod +x "$TARGET" # 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 cat > AppDir/usr/share/applications/gonavi.desktop << 'EOF' [Desktop Entry] Name=GoNavi Exec=gonavi Icon=gonavi Type=Application Categories=Development;Database; Comment=Database Management Tool EOF 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 echo "📦 正在生成 AppImage..." export DEPLOY_GTK_VERSION=3 /tmp/linuxdeploy --appdir AppDir --plugin gtk --output appimage # Rename output mv GoNavi*.AppImage "$TARGET.AppImage" mv "$TARGET.AppImage" ../../ # 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-*${{ matrix.asset_ext }} 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: 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 }}