94 lines
3.1 KiB
YAML
94 lines
3.1 KiB
YAML
name: Deploy
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
deploy:
|
|
runs-on: docker
|
|
steps:
|
|
# Checkout code
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
# Setup SSH for services server
|
|
- name: Setup SSH
|
|
shell: bash
|
|
env:
|
|
SERVICE_SSH_KEY: ${{ secrets.SERVICE_SSH_KEY }}
|
|
SERVICE_HOST: ${{ secrets.SERVICE_HOST }}
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
echo "SSH setup: host=$SERVICE_HOST"
|
|
|
|
if ! command -v ssh >/dev/null 2>&1; then
|
|
if command -v apk >/dev/null 2>&1; then
|
|
apk add --no-cache openssh-client
|
|
elif command -v apt-get >/dev/null 2>&1; then
|
|
apt-get update
|
|
apt-get install -y openssh-client
|
|
else
|
|
echo "ssh client not found and no known package manager available" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
: "${SERVICE_HOST:?Missing secret SERVICE_HOST}"
|
|
: "${SERVICE_SSH_KEY:?Missing secret SERVICE_SSH_KEY}"
|
|
|
|
SERVICE_IP="$(getent ahostsv4 "$SERVICE_HOST" | awk '{print $1; exit}')"
|
|
if [[ -z "${SERVICE_IP}" ]]; then
|
|
echo "ERROR: Could not resolve IPv4 for $SERVICE_HOST" >&2
|
|
getent hosts "$SERVICE_HOST" || true
|
|
exit 1
|
|
fi
|
|
|
|
echo "Resolved IPv4: $SERVICE_HOST -> $SERVICE_IP"
|
|
|
|
echo "Checking TCP/22 reachability..."
|
|
timeout 5 bash -lc "</dev/tcp/$SERVICE_IP/22" || {
|
|
echo "ERROR: Cannot reach $SERVICE_HOST ($SERVICE_IP):22 from runner container" >&2
|
|
exit 1
|
|
}
|
|
|
|
mkdir -p ~/.ssh
|
|
printf '%s\n' "$SERVICE_SSH_KEY" | tr -d '\r' > ~/.ssh/id_ed25519
|
|
chmod 600 ~/.ssh/id_ed25519
|
|
|
|
echo "Fetching host key (ssh-keyscan)..."
|
|
ssh-keyscan -4 -T 5 -H "$SERVICE_HOST" "$SERVICE_IP" >> ~/.ssh/known_hosts || {
|
|
echo "ERROR: ssh-keyscan failed for $SERVICE_HOST ($SERVICE_IP)" >&2
|
|
exit 1
|
|
}
|
|
|
|
# Deploy app locally on the runner host
|
|
- name: Deploy App (Docker Compose)
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
APP_NAME="${{ github.event.repository.name }}"
|
|
APP_PATH="/srv/apps/$APP_NAME"
|
|
echo "Deploying $APP_NAME from $APP_PATH..."
|
|
cd "$APP_PATH"
|
|
docker compose pull
|
|
docker compose up -d
|
|
|
|
# Register app on the services server (triggers infra-controller.path)
|
|
- name: Register App Requirements
|
|
shell: bash
|
|
env:
|
|
SERVICE_HOST: ${{ secrets.SERVICE_HOST }}
|
|
SERVICE_USER: ${{ secrets.SERVICE_USER }}
|
|
run: |
|
|
set -euo pipefail
|
|
APP_NAME="${{ github.event.repository.name }}"
|
|
echo "Registering app $APP_NAME with infra-controller..."
|
|
if [[ -f .infra.toml ]]; then
|
|
ssh -i ~/.ssh/id_ed25519 "$SERVICE_USER@$SERVICE_HOST" infra-register-stdin "$APP_NAME" < .infra.toml
|
|
else
|
|
ssh -i ~/.ssh/id_ed25519 "$SERVICE_USER@$SERVICE_HOST" infra-deregister "$APP_NAME"
|
|
fi
|