name: Build Server .exe on: push: branches: [main] paths: - "server/**" - ".gitea/workflows/build-exe.yml" pull_request: branches: [main] paths: - "server/**" - ".gitea/workflows/build-exe.yml" workflow_dispatch: env: WINEPREFIX: ${{ github.workspace }}/wine-prefix WINEPYTHON: ${{ github.workspace }}/wine-prefix/drive_c/Python312/python.exe DISPLAY: :99.0 WINEDLLOVERRIDES: "mscoree,mshtml=;winemenubuilder.exe=d" WINEARCH: win64 jobs: build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Install Wine & Xvfb run: | sudo dpkg --add-architecture i386 sudo mkdir -p /etc/apt/keyrings sudo wget -qO /etc/apt/keyrings/winehq-archive.key \ https://dl.winehq.org/wine-builds/winehq.key CODENAME=$(lsb_release -cs) sudo wget -qO /etc/apt/sources.list.d/winehq-${CODENAME}.sources \ "https://dl.winehq.org/wine-builds/ubuntu/dists/${CODENAME}/winehq-${CODENAME}.sources" sudo apt-get update sudo apt-get install --install-recommends winehq-stable xvfb -y - name: Start Xvfb run: | Xvfb :99 -screen 0 1024x768x16 & sleep 2 - name: Set up Wine prefix run: | mkdir -p "$WINEPREFIX" wineboot --init --update winecfg -v win10 - name: Download Python embeddable ZIP run: | wget -q \ "https://www.python.org/ftp/python/3.12.4/python-3.12.4-embed-amd64.zip" \ -O /tmp/python-embed.zip - name: Extract Python into Wine prefix run: | TARGET="$WINEPREFIX/drive_c/Python312" mkdir -p "$TARGET" unzip -q /tmp/python-embed.zip -d "$TARGET" # Remove the embeddable zip to avoid confusion rm /tmp/python-embed.zip # Verify echo "Python executable:" ls -la "$TARGET/python.exe" - name: Bootstrap pip for embedded Python run: | cd "$WINEPREFIX/drive_c/Python312" # Download get-pip.py wget -q https://bootstrap.pypa.io/get-pip.py wine python.exe get-pip.py --no-warn-script-location rm get-pip.py # Verify pip is installed wine python.exe -m pip --version - name: Install Python dependencies run: | cd server wine "$WINEPYTHON" -m pip install --upgrade pip wine "$WINEPYTHON" -m pip install -r requirements.txt - name: Run tests run: | cd server wine "$WINEPYTHON" -m pip install pytest pytest-asyncio wine "$WINEPYTHON" -m pytest tests/ -v - name: Build .exe with PyInstaller run: | cd server wine "$WINEPYTHON" -m PyInstaller \ tray_wrapper.py \ --name PaperDash \ --onefile \ --noconsole \ --clean ls -la dist/ - name: Stop Xvfb if: always() run: killall Xvfb || true - name: Upload artifact uses: actions/upload-artifact@v4 with: name: PaperDash.exe path: server/dist/PaperDash.exe if-no-files-found: error - name: Create or update draft release env: GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }} RELEASE_TAG: rolling-draft run: | API="${{ github.api_url }}/repos/${{ github.repository }}" RESPONSE=$(curl -sS -H "Authorization: token $GITEA_TOKEN" \ "$API/releases/tags/$RELEASE_TAG") RELEASE_ID=$(echo "$RESPONSE" | jq -r '.id // empty') if [ -n "$RELEASE_ID" ]; then echo "Updating existing draft release (ID $RELEASE_ID)" curl -sS -X PATCH -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "draft": true, "name": "Draft (latest build)", "body": "Latest PaperDash server build from commit '"${{ github.sha }}"'. Built on Linux via Wine + PyInstaller. Edit tag, name, and notes before publishing." }' \ "$API/releases/$RELEASE_ID" ASSETS=$(curl -sS -H "Authorization: token $GITEA_TOKEN" \ "$API/releases/$RELEASE_ID/assets") for asset_id in $(echo "$ASSETS" | jq -r '.[].id'); do curl -sS -X DELETE -H "Authorization: token $GITEA_TOKEN" \ "$API/releases/$RELEASE_ID/assets/$asset_id" done else echo "Creating new draft release" RESPONSE=$(curl -sS -X POST -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "tag_name": "'"$RELEASE_TAG"'", "draft": true, "name": "Draft (latest build)", "body": "Latest PaperDash server build from commit '"${{ github.sha }}"'. Built on Linux via Wine + PyInstaller. Edit tag, name, and notes before publishing." }' \ "$API/releases") RELEASE_ID=$(echo "$RESPONSE" | jq -r '.id') fi echo "Uploading PaperDash.exe to release $RELEASE_ID" curl -sS -X POST -H "Authorization: token $GITEA_TOKEN" \ -F "attachment=@server/dist/PaperDash.exe;type=application/vnd.microsoft.portable-executable" \ "$API/releases/$RELEASE_ID/assets"