name: Builds on: push: branches: - master pull_request: branches: - master workflow_dispatch: permissions: contents: write jobs: build: name: Build (${{ matrix.target }}) strategy: fail-fast: false matrix: include: - os: ubuntu-latest target: x86_64-unknown-linux-gnu artifact_name: pacman toolchain: 1.86.0 - os: macos-15-intel target: x86_64-apple-darwin artifact_name: pacman toolchain: 1.86.0 - os: macos-15 target: aarch64-apple-darwin artifact_name: pacman toolchain: 1.86.0 - os: windows-latest target: x86_64-pc-windows-gnu artifact_name: pacman.exe toolchain: 1.86.0 runs-on: ${{ matrix.os }} steps: - name: Checkout uses: actions/checkout@v5 - name: Setup Rust Toolchain uses: dtolnay/rust-toolchain@master with: target: ${{ matrix.target }} toolchain: ${{ matrix.toolchain }} - name: Rust Cache uses: Swatinem/rust-cache@v2 - name: Cache cargo-vcpkg (Non-macOS) if: runner.os != 'macOS' uses: actions/cache@v4 with: path: target/vcpkg key: A-vcpkg-${{ runner.os }}-${{ matrix.target }}-${{ hashFiles('Cargo.toml', 'Cargo.lock') }} restore-keys: | A-vcpkg-${{ runner.os }}-${{ matrix.target }}- - name: Cache vcpkg (macOS) if: runner.os == 'macOS' uses: actions/cache@v4 with: path: | ${{ github.workspace }}/vcpkg/installed ${{ github.workspace }}/vcpkg/packages key: vcpkg-2025.10.17-${{ matrix.target }} restore-keys: | vcpkg-2025.10.17- - name: Vcpkg Linux Dependencies if: runner.os == 'Linux' run: | sudo apt-get update sudo apt-get install -y libltdl-dev - name: Setup vcpkg (macOS) if: runner.os == 'macOS' run: | # Clone vcpkg at latest stable release git clone https://github.com/microsoft/vcpkg.git ${{ github.workspace }}/vcpkg cd ${{ github.workspace }}/vcpkg git checkout 2025.10.17 # Bootstrap vcpkg ./bootstrap-vcpkg.sh -disableMetrics # Determine triplet based on target if [ "${{ matrix.target }}" = "aarch64-apple-darwin" ]; then TRIPLET="arm64-osx" else TRIPLET="x64-osx" fi # Install SDL2 packages ./vcpkg install sdl2 sdl2-image sdl2-ttf sdl2-gfx sdl2-mixer --triplet=$TRIPLET # Set VCPKG_ROOT for rust-sdl2 to find it echo "VCPKG_ROOT=${{ github.workspace }}/vcpkg" >> $GITHUB_ENV - name: Vcpkg (Non-macOS) if: runner.os != 'macOS' run: | cargo install cargo-vcpkg cargo vcpkg -v build working-directory: pacman - name: Build run: cargo build --release working-directory: pacman - name: Acquire Package Version id: get_version shell: bash # required to prevent Windows runners from failing run: | set -euo pipefail # exit on error echo "version=$(cargo metadata --format-version 1 --no-deps | jq '.packages[0].version' -r)" >> $GITHUB_OUTPUT working-directory: pacman - name: Upload Artifact uses: actions/upload-artifact@v4 with: name: "pacman-${{ steps.get_version.outputs.version }}-${{ matrix.target }}" path: ./target/release/${{ matrix.artifact_name }} retention-days: 7 if-no-files-found: error wasm: name: Build (wasm32-unknown-emscripten) runs-on: ubuntu-latest permissions: pages: write id-token: write # concurrency group is used to prevent multiple page deployments from being attempted at the same time concurrency: group: ${{ github.workflow }}-wasm steps: - name: Checkout uses: actions/checkout@v5 - name: Setup Emscripten SDK uses: pyodide/setup-emsdk@v15 with: version: 3.1.43 actions-cache-folder: "emsdk-cache-b" - name: Setup Rust (WASM32 Emscripten) uses: dtolnay/rust-toolchain@master with: target: wasm32-unknown-emscripten toolchain: 1.86.0 - name: Rust Cache uses: Swatinem/rust-cache@v2 - name: Setup Bun uses: oven-sh/setup-bun@v2 with: bun-version: latest - name: Build with Emscripten shell: bash run: | # Retry mechanism for Emscripten build - only retry on specific hash errors MAX_RETRIES=3 RETRY_DELAY=30 for attempt in $(seq 1 $MAX_RETRIES); do echo "Build attempt $attempt of $MAX_RETRIES" # Capture output and check for specific error while preserving real-time output if bun run -i pacman/web.build.ts 2>&1 | tee /tmp/build_output.log; then echo "Build successful on attempt $attempt" break else echo "Build failed on attempt $attempt" # Check if the failure was due to the specific hash error if grep -q "emcc: error: Unexpected hash:" /tmp/build_output.log; then echo "::warning::Detected 'emcc: error: Unexpected hash:' error - will retry (attempt $attempt of $MAX_RETRIES)" if [ $attempt -eq $MAX_RETRIES ]; then echo "::error::All retry attempts failed. Exiting with error." exit 1 fi echo "Waiting $RETRY_DELAY seconds before retry..." sleep $RETRY_DELAY # Exponential backoff: double the delay for next attempt RETRY_DELAY=$((RETRY_DELAY * 2)) else echo "Build failed but not due to hash error - not retrying" exit 1 fi fi done - name: Upload Artifact uses: actions/upload-pages-artifact@v4 if: github.ref == 'refs/heads/master' && github.event_name == 'push' with: path: "./dist/" retention-days: 7 - name: Deploy if: github.ref == 'refs/heads/master' && github.event_name == 'push' uses: actions/deploy-pages@v4