v6.2.0 #42
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build | |
| on: | |
| push: | |
| branches: | |
| - master | |
| pull_request: | |
| branches: | |
| - master | |
| release: | |
| types: [created] | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| jobs: | |
| build-windows: | |
| name: Build Windows | |
| runs-on: windows-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Setup Qt | |
| uses: jurplel/install-qt-action@v4 | |
| with: | |
| version: "6.10.1" | |
| cache: true | |
| - name: Configure CMake | |
| run: | | |
| cmake -B build -S . -DCMAKE_BUILD_TYPE=Release | |
| - name: Build | |
| run: | | |
| cmake --build build --config Release | |
| - name: Deploy Qt dependencies | |
| shell: pwsh | |
| run: | | |
| $env:PATH = "$env:Qt6_DIR\bin;$env:PATH" | |
| # Find the executable | |
| $ExePath = "" | |
| if (Test-Path "build\bin\Release\ApkStudio.exe") { | |
| $ExePath = "build\bin\Release\ApkStudio.exe" | |
| } elseif (Test-Path "build\Release\ApkStudio.exe") { | |
| $ExePath = "build\Release\ApkStudio.exe" | |
| } else { | |
| Write-Host "Error: Executable not found. Searching..." | |
| Get-ChildItem -Path build -Recurse -Filter "ApkStudio.exe" -ErrorAction SilentlyContinue | Select-Object FullName | |
| exit 1 | |
| } | |
| Write-Host "Found executable at: $ExePath" | |
| windeployqt --release $ExePath | |
| - name: Create archive | |
| shell: pwsh | |
| run: | | |
| # Find the directory containing the executable | |
| $SourceDir = "" | |
| if (Test-Path "build\bin\Release") { | |
| $SourceDir = "build\bin\Release" | |
| } elseif (Test-Path "build\Release") { | |
| $SourceDir = "build\Release" | |
| } else { | |
| Write-Host "Error: Release directory not found" | |
| exit 1 | |
| } | |
| Write-Host "Creating archive from: $SourceDir" | |
| Compress-Archive -Path "$SourceDir\*" -DestinationPath ApkStudio-Windows-x64.zip | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ApkStudio-Windows-x64 | |
| path: ApkStudio-Windows-x64.zip | |
| retention-days: 30 | |
| - name: Upload to release | |
| if: github.event_name == 'release' | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| tag_name: ${{ github.event.release.tag_name }} | |
| files: ApkStudio-Windows-x64.zip | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| build-linux: | |
| name: Build Linux | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libgl1-mesa-dev libxkbcommon-x11-0 | |
| - name: Setup Qt | |
| uses: jurplel/install-qt-action@v4 | |
| with: | |
| version: "6.10.1" | |
| cache: true | |
| - name: Configure CMake | |
| run: | | |
| cmake -B build -S . -DCMAKE_BUILD_TYPE=Release | |
| - name: Build | |
| run: | | |
| cmake --build build --config Release -j$(nproc) | |
| - name: Install | |
| run: | | |
| cmake --install build --prefix install | |
| - name: Download linuxdeploy and plugins | |
| run: | | |
| wget -c -nv "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage" | |
| wget -c -nv "https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage" | |
| wget -c -nv "https://github.com/linuxdeploy/linuxdeploy-plugin-appimage/releases/download/continuous/linuxdeploy-plugin-appimage-x86_64.AppImage" | |
| chmod +x linuxdeploy*.AppImage | |
| - name: Find executable | |
| run: | | |
| echo "Searching for executable..." | |
| find . -type f -executable \( -name "ApkStudio" -o -name "apkstudio" \) 2>/dev/null | head -5 | |
| ls -la install/bin/ 2>/dev/null || echo "install/bin/ does not exist" | |
| ls -la build/ 2>/dev/null | head -10 || echo "build/ does not exist" | |
| - name: Prepare AppDir for AppImage | |
| run: | | |
| mkdir -p AppDir/usr/bin | |
| mkdir -p AppDir/usr/lib | |
| # Find the executable (could be ApkStudio or apkstudio, in build or install) | |
| EXECUTABLE="" | |
| if [ -f install/bin/ApkStudio ]; then | |
| EXECUTABLE="install/bin/ApkStudio" | |
| elif [ -f install/bin/apkstudio ]; then | |
| EXECUTABLE="install/bin/apkstudio" | |
| elif [ -f build/ApkStudio ]; then | |
| EXECUTABLE="build/ApkStudio" | |
| elif [ -f build/apkstudio ]; then | |
| EXECUTABLE="build/apkstudio" | |
| else | |
| echo "Error: Executable not found. Listing directories..." | |
| find . -type f -executable -name "*pk*" 2>/dev/null || true | |
| exit 1 | |
| fi | |
| echo "Found executable at: $EXECUTABLE" | |
| cp "$EXECUTABLE" AppDir/usr/bin/apkstudio | |
| mkdir -p AppDir/usr/share/applications | |
| mkdir -p AppDir/usr/share/icons/hicolor/512x512/apps | |
| # Copy and fix desktop file to use correct icon name | |
| cp ${{ github.workspace }}/resources/apkstudio.desktop AppDir/usr/share/applications/ | |
| sed -i 's/^Icon=.*/Icon=apkstudio/' AppDir/usr/share/applications/apkstudio.desktop | |
| # Copy icon to both locations: root for linuxdeploy and hicolor for system | |
| cp ${{ github.workspace }}/resources/icon.png AppDir/apkstudio.png | |
| cp ${{ github.workspace }}/resources/icon.png AppDir/usr/share/icons/hicolor/512x512/apps/apkstudio.png | |
| chmod +x AppDir/usr/bin/apkstudio | |
| - name: Create AppImage with linuxdeploy | |
| run: | | |
| export QTDIR=${{ env.QT_ROOT_DIR }} | |
| ./linuxdeploy-x86_64.AppImage --appdir AppDir --executable AppDir/usr/bin/apkstudio --desktop-file AppDir/usr/share/applications/apkstudio.desktop --icon-file AppDir/apkstudio.png --plugin qt --output appimage | |
| - name: Rename AppImage if tagged | |
| run: | | |
| if [ ! -z "${{ github.ref }}" ] && [[ "${{ github.ref }}" == refs/tags/* ]]; then | |
| TAG_NAME=${GITHUB_REF#refs/tags/} | |
| if [ -f ApkStudio-x86_64.AppImage ]; then | |
| mv ApkStudio-x86_64.AppImage ApkStudio-${TAG_NAME}-x86_64.AppImage | |
| fi | |
| fi | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ApkStudio-Linux-x64 | |
| path: ApkStudio*.AppImage | |
| if-no-files-found: error | |
| retention-days: 30 | |
| - name: Upload to release | |
| if: github.event_name == 'release' | |
| run: | | |
| # Find the AppImage file | |
| APPIMAGE_FILE=$(find . -maxdepth 1 -name "ApkStudio*.AppImage" -type f | head -1) | |
| if [ -z "$APPIMAGE_FILE" ]; then | |
| echo "Error: AppImage file not found" | |
| exit 1 | |
| fi | |
| echo "Found AppImage: $APPIMAGE_FILE" | |
| echo "APPIMAGE_FILE=$APPIMAGE_FILE" >> $GITHUB_ENV | |
| - name: Upload AppImage to release | |
| if: github.event_name == 'release' | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| tag_name: ${{ github.event.release.tag_name }} | |
| files: ${{ env.APPIMAGE_FILE }} | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| build-macos: | |
| name: Build macOS | |
| runs-on: macos-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Setup Qt | |
| uses: jurplel/install-qt-action@v4 | |
| with: | |
| version: "6.10.1" | |
| cache: true | |
| - name: Set Qt directory | |
| run: | | |
| QT_DIR="" | |
| if [ -n "${{ env.Qt6_DIR }}" ]; then | |
| QT_DIR="${{ env.Qt6_DIR }}" | |
| elif [ -n "${{ env.Qt_DIR }}" ]; then | |
| QT_DIR="${{ env.Qt_DIR }}" | |
| else | |
| QT_CONFIG=$(find "$HOME" "$RUNNER_WORKSPACE" "/Users/runner" -name "Qt6Config.cmake" -type f 2>/dev/null | head -1) | |
| if [ -n "$QT_CONFIG" ]; then | |
| QT_DIR=$(dirname "$QT_CONFIG" | xargs dirname | xargs dirname | xargs dirname) | |
| fi | |
| fi | |
| if [ -z "$QT_DIR" ] || [ ! -d "$QT_DIR" ]; then | |
| echo "Error: Could not determine Qt directory" | |
| exit 1 | |
| fi | |
| echo "Using Qt directory: $QT_DIR" | |
| echo "QT_DIR=$QT_DIR" >> $GITHUB_ENV | |
| - name: Configure CMake | |
| run: | | |
| cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="${{ env.QT_DIR }}" | |
| - name: Build | |
| run: | | |
| cmake --build build --config Release -j$(sysctl -n hw.ncpu) | |
| - name: Deploy Qt frameworks | |
| run: | | |
| QT_DIR="${{ env.QT_DIR }}" | |
| export PATH="$QT_DIR/bin:$PATH" | |
| APP_BUNDLE="build/bin/ApkStudio.app" | |
| # Verify app bundle exists | |
| if [ ! -d "$APP_BUNDLE" ]; then | |
| echo "Error: App bundle not found at $APP_BUNDLE" | |
| find . -type d -name "*.app" 2>/dev/null || true | |
| exit 1 | |
| fi | |
| # Find macdeployqt | |
| MACDEPLOYQT="$QT_DIR/bin/macdeployqt" | |
| if [ ! -f "$MACDEPLOYQT" ]; then | |
| MACDEPLOYQT=$(find "$QT_DIR" -name "macdeployqt" -type f 2>/dev/null | head -1) | |
| fi | |
| if [ -z "$MACDEPLOYQT" ] || [ ! -f "$MACDEPLOYQT" ]; then | |
| echo "Error: macdeployqt not found" | |
| exit 1 | |
| fi | |
| echo "Deploying Qt frameworks to: $APP_BUNDLE" | |
| chmod +x "$MACDEPLOYQT" | |
| "$MACDEPLOYQT" "$APP_BUNDLE" -always-overwrite | |
| - name: Install create-dmg | |
| run: | | |
| brew install create-dmg | |
| - name: Create DMG | |
| run: | | |
| APP_NAME="APK Studio" | |
| APP_BUNDLE_NAME="ApkStudio.app" | |
| APP_PATH="build/bin/${APP_BUNDLE_NAME}" | |
| DMG_NAME="ApkStudio-macOS-x64.dmg" | |
| if [ ! -d "$APP_PATH" ]; then | |
| echo "Error: App bundle not found at $APP_PATH" | |
| exit 1 | |
| fi | |
| # Remove quarantine attribute to prevent "damaged" error | |
| xattr -cr "$APP_PATH" | |
| # Code sign the app with ad-hoc signature (required for macOS Gatekeeper) | |
| echo "Code signing app bundle..." | |
| codesign --force --deep --sign - "$APP_PATH" || { | |
| echo "Warning: Code signing failed, but continuing..." | |
| } | |
| # Verify the signature | |
| codesign --verify --verbose "$APP_PATH" || { | |
| echo "Warning: Code signature verification failed, but continuing..." | |
| } | |
| # Create a temporary directory for DMG contents | |
| mkdir -p dmg_temp | |
| cp -R "$APP_PATH" "dmg_temp/${APP_BUNDLE_NAME}" | |
| # Remove quarantine from copied app as well | |
| xattr -cr "dmg_temp/${APP_BUNDLE_NAME}" | |
| # Code sign the copied app as well | |
| codesign --force --deep --sign - "dmg_temp/${APP_BUNDLE_NAME}" || { | |
| echo "Warning: Code signing copied app failed, but continuing..." | |
| } | |
| # Touch the app bundle to refresh Finder icon cache | |
| touch "dmg_temp/${APP_BUNDLE_NAME}" | |
| touch "dmg_temp/${APP_BUNDLE_NAME}/Contents" | |
| touch "dmg_temp/${APP_BUNDLE_NAME}/Contents/Info.plist" | |
| # Verify icon exists in app bundle | |
| ICON_PATH="$APP_PATH/Contents/Resources/icon.icns" | |
| if [ ! -f "$ICON_PATH" ]; then | |
| echo "Warning: Icon not found at $ICON_PATH" | |
| echo "Contents of Resources directory:" | |
| ls -la "$APP_PATH/Contents/Resources/" 2>/dev/null || echo "Resources directory not found" | |
| fi | |
| # Rename the bundle in DMG to show "APK Studio" instead of "ApkStudio" | |
| # The executable name stays the same, only the bundle name changes | |
| if [ -d "dmg_temp/${APP_BUNDLE_NAME}" ]; then | |
| mv "dmg_temp/${APP_BUNDLE_NAME}" "dmg_temp/APK Studio.app" | |
| DMG_APP_NAME="APK Studio.app" | |
| echo "Renamed bundle to 'APK Studio.app' for DMG display" | |
| else | |
| DMG_APP_NAME="${APP_BUNDLE_NAME}" | |
| fi | |
| # Re-sign the renamed bundle | |
| if [ -d "dmg_temp/${DMG_APP_NAME}" ]; then | |
| codesign --force --deep --sign - "dmg_temp/${DMG_APP_NAME}" || { | |
| echo "Warning: Re-signing renamed bundle failed, but continuing..." | |
| } | |
| fi | |
| # Create DMG with volume icon and ensure app icon is visible | |
| if [ -f "$ICON_PATH" ]; then | |
| create-dmg \ | |
| --volname "APK Studio" \ | |
| --volicon "$ICON_PATH" \ | |
| --window-pos 200 120 \ | |
| --window-size 600 400 \ | |
| --icon-size 100 \ | |
| --icon "${DMG_APP_NAME}" 150 190 \ | |
| --hide-extension "${DMG_APP_NAME}" \ | |
| --app-drop-link 450 190 \ | |
| "$DMG_NAME" \ | |
| dmg_temp/ | |
| else | |
| echo "Creating DMG without volume icon (icon file not found)" | |
| create-dmg \ | |
| --volname "APK Studio" \ | |
| --window-pos 200 120 \ | |
| --window-size 600 400 \ | |
| --icon-size 100 \ | |
| --icon "${DMG_APP_NAME}" 150 190 \ | |
| --hide-extension "${DMG_APP_NAME}" \ | |
| --app-drop-link 450 190 \ | |
| "$DMG_NAME" \ | |
| dmg_temp/ | |
| fi | |
| # Verify DMG was created | |
| if [ -f "$DMG_NAME" ]; then | |
| echo "DMG created successfully: $DMG_NAME" | |
| ls -lh "$DMG_NAME" | |
| else | |
| echo "Error: DMG was not created" | |
| exit 1 | |
| fi | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ApkStudio-macOS-x64 | |
| path: ApkStudio-macOS-x64.dmg | |
| if-no-files-found: error | |
| retention-days: 30 | |
| - name: Upload to release | |
| if: github.event_name == 'release' | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| tag_name: ${{ github.event.release.tag_name }} | |
| files: ApkStudio-macOS-x64.dmg | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |