fix: compiles #67
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI/CD - Build, Test & Deploy | |
| on: | |
| push: | |
| branches: [ main, next, feature/* ] | |
| pull_request: | |
| branches: [ main ] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read # For checkout in build and deploy jobs | |
| packages: read # For pulling from GHCR | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository }} | |
| jobs: | |
| build-and-test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Generate GitHub App token | |
| id: app-token | |
| uses: actions/create-github-app-token@v1 | |
| with: | |
| app-id: ${{ secrets.GH_APP_ID }} | |
| private-key: ${{ secrets.GH_APP_PRIVATEKEY }} | |
| owner: app4dog | |
| repositories: workspace | |
| - name: Clone workspace and symlink critter-keeper | |
| run: | | |
| set -e # Exit on any error | |
| echo "📂 Cloning workspace repository" | |
| if ! git clone --filter=blob:none --sparse https://x-access-token:${{ steps.app-token.outputs.token }}@github.com/app4dog/workspace.git ~/workspace; then | |
| echo "❌ Failed to clone workspace repository" | |
| exit 1 | |
| fi | |
| cd ~/workspace | |
| if ! git sparse-checkout set critter-keeper; then | |
| echo "❌ Failed to configure sparse checkout for critter-keeper" | |
| exit 1 | |
| fi | |
| # Verify critter-keeper was actually checked out | |
| if [ ! -d "critter-keeper" ]; then | |
| echo "❌ critter-keeper directory not found after sparse checkout" | |
| exit 1 | |
| fi | |
| echo "📁 Creating symlink for critter-keeper in game-play repo" | |
| cd $GITHUB_WORKSPACE | |
| if ! ln -sf ~/workspace/critter-keeper ./critter-keeper; then | |
| echo "❌ Failed to create symlink for critter-keeper" | |
| exit 1 | |
| fi | |
| echo "✅ critter-keeper symlink created" | |
| echo "📂 Verifying symlink target exists:" | |
| if ! ls -la ./critter-keeper/; then | |
| echo "❌ Symlink target directory is not accessible" | |
| exit 1 | |
| fi | |
| echo "📂 Testing Cargo.toml accessibility:" | |
| if ! test -f ./critter-keeper/Cargo.toml; then | |
| echo "❌ Cargo.toml not found - critter-keeper dependency will fail" | |
| exit 1 | |
| fi | |
| echo "✅ Cargo.toml found and accessible" | |
| echo "📂 Working directory is: $(pwd)" | |
| echo "📂 Full path to critter-keeper: $(readlink -f ./critter-keeper)" | |
| - name: Pull and setup artifacts from GHCR | |
| continue-on-error: true | |
| run: | | |
| echo "Logging into GHCR as ${{ github.actor }}" | |
| echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin | |
| echo "Pulling artifacts image..." | |
| docker pull ghcr.io/app4dog/artifacts:latest | |
| echo "Copying all artifacts to CI repo root..." | |
| rm -rf artifacts | |
| mkdir -p artifacts | |
| docker run --rm --user "$(id -u):$(id -g)" -v "$PWD/artifacts:/output" ghcr.io/app4dog/artifacts:latest sh -c "cp -r /artifacts/* /output/ && ls -la /output/" | |
| echo "Updating critters symlink for CI (artifacts -> public/critters)" | |
| mkdir -p public | |
| cd public && rm -f critters && ln -s ../artifacts/critters critters && ls -la critters | |
| cd .. | |
| echo "Artifacts setup complete:" | |
| ls -la artifacts/ | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v2 | |
| with: | |
| version: 8 | |
| run_install: false | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'pnpm' | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: wasm32-unknown-unknown | |
| - name: Install wasm-pack | |
| run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh | |
| - name: Setup just | |
| uses: extractions/setup-just@v2 | |
| with: | |
| just-version: '*' | |
| - name: Cache pnpm dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.pnpm-store | |
| key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pnpm- | |
| - name: Cache Rust dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| game-engine/target | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| key: ${{ runner.os }}-cargo-${{ hashFiles('game-engine/Cargo.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo- | |
| - name: Pull and setup artifacts from GHCR | |
| continue-on-error: true | |
| run: | | |
| echo "Logging into GHCR as ${{ github.actor }}" | |
| echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin | |
| echo "Pulling artifacts image..." | |
| docker pull ghcr.io/app4dog/artifacts:latest | |
| echo "Copying all artifacts to CI repo root..." | |
| mkdir -p artifacts | |
| docker run --rm --user "$(id -u):$(id -g)" -v "$PWD/artifacts:/output" ghcr.io/app4dog/artifacts:latest sh -c "cp -r /artifacts/* /output/ && ls -la /output/" | |
| echo "Updating critters symlink for CI (../../artifacts -> ./artifacts)" | |
| cd public && rm -f critters && ln -s ../artifacts/critters critters && ls -la critters | |
| cd .. | |
| echo "Artifacts setup complete:" | |
| ls -la artifacts/ | |
| - name: Install Node dependencies | |
| run: pnpm install | |
| - name: Build WASM game engine | |
| run: WASM_FEATURES="--no-default-features --features camera_sprite_preview,critter-keeper" just build-wasm | |
| - name: Build Quasar app | |
| run: pnpm run build | |
| - name: Run linting | |
| run: pnpm run lint | |
| - name: Run type checking | |
| run: | | |
| echo "🔍 Running TypeScript type checking..." | |
| if ! pnpm exec vue-tsc --noEmit; then | |
| echo "❌ Type checking failed - please fix TypeScript errors before merging" | |
| # Allow type checking to fail in CI for now, but make it visible | |
| echo "::warning::TypeScript type checking failed" | |
| else | |
| echo "✅ Type checking passed" | |
| fi | |
| - name: Run tests | |
| run: | | |
| echo "🧪 Running test suite..." | |
| if ! pnpm test; then | |
| echo "❌ Tests failed - please fix failing tests before merging" | |
| # Allow tests to fail in CI for now, but make it visible | |
| echo "::warning::Test suite failed" | |
| else | |
| echo "✅ All tests passed" | |
| fi | |
| - name: Test WASM integration | |
| run: | | |
| echo "🔍 Verifying WASM files were generated..." | |
| WASM_FOUND=false | |
| # Check primary location (src/types/wasm/) first | |
| if [ -f "src/types/wasm/app4dog_game_engine.js" ] && [ -f "src/types/wasm/app4dog_game_engine_bg.wasm" ]; then | |
| echo "✅ WASM files found in src/types/wasm/" | |
| ls -la src/types/wasm/ | |
| WASM_FOUND=true | |
| # Check fallback location (public/game-engine/) | |
| elif [ -f "public/game-engine/app4dog_game_engine.js" ] && [ -f "public/game-engine/app4dog_game_engine_bg.wasm" ]; then | |
| echo "✅ WASM files found in public/game-engine/" | |
| ls -la public/game-engine/ | |
| WASM_FOUND=true | |
| fi | |
| if [ "$WASM_FOUND" = "false" ]; then | |
| echo "❌ WASM files not found in expected locations" | |
| echo "Checking for any WASM files..." | |
| find . -name "*.wasm" -o -name "*game_engine*.js" | head -10 | |
| exit 1 | |
| fi | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: dist | |
| path: dist/ | |
| retention-days: 7 | |
| - name: Upload WASM artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: wasm-build | |
| path: | | |
| src/types/wasm/ | |
| retention-days: 7 | |
| if-no-files-found: error | |
| deploy-cloudflare: | |
| needs: build-and-test | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/next' | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Download build artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: dist | |
| path: dist/ | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Set R2 bucket name | |
| id: bucket | |
| run: | | |
| if [[ "${GITHUB_REF}" == "refs/heads/main" ]]; then | |
| echo "name=gameplay-live" >> $GITHUB_OUTPUT | |
| else | |
| echo "name=gameplay-next" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Deploy to Cloudflare R2 | |
| uses: ryand56/r2-upload-action@latest | |
| with: | |
| r2-account-id: ${{ secrets.CF_ACCOUNT_ID }} | |
| r2-access-key-id: ${{ secrets.CLOUDFLARE_R2_ACCESS_KEY }} | |
| r2-secret-access-key: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }} | |
| r2-bucket: ${{ steps.bucket.outputs.name }} | |
| source-dir: dist/spa | |
| destination-dir: ./ |