Skip to content

Merge pull request #381 from commjoen/dependabot/npm_and_yarn/asamuza… #737

Merge pull request #381 from commjoen/dependabot/npm_and_yarn/asamuza…

Merge pull request #381 from commjoen/dependabot/npm_and_yarn/asamuza… #737

name: Docker Build and Release
on:
pull_request:
branches: [main]
paths:
- 'src/**'
- 'public/**'
- 'server.js'
- 'server-package.json'
- 'Dockerfile'
- 'package.json'
- 'package-lock.json'
- 'nginx*.conf'
- 'start.sh'
- 'index.html'
- 'vite.config.ts'
push:
branches: [main]
paths:
- 'src/**'
- 'public/**'
- 'server.js'
- 'server-package.json'
- 'Dockerfile'
- 'package.json'
- 'package-lock.json'
- 'nginx*.conf'
- 'start.sh'
- 'index.html'
- 'vite.config.ts'
release:
types: [published]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push:
runs-on: ubuntu-latest
outputs:
image-url: ${{ steps.deployment.outputs.DEPLOY_URL }}
image-tag: ${{ steps.deployment.outputs.DEPLOY_TAG }}
permissions:
contents: read
packages: write
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Fetch full git history for version injection
run: git fetch --unshallow || true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
# Set latest tag for main branch
type=ref,event=branch
type=ref,event=pr
type=raw,value=latest,enable={{is_default_branch}}
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,format=short
labels: |
org.opencontainers.image.title=Multiplayer Platformer Game
org.opencontainers.image.description=A 2D platformer game with optional multiplayer support
org.opencontainers.image.url=https://github.com/${{ github.repository }}
org.opencontainers.image.source=https://github.com/${{ github.repository }}
org.opencontainers.image.version=${{ github.ref_name }}
org.opencontainers.image.created=${{ github.event.head_commit.timestamp }}
org.opencontainers.image.revision=${{ github.sha }}
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Generate deployment URL
id: deployment
run: |
# Extract the first tag from the metadata output
FIRST_TAG=$(echo "${{ steps.meta.outputs.tags }}" | head -n1)
echo "DEPLOY_URL=${FIRST_TAG}" >> $GITHUB_OUTPUT
# Extract just the tag part for display
TAG_ONLY=$(echo "${FIRST_TAG}" | cut -d':' -f2)
echo "DEPLOY_TAG=${TAG_ONLY}" >> $GITHUB_OUTPUT
echo "Using image: ${FIRST_TAG}"
- name: Test Docker image
run: |
echo "Testing Docker image..."
# Pull the built image
docker pull ${{ steps.deployment.outputs.DEPLOY_URL }}
# Run container in background
docker run -d --name test-container -p 8080:80 -p 3001:3001 ${{ steps.deployment.outputs.DEPLOY_URL }}
# Wait for container to start
sleep 20
# Test game client (retry a few times)
for i in {1..5}; do
if curl -f http://localhost:8080; then
echo "✅ Game client responding"
break
else
echo "Attempt $i failed, retrying..."
sleep 5
fi
done
# Test multiplayer health check (optional, don't fail on this)
curl -f http://localhost:3001/health && echo "✅ Multiplayer server responding" || echo "⚠️ Multiplayer server not ready"
# Show container logs for debugging
echo "=== Container Logs ==="
docker logs test-container --tail 20
# Cleanup
docker stop test-container
docker rm test-container
echo "✅ Docker image test completed!"
- name: Comment on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v8
with:
script: |
const output = `## 🐳 Docker Image Built Successfully!
**Image:** \`${{ steps.deployment.outputs.DEPLOY_URL }}\`
### 🚀 Quick Test
\`\`\`bash
# Pull and run the PR image
docker pull ${{ steps.deployment.outputs.DEPLOY_URL }}
docker run -p 8080:80 -p 3001:3001 ${{ steps.deployment.outputs.DEPLOY_URL }}
# Access the game
open http://localhost:8080
\`\`\`
### 📋 Features Tested
- ✅ Game client loads on port 80
- ✅ Multiplayer server starts on port 3001
- ✅ Health checks pass
- ✅ Multi-platform build (amd64, arm64)
### 🔗 Container Details
- **Registry:** GitHub Container Registry (ghcr.io)
- **Platforms:** linux/amd64, linux/arm64
- **Size:** Optimized multi-stage build
- **Security:** Runs as non-root user
### 🌐 Deploy to Render
You can deploy this specific image to Render by updating the image reference in your service settings.`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: output
});
- name: Generate summary
run: |
echo "## 🐳 Docker Build Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Image:** \`${{ steps.deployment.outputs.DEPLOY_URL }}\`" >> $GITHUB_STEP_SUMMARY
echo "**Tag:** \`${{ steps.deployment.outputs.DEPLOY_TAG }}\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📦 Available Images" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 🚀 Usage" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
echo "docker pull ${{ steps.deployment.outputs.DEPLOY_URL }}" >> $GITHUB_STEP_SUMMARY
echo "docker run -p 8080:80 -p 3001:3001 ${{ steps.deployment.outputs.DEPLOY_URL }}" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
security-scan:
runs-on: ubuntu-latest
needs: build-and-push
if: github.event_name != 'pull_request' # Skip security scan for PRs to reduce build time
permissions:
contents: read
security-events: write
steps:
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ needs.build-and-push.outputs.image-url }}
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v4
if: always()
with:
sarif_file: 'trivy-results.sarif'