diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 922ac00..179fcfb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -82,6 +82,8 @@ jobs: needs: build-and-push-images if: github.ref == 'refs/heads/prod' runs-on: ubuntu-latest + environment: + name: production env: SERVER_HOST: ${{ secrets.SERVER_IP }} SERVER_USER: ${{ secrets.SERVER_USER }} @@ -94,20 +96,70 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Normalize deploy settings + run: | + server_host="$(printf '%s' "${SERVER_HOST}" | tr -d '\r' | sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//')" + server_user="$(printf '%s' "${SERVER_USER}" | tr -d '\r' | sed -E 's/[[:space:]]+$//')" + server_port="$(printf '%s' "${SERVER_PORT}" | tr -d '\r' | sed -E 's/[[:space:]]+$//')" + deploy_path="$(printf '%s' "${DEPLOY_PATH}" | tr -d '\r' | sed -E 's/[[:space:]]+$//')" + + server_host="${server_host#http://}" + server_host="${server_host#https://}" + server_host="${server_host%%/*}" + + if [[ "$server_host" == *"@"* ]]; then + if [ -z "$server_user" ]; then + server_user="${server_host%@*}" + fi + server_host="${server_host#*@}" + fi + + if printf '%s' "$server_host" | grep -Eq '^[^:/]+:[0-9]+$'; then + if [ -z "$server_port" ]; then + server_port="${server_host##*:}" + fi + server_host="${server_host%:*}" + fi + + : "${server_user:=ubuntu}" + : "${server_port:=22}" + : "${deploy_path:=/opt/focus}" + + if [ -z "$server_host" ]; then + echo "SERVER_IP secret is empty or invalid" >&2 + exit 1 + fi + + if [ -z "$SSH_PRIVATE_KEY" ]; then + echo "SSH_PRIVATE_KEY secret is empty" >&2 + exit 1 + fi + + if [ -z "$GHCR_TOKEN" ]; then + echo "GHCR_TOKEN secret is empty" >&2 + exit 1 + fi + + { + echo "SERVER_HOST=$server_host" + echo "SERVER_USER=$server_user" + echo "SERVER_PORT=$server_port" + echo "DEPLOY_PATH=$deploy_path" + } >> "$GITHUB_ENV" + - name: Prepare SSH run: | - : "${SERVER_USER:=ubuntu}" - : "${SERVER_PORT:=22}" mkdir -p ~/.ssh printf '%s\n' "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa - ssh-keyscan -p "$SERVER_PORT" -H "$SERVER_HOST" >> ~/.ssh/known_hosts + ssh-keyscan -T 10 -p "$SERVER_PORT" -H "$SERVER_HOST" >> ~/.ssh/known_hosts || { + echo "Could not read SSH host key from $SERVER_HOST:$SERVER_PORT" >&2 + echo "Check that SERVER_IP and SERVER_PORT point to the SSH service, not a web panel port." >&2 + exit 1 + } - name: Upload deployment files run: | - : "${SERVER_USER:=ubuntu}" - : "${SERVER_PORT:=22}" - : "${DEPLOY_PATH:=/opt/focus}" ssh -p "$SERVER_PORT" "$SERVER_USER@$SERVER_HOST" "mkdir -p '$DEPLOY_PATH'" scp -P "$SERVER_PORT" deploy/docker-compose.server.yml "$SERVER_USER@$SERVER_HOST:$DEPLOY_PATH/docker-compose.yml" @@ -148,16 +200,10 @@ jobs: - name: Upload env file run: | - : "${SERVER_USER:=ubuntu}" - : "${SERVER_PORT:=22}" - : "${DEPLOY_PATH:=/opt/focus}" scp -P "$SERVER_PORT" deploy.env "$SERVER_USER@$SERVER_HOST:$DEPLOY_PATH/.env" - name: Deploy on server run: | - : "${SERVER_USER:=ubuntu}" - : "${SERVER_PORT:=22}" - : "${DEPLOY_PATH:=/opt/focus}" ssh -p "$SERVER_PORT" "$SERVER_USER@$SERVER_HOST" <