# Multi-platform build + packaging workflow # - Builds a pyinstaller executable on Windows, Debian, Arch, Rocky. # - Packages using fpm into .deb, .rpm, and pacman (.pkg.tar.zst) files with explicit filenames. # - Creates a GitHub Release with the produced artifacts. # # Notes: # - Poetry is installed via snok/install-poetry@v1 in all jobs. # - fpm gem is pinned to 1.16.0 in the examples; change as needed. # - Rocky job uses tarball downloads for pyenv and python-build (non-interactive, CI-friendly). name: Build Multi-Platform Binaries on: workflow_dispatch: permissions: contents: write env: # change this if you prefer a different pinned fpm version FPM_VERSION: "1.16.0" # Personal Access Token for HTTPS git operations (populate in repository secrets) CI_CD_PAT: ${{ secrets.CI_CD_PAT }} jobs: build-windows: runs-on: windows-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Python 3.12 uses: actions/setup-python@v5 with: python-version: '3.12' - name: Install Poetry uses: snok/install-poetry@v1 with: version: latest virtualenvs-create: true virtualenvs-in-project: true - name: Ensure Poetry is on PATH (Windows) shell: pwsh run: | # Add Poetry user bin to PATH for subsequent steps in this job $poetryPath = Join-Path $env:USERPROFILE ".local\bin" Write-Output $poetryPath >> $Env:GITHUB_PATH - name: Install dependencies run: | poetry install - name: Build Windows executable run: | # Use the Windows spec file so packaging is consistent and reproducible poetry run pyinstaller scripts/spec_scripts/android-file-handler-windows.spec - name: Upload Windows artifact uses: actions/upload-artifact@v4 with: name: windows-binary path: dist/android-file-handler.exe build-debian: runs-on: ubuntu-latest container: image: python:3.12-slim steps: - name: Install system dependencies & gem fpm run: | set -euo pipefail apt-get update apt-get install -y --no-install-recommends curl git build-essential ruby ruby-dev gcc make zlib1g-dev ca-certificates # install pinned fpm to the system gem dir (will be available under gem env's EXECUTABLE DIRECTORY or /usr/local/bin) gem install --no-document -v "${FPM_VERSION}" fpm - name: Checkout code uses: actions/checkout@v4 - name: Set up Python 3.12 uses: actions/setup-python@v5 with: python-version: '3.12' - name: Install Poetry uses: snok/install-poetry@v1 with: version: latest virtualenvs-create: true virtualenvs-in-project: true - name: Configure Poetry run: | echo 'export PATH="$HOME/.local/bin:$PATH"' >> $GITHUB_ENV export PATH="$HOME/.local/bin:$PATH" poetry config virtualenvs.create true poetry config virtualenvs.in-project true - name: Install dependencies & build executable run: | export PATH="$HOME/.local/bin:$PATH" poetry env use python3.12 || true poetry install # Use the Linux spec file for reproducible builds poetry run pyinstaller scripts/spec_scripts/android-file-handler-linux.spec - name: Package .deb (fpm) run: | set -euo pipefail export PATH="$HOME/.local/bin:$PATH" VERSION="$(poetry version -s)" mkdir -p dist chmod +x dist/android-file-handler # explicit filename into dist/ fpm -s dir -t deb -n android-file-handler -v "$VERSION" --architecture amd64 --prefix /usr/local/bin -p "dist/android-file-handler_${VERSION}_amd64.deb" dist/android-file-handler - name: Upload Debian .deb uses: actions/upload-artifact@v4 with: name: debian-package path: dist/android-file-handler_*.deb build-arch: runs-on: ubuntu-latest container: image: archlinux:latest steps: - name: Install system dependencies (Arch) and system Ruby run: | set -euo pipefail pacman -Syu --noconfirm pacman -S --noconfirm ruby base-devel curl git tar ca-certificates # Install fpm system-wide and pin version so fpm will be in /usr/local/bin gem install --no-document erb gem install --no-document -v "${FPM_VERSION}" fpm --bindir /usr/local/bin # persist system bindir to subsequent steps (usually already on PATH) echo "/usr/local/bin" >> $GITHUB_PATH - name: Checkout code uses: actions/checkout@v4 - name: Set up Python 3.12 uses: actions/setup-python@v5 with: python-version: '3.12' - name: Install Poetry uses: snok/install-poetry@v1 with: version: latest virtualenvs-create: true virtualenvs-in-project: true - name: Configure Poetry run: | echo 'export PATH="$HOME/.local/bin:$PATH"' >> $GITHUB_ENV export PATH="$HOME/.local/bin:$PATH" - name: Install dependencies & build executable run: | export PATH="$HOME/.local/bin:/usr/local/bin:$PATH" poetry install # Use the Linux spec file for reproducible builds on Arch poetry run pyinstaller scripts/spec_scripts/android-file-handler-linux.spec - name: Package pacman (fpm) run: | set -euo pipefail export PATH="$HOME/.local/bin:/usr/local/bin:$PATH" VERSION="$(poetry version -s)" mkdir -p dist chmod +x dist/android-file-handler # explicit filename into dist/ fpm -s dir -t pacman -n android-file-handler -v "$VERSION" --architecture x86_64 --prefix /usr/local/bin -p "dist/android-file-handler-${VERSION}-1-x86_64.pkg.tar.zst" dist/android-file-handler - name: Upload Arch package uses: actions/upload-artifact@v4 with: name: arch-package path: dist/*.pkg.tar.* create-release: needs: [build-windows, build-debian, build-arch] runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Install Poetry uses: snok/install-poetry@v1 - name: Get version id: version run: echo "version=$(poetry version -s)" >> $GITHUB_OUTPUT - name: Download all artifacts uses: actions/download-artifact@v4 with: merge-multiple: true path: ./binaries - name: List downloaded binaries (debug) run: | echo "Downloaded files:" ls -la ./binaries || true - name: Create Release uses: softprops/action-gh-release@v1 with: tag_name: v${{ steps.version.outputs.version }} name: Release v${{ steps.version.outputs.version }} files: | ./binaries/android-file-handler.exe ./binaries/android-file-handler_*.deb ./binaries/android-file-handler-*.rpm ./binaries/android-file-handler-*-x86_64.pkg.tar.* draft: false prerelease: false env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}