Update README.md #23
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
| # Build AppImage and Docker image on push/release | |
| name: Build | |
| on: | |
| push: | |
| branches: [main, master] | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| # Top-level permissions ensure the GITHUB_TOKEN is minted with packages:write | |
| # so GHCR accepts the push. Job-level overrides alone are not always sufficient. | |
| permissions: | |
| contents: read | |
| packages: write | |
| env: | |
| REGISTRY: ghcr.io | |
| jobs: | |
| # ── AppImage ─────────────────────────────────────────────────────────────── | |
| appimage: | |
| name: Build AppImage | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update -q | |
| sudo apt-get install -y wget rsync libfuse2 fuse file | |
| - name: Build AppImage | |
| run: | | |
| chmod +x build_appimage.sh | |
| ./build_appimage.sh | |
| - name: Verify AppImage | |
| run: | | |
| ls -lh SortIQ-*-x86_64.AppImage | |
| file SortIQ-*-x86_64.AppImage | |
| - name: Upload AppImage artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: SortIQ-AppImage-x86_64 | |
| path: SortIQ-*-x86_64.AppImage | |
| retention-days: 30 | |
| - name: Upload AppImage to release | |
| if: github.event_name == 'release' | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: SortIQ-*-x86_64.AppImage | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # ── Windows ──────────────────────────────────────────────────────────────── | |
| windows: | |
| name: Build Windows .exe | |
| runs-on: windows-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Install dependencies | |
| run: | | |
| pip install --upgrade pip | |
| pip install pyinstaller pillow | |
| pip install -r requirements.txt | |
| - name: Build Windows exe | |
| shell: bash | |
| run: | | |
| chmod +x build_windows.sh | |
| ./build_windows.sh | |
| - name: Verify output | |
| shell: bash | |
| run: ls -lh SortIQ-*-Windows.zip | |
| - name: Upload Windows artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: SortIQ-Windows | |
| path: SortIQ-*-Windows.zip | |
| retention-days: 30 | |
| - name: Upload to release | |
| if: github.event_name == 'release' | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: SortIQ-*-Windows.zip | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # ── macOS ─────────────────────────────────────────────────────────────────── | |
| macos: | |
| name: Build macOS DMG | |
| # macos-14 is Apple Silicon (arm64). Produces arm64-native app; | |
| # Rosetta 2 runs it transparently on Intel Macs. | |
| runs-on: macos-14 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Install dependencies | |
| run: | | |
| pip install --upgrade pip | |
| pip install "pyinstaller>=6.0" pillow | |
| pip install -r requirements.txt | |
| brew install create-dmg || true | |
| - name: Build macOS app + dmg | |
| run: | | |
| chmod +x build_macos.sh | |
| ./build_macos.sh | |
| - name: Verify output | |
| run: ls -lh SortIQ-*-macOS.dmg | |
| - name: Upload macOS artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: SortIQ-macOS | |
| path: SortIQ-*-macOS.dmg | |
| retention-days: 30 | |
| - name: Upload to release | |
| if: github.event_name == 'release' | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: SortIQ-*-macOS.dmg | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # ── Docker ───────────────────────────────────────────────────────────────── | |
| # ── Docker ───────────────────────────────────────────────────────────────── | |
| docker: | |
| name: Build and push Docker image | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ github.repository }} | |
| tags: | | |
| type=ref,event=branch | |
| type=ref,event=pr | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=sha,prefix= | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| # Build image locally for smoke-testing (not pushed yet) | |
| - name: Build Docker image (local smoke-test) | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| push: false | |
| load: true | |
| tags: sortiq:ci-test | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| # --entrypoint python3 overrides /entrypoint.sh to run Python directly | |
| # (without it, passing python3 as an arg starts the full GUI stack). | |
| # Shell timeout 60 kills the container if any import blocks on DBus. | |
| - name: Smoke test — PyQt6 + core modules | |
| run: | | |
| timeout 60 docker run --rm \ | |
| --entrypoint python3 \ | |
| -e QT_QPA_PLATFORM=offscreen \ | |
| -e LIBGL_ALWAYS_SOFTWARE=1 \ | |
| -e DBUS_SESSION_BUS_ADDRESS="unix:path=/dev/null/nosuchsocket" \ | |
| -e NO_AT_BRIDGE=1 \ | |
| -w /app \ | |
| sortiq:ci-test \ | |
| -c " | |
| import PyQt6.sip, PyQt6.QtCore, PyQt6.QtGui, PyQt6.QtWidgets | |
| print('PyQt6 OK') | |
| from core.matcher import MediaMatcher | |
| from core.renamer import FileRenamer | |
| from core.history import RenameHistory | |
| from core.presets import PresetManager | |
| from core.artwork import ArtworkDownloader | |
| from core.media_info import MediaInfoExtractor | |
| print('All core modules OK') | |
| " | |
| # Push to GHCR after smoke test passes. | |
| # If this fails with permission_denied, enable write access in your repo: | |
| # Settings → Actions → General → Workflow permissions → Read and write permissions | |
| - name: Build and push Docker image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| push: ${{ github.event_name != 'pull_request' }} | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| platforms: linux/amd64 |