name: Deploy to Railway on: push: branches: - master workflow_dispatch: permissions: contents: read packages: write env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} jobs: build-and-deploy: name: Build and Deploy runs-on: ubuntu-latest outputs: digest: ${{ steps.docker_build.outputs.digest }} 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 # ========== WASM Build ========== - name: Build WASM 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 # ========== Docker Build and Push ========== # Note: Frontend is now built inside Docker using multi-stage build - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to GitHub Container Registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata for Docker id: meta uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=ref,event=branch type=sha,prefix={{branch}}- type=raw,value=latest,enable={{is_default_branch}} - name: Build and push Docker image id: docker_build uses: docker/build-push-action@v6 with: context: . file: ./pacman-server/Dockerfile push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max build-args: | GIT_COMMIT_SHA=${{ github.sha }} # Wait for ghcr.io propagation (paranoid safety) - name: Wait for registry propagation run: sleep 5 # Deploy to Railway - separate job to use container properly deploy: name: Deploy to Railway runs-on: ubuntu-latest needs: build-and-deploy container: ghcr.io/railwayapp/cli:latest env: RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }} steps: - name: Generate proxy Dockerfile run: echo "FROM ghcr.io/xevion/pac-man@${{ needs.build-and-deploy.outputs.digest }}" > Dockerfile - name: Deploy to Railway run: railway up --service pac-man