Skip to content

Pass fAIr env vars to backend container #186

Pass fAIr env vars to backend container

Pass fAIr env vars to backend container #186

name: Deploy to Testing Environment
on:
push:
branches:
- develop
env:
REGISTRY: ghcr.io
IMAGE_PREFIX: ${{ github.repository }}
jobs:
test:
name: Run Tests
runs-on: ubuntu-latest
environment: Development
services:
postgres:
image: postgis/postgis:16-3.4
env:
POSTGRES_USER: test
POSTGRES_PASSWORD: test
POSTGRES_DB: test
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Install backend dependencies (with hotosm-auth from monorepo)
working-directory: ./backend
run: |
# Install dependencies (hotosm-auth will be resolved from ../frontend/auth-libs/python)
uv sync --all-extras
- name: Run backend tests
working-directory: ./backend
env:
DATABASE_URL: postgresql+asyncpg://test:test@localhost:5432/test
COOKIE_SECRET: ${{ secrets.COOKIE_SECRET }}
run: uv run pytest
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: latest
- name: Install frontend dependencies
working-directory: ./frontend
run: pnpm install --frozen-lockfile
- name: Run frontend tests
working-directory: ./frontend
run: pnpm test
- name: Build frontend
working-directory: ./frontend
run: pnpm build
deploy:
name: Deploy to EC2
runs-on: ubuntu-latest
needs: test
environment: Development
if: github.ref == 'refs/heads/develop'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup SSH
uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.EC2_SSH_KEY }}
- name: Add EC2 host to known hosts
env:
EC2_HOST: ${{ secrets.EC2_HOST }}
run: |
mkdir -p ~/.ssh
ssh-keyscan -H $EC2_HOST >> ~/.ssh/known_hosts
- 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: Build and push Docker images
run: |
# Build and push backend image (use root context for monorepo access)
docker build -t ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-backend:latest \
-t ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-backend:${{ github.sha }} \
--target production \
-f backend/Dockerfile \
.
docker push ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-backend:latest
docker push ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-backend:${{ github.sha }}
# Build and push frontend image
docker build -t ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-frontend:latest \
-t ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-frontend:${{ github.sha }} \
--target production \
--build-arg VITE_HANKO_URL=https://dev.login.hotosm.org \
--build-arg VITE_DRONE_TM_URL=https://testlogin.dronetm.hotosm.org \
--build-arg BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ) \
--no-cache \
--pull \
./frontend
docker push ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-frontend:latest
docker push ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-frontend:${{ github.sha }}
- name: Deploy to EC2
env:
EC2_HOST: ${{ secrets.EC2_HOST }}
EC2_USER: ${{ secrets.EC2_USER }}
COOKIE_SECRET: ${{ secrets.COOKIE_SECRET }}
OSM_CLIENT_ID: ${{ secrets.OSM_CLIENT_ID }}
OSM_CLIENT_SECRET: ${{ secrets.OSM_CLIENT_SECRET }}
OSM_REDIRECT_URI: ${{ secrets.OSM_REDIRECT_URI }}
ADMIN_EMAILS: ${{ secrets.ADMIN_EMAILS }}
run: |
# Deploy via SSH (using ssh-agent from webfactory/ssh-agent action)
ssh $EC2_USER@$EC2_HOST << 'EOF'
set -e
# Navigate to application directory
cd /opt/portal || exit 1
# Pull latest changes (reset to avoid divergent branches)
git fetch origin develop
git reset --hard origin/develop
# Create/update .env file with secrets (if not exists)
if [ ! -f .env ]; then
cp .env.example .env
echo "✓ Created .env from .env.example"
fi
# Update authentication secrets in .env
sed -i 's|^COOKIE_SECRET=.*|COOKIE_SECRET=${{ secrets.COOKIE_SECRET }}|' .env
sed -i 's|^OSM_CLIENT_ID=.*|OSM_CLIENT_ID=${{ secrets.OSM_CLIENT_ID }}|' .env
sed -i 's|^OSM_CLIENT_SECRET=.*|OSM_CLIENT_SECRET=${{ secrets.OSM_CLIENT_SECRET }}|' .env
sed -i 's|^OSM_REDIRECT_URI=.*|OSM_REDIRECT_URI=${{ secrets.OSM_REDIRECT_URI }}|' .env
sed -i 's|^ADMIN_EMAILS=.*|ADMIN_EMAILS=${{ secrets.ADMIN_EMAILS }}|' .env
echo "✓ Updated authentication secrets in .env"
# Configure Drone-TM backend URL (point to testlogin for SSO testing)
if grep -q '^DRONE_TM_BACKEND_URL=' .env; then
sed -i 's|^DRONE_TM_BACKEND_URL=.*|DRONE_TM_BACKEND_URL=https://testlogin.dronetm.hotosm.org/api|' .env
else
echo 'DRONE_TM_BACKEND_URL=https://testlogin.dronetm.hotosm.org/api' >> .env
fi
echo "✓ Updated Drone-TM backend URL"
# Configure fAIr API URL (point to testlogin for SSO testing)
if grep -q '^FAIR_API_BASE_URL=' .env; then
sed -i 's|^FAIR_API_BASE_URL=.*|FAIR_API_BASE_URL=https://testlogin.fair.hotosm.org/api/v1|' .env
else
echo 'FAIR_API_BASE_URL=https://testlogin.fair.hotosm.org/api/v1' >> .env
fi
echo "✓ Updated fAIr API URL"
# Enable SSL verification for production (valid certs)
if grep -q '^DRONE_TM_VERIFY_SSL=' .env; then
sed -i 's|^DRONE_TM_VERIFY_SSL=.*|DRONE_TM_VERIFY_SSL=true|' .env
else
echo 'DRONE_TM_VERIFY_SSL=true' >> .env
fi
if grep -q '^FAIR_VERIFY_SSL=' .env; then
sed -i 's|^FAIR_VERIFY_SSL=.*|FAIR_VERIFY_SSL=true|' .env
else
echo 'FAIR_VERIFY_SSL=true' >> .env
fi
echo "✓ Enabled SSL verification"
# Login to GitHub Container Registry
echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
# Pull latest images
docker compose pull
# Restart services with force recreate and pull (uses .env.example values)
docker compose --profile prod up -d --force-recreate --pull always
# Clean up old images
docker image prune -af
echo "✓ Deployment completed successfully"
EOF
# - name: Verify deployment
# env:
# EC2_HOST: ${{ secrets.EC2_HOST }}
# run: |
# sleep 30
# curl -f http://$EC2_HOST:8000/health || exit 1
# echo "✓ Backend health check passed"
- name: Notify deployment status
if: always()
run: |
if [ ${{ job.status }} == 'success' ]; then
echo "✓ Deployment to testing environment successful"
echo "Note: Manual verification required (health check disabled)"
else
echo "✗ Deployment failed"
exit 1
fi