name: Build
run-name: Build Windows (x86_64), macOS (Intel), Snap, and Flatpak 🚀
on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  build-win64:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install python
        uses: actions/setup-python@v5
        with:
          python-version: "3.12.8"

      - name: Install poetry
        run: C:\hostedtoolcache\windows\Python\3.12.8\x64\python -m pip install poetry

      - name: Restore cache - poetry
        uses: actions/cache@v4
        with:
          path: ~\AppData\Local\pypoetry\Cache\virtualenvs
          key: ${{ runner.os }}-win64-poetry-${{ hashFiles('desktop/poetry.lock') }}

      - name: Install poetry dependencies
        run: |
          cd desktop
          C:\hostedtoolcache\windows\Python\3.12.8\x64\Scripts\poetry install
          C:\hostedtoolcache\windows\Python\3.12.8\x64\Scripts\poetry env list --full-path

      - name: Restore cache - tor
        uses: actions/cache@v4
        with:
          path: desktop\build\tor
          key: ${{ runner.os }}-win64-tor-${{ hashFiles('desktop/scripts/get-tor.py') }}

      - name: Get tor binaries from Tor Browser (64-bit)
        run: cd desktop && C:\hostedtoolcache\windows\Python\3.12.8\x64\Scripts\poetry run python .\scripts\get-tor.py win64

      - name: Install Go >=1.23.5
        uses: actions/setup-go@v5
        with:
          go-version: ">=1.23.5"
          cache: false
      - run: go version

      - name: Restore cache - obfs4proxy
        uses: actions/cache@v4
        with:
          path: desktop\onionshare\resources\tor\obfs4proxy.exe
          key: ${{ runner.os }}-win64-obfs4proxy-${{ hashFiles('desktop/scripts/build-pt-obfs4proxy.ps1') }}

      - name: Build obfs4proxy
        shell: pwsh
        run: |
          if ((Test-Path -Path 'desktop\onionshare\resources\tor\obfs4proxy.exe') -eq $True) {
            Write-Output "obfs4proxy already built"
          } else {
            cd desktop
            .\scripts\build-pt-obfs4proxy.ps1
          }

      - name: Restore cache - snowflake
        uses: actions/cache@v4
        with:
          path: desktop\onionshare\resources\tor\snowflake-client.exe
          key: ${{ runner.os }}-win64-snowflake-${{ hashFiles('desktop/scripts/build-pt-snowflake.ps1') }}

      - name: Build snowflake
        shell: pwsh
        run: |
          if ((Test-Path -Path 'desktop\onionshare\resources\tor\snowflake-client.exe') -eq $True) {
            Write-Output "snowflake already built"
          } else {
            cd desktop
            .\scripts\build-pt-snowflake.ps1
          }

      - name: Restore cache - meek
        uses: actions/cache@v4
        with:
          path: desktop\onionshare\resources\tor\meek-client.exe
          key: ${{ runner.os }}-win64-meek-${{ hashFiles('desktop/scripts/build-pt-meek.ps1') }}

      - name: Build meek
        shell: pwsh
        run: |
          if ((Test-Path -Path 'desktop\onionshare\resources\tor\meek-client.exe') -eq $True) {
            Write-Output "meek already built"
          } else {
            cd desktop
            .\scripts\build-pt-meek.ps1
          }

      - name: Build OnionShare
        run: |
          cd desktop
          C:\hostedtoolcache\windows\Python\3.12.8\x64\Scripts\poetry run python .\setup-freeze.py build
          C:\hostedtoolcache\windows\Python\3.12.8\x64\Scripts\poetry run python .\scripts\build-windows.py cleanup-build

      - name: Compress
        shell: pwsh
        run: |
          mv desktop\build\exe.win-amd64-3.12\ ~\onionshare-win64
          Compress-Archive -LiteralPath ~\onionshare-win64 -DestinationPath ~\onionshare-win64.zip

      - uses: actions/upload-artifact@v4
        with:
          name: win64-build
          path: ~\onionshare-win64.zip

  build-mac-intel:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Python 3.12.8 (universal2)
        run: |
          curl -L https://www.python.org/ftp/python/3.12.8/python-3.12.8-macos11.pkg --output ~/Downloads/python.pkg
          sudo installer -pkg ~/Downloads/python.pkg -target /

      - name: Install poetry
        run: |
          curl -sSL https://install.python-poetry.org | python3 -

      - name: Restore cache - poetry
        uses: actions/cache@v4
        with:
          path: ~/Library/Caches/pypoetry/virtualenvs
          key: ${{ runner.os }}-macos-poetry-${{ hashFiles('desktop/poetry.lock') }}

      - name: Install poetry dependencies
        run: |
          cd desktop
          ~/Library/Application\ Support/pypoetry/venv/bin/poetry install

      - name: Restore cache - tor
        uses: actions/cache@v4
        with:
          path: desktop/build/tor
          key: ${{ runner.os }}-macos-tor-${{ hashFiles('desktop/scripts/get-tor.py') }}

      - name: Get tor binaries from Tor Browser
        run: |
          cd desktop
          ~/Library/Application\ Support/pypoetry/venv/bin/poetry run python ./scripts/get-tor.py macos

      - name: Install Go >=1.23.5
        uses: actions/setup-go@v5
        with:
          go-version: ">=1.23.5"
          cache: false
      - run: go version

      - name: Restore cache - obfs4proxy
        uses: actions/cache@v4
        with:
          path: desktop/onionshare/resources/tor/obfs4proxy
          key: ${{ runner.os }}-macos-obfs4proxy-${{ hashFiles('desktop/scripts/build-pt-obfs4proxy.sh') }}

      - name: Build obfs4proxy
        run: |
          if [[ -f "desktop/onionshare/resources/tor/obfs4proxy" ]]; then
            echo "obfs4proxy already built"
          else
            cd desktop
            ./scripts/build-pt-obfs4proxy.sh
          fi

      - name: Restore cache - snowflake
        uses: actions/cache@v4
        with:
          path: desktop/onionshare/resources/tor/snowflake-client
          key: ${{ runner.os }}-macos-snowflake-${{ hashFiles('desktop/scripts/build-pt-snowflake.sh') }}

      - name: Build snowflake
        run: |
          if [[ -f "desktop/onionshare/resources/tor/snowflake-client" ]]; then
            echo "snowflake already built"
          else
            cd desktop
            ./scripts/build-pt-snowflake.sh
          fi

      - name: Restore cache - meek
        uses: actions/cache@v4
        with:
          path: desktop/onionshare/resources/tor/meek-client
          key: ${{ runner.os }}-macos-meek-${{ hashFiles('desktop/scripts/build-pt-meek.sh') }}

      - name: Build meek
        run: |
          if [[ -f "desktop/onionshare/resources/tor/meek-client" ]]; then
            echo "meek already built"
          else
            cd desktop
            ./scripts/build-pt-meek.sh
          fi

      - name: Install cx_Freeze/PySide6 build dependencies
        run: |
          brew install libiodbc
          cd ~/Downloads
          curl -O -L https://github.com/PostgresApp/PostgresApp/releases/download/v2.6.5/Postgres-2.6.5-14.dmg
          hdiutil attach Postgres-2.6.5-14.dmg
          cp -r /Volumes/Postgres-2.6.5-14/Postgres.app /Applications/
          hdiutil detach /Volumes/Postgres-2.6.5-14

      - name: Build OnionShare
        run: |
          cd desktop
          ~/Library/Application\ Support/pypoetry/venv/bin/poetry run python ./setup-freeze.py bdist_mac
          ~/Library/Application\ Support/pypoetry/venv/bin/poetry run python ./scripts/build-macos.py cleanup-build

      - name: Compress
        run: |
          cd desktop/build
          tar -czvf ~/onionshare-macos-intel.tar.gz OnionShare.app

      - uses: actions/upload-artifact@v4
        with:
          name: mac-intel-build
          path: ~/onionshare-macos-intel.tar.gz

  build-flatpak:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup
        run: |
          sudo apt update
          sudo apt install -y flatpak flatpak-builder
          flatpak remote-add --if-not-exists --user flathub https://flathub.org/repo/flathub.flatpakrepo

      - name: Restore cache - .flatpak-builder
        uses: actions/cache@v4
        with:
          path: flatpak/.flatpak-builder
          key: flatpak-.flatpak-builder-${{ hashFiles('flatpak/org.onionshare.OnionShare.yaml') }}

      - name: Restore cache - build
        uses: actions/cache@v4
        with:
          path: flatpak/build
          key: flatpak-build-${{ hashFiles('flatpak/org.onionshare.OnionShare.yaml') }}

      - name: Flatpak build
        run: |
          cd flatpak
          flatpak-builder build --force-clean --install-deps-from=flathub --install --user org.onionshare.OnionShare.yaml
          flatpak build-bundle ~/.local/share/flatpak/repo ~/OnionShare.flatpak org.onionshare.OnionShare --runtime-repo=https://flathub.org/repo/flathub.flatpakrepo

      - uses: actions/upload-artifact@v4
        with:
          name: flatpak-build
          path: ~/OnionShare.flatpak

  build-snap:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Restore cache - lxd
        uses: actions/cache@v4
        with:
          path: ~/lxd_cache.tar.gz
          key: snap-lxd-${{ hashFiles('snap/snapcraft.yaml') }}

      - name: Decompress cached content to lxd directory
        run: |
          if [ -f "~/lxd_cache.tar.gz" ]; then
            sudo tar -xzf ~/lxd_cache.tar.gz -C /
          fi

      - name: Install dependencies
        run: |
          sudo lxd init --auto
          sudo lxc storage list
          sudo snap install snapcraft --classic
          sudo ufw disable

      - name: Build snap
        run: sudo snapcraft

      - name: Compress lxd directory and set proper permissions
        run: |
          sudo tar -czf ~/lxd_cache.tar.gz /var/snap/lxd/common/lxd/storage-pools/default
          sudo chown $USER:$USER ~/lxd_cache.tar.gz

      - uses: actions/upload-artifact@v4
        with:
          name: snapcraft-build
          path: onionshare_*.snap
