name: Deploy on: push: branches: - main workflow_dispatch: jobs: deploy: runs-on: self-hosted 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 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 timeout 5 bash -lc "&2 exit 1 } mkdir -p ~/.ssh printf '%s\n' "$SERVICE_SSH_KEY" | tr -d '\r' > ~/.ssh/id_ed25519 chmod 600 ~/.ssh/id_ed25519 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..." if [[ ! -d "$APP_PATH" ]]; then echo "Skipping deploy: $APP_PATH not found on this runner" exit 0 fi 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