Skip to content

Merge pull request #5 from bnbong/feature/multiplayer #1

Merge pull request #5 from bnbong/feature/multiplayer

Merge pull request #5 from bnbong/feature/multiplayer #1

name: Deploy Backend
on:
workflow_dispatch:
push:
branches: [main]
paths:
- "backend/**"
- "src/fall_in/core/**"
- "src/fall_in/ai/**"
- "src/fall_in/net/**"
- "src/fall_in/multiplayer/models.py"
# Only one deployment at a time.
concurrency:
group: deploy-backend
cancel-in-progress: true
jobs:
test:
name: Pre-deploy Test
runs-on: ubuntu-latest
defaults:
run:
shell: bash
working-directory: backend
steps:
- uses: actions/checkout@v6
- name: Set up Python 3.12
uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install dependencies
run: uv sync --extra dev
- name: Lint
run: uv run ruff check app/ tests/
- name: Test
run: uv run pytest -x -q
deploy:
name: Deploy to OCI
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.OCI_SSH_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan -H "${{ secrets.OCI_HOST }}" >> ~/.ssh/known_hosts
- name: Sync source to server
run: |
rsync -azP --delete \
--include='backend/***' \
--include='src/fall_in/core/***' \
--include='src/fall_in/ai/***' \
--include='src/fall_in/net/***' \
--include='src/fall_in/multiplayer/models.py' \
--include='src/fall_in/__init__.py' \
--include='src/fall_in/multiplayer/__init__.py' \
--include='src/' \
--include='src/fall_in/' \
--include='src/fall_in/multiplayer/' \
--include='pyproject.toml' \
--include='uv.lock' \
--include='data/***' \
--exclude='*' \
./ "${{ secrets.OCI_USER }}@${{ secrets.OCI_HOST }}:~/fall-in/"
- name: Build & restart on server
run: |
ssh "${{ secrets.OCI_USER }}@${{ secrets.OCI_HOST }}" << 'DEPLOY_SCRIPT'
set -e
cd ~/fall-in
# Build Docker image (ARM-native on Ampere A1).
docker build -t fall-in-backend -f backend/Dockerfile .
# Stop existing container (if any) and start fresh.
docker stop fall-in-backend 2>/dev/null || true
docker rm fall-in-backend 2>/dev/null || true
docker run -d \
--name fall-in-backend \
--restart unless-stopped \
--env-file ~/fall-in/backend/.env \
--network host \
fall-in-backend
# Wait for health check.
echo "Waiting for health check..."
for i in $(seq 1 15); do
if curl -sf http://localhost:8000/healthz > /dev/null 2>&1; then
echo "Health check passed."
exit 0
fi
sleep 2
done
echo "Health check failed after 30s"
docker logs fall-in-backend --tail 30
exit 1
DEPLOY_SCRIPT
- name: Clean up old Docker images
if: success()
run: |
ssh "${{ secrets.OCI_USER }}@${{ secrets.OCI_HOST }}" \
'docker image prune -f'