setup-ssh-client/action.yml

161 lines
5.5 KiB
YAML

name: 'Setup SSH Client'
description: 'Configure SSH client for running remote commands with custom shell wrapper'
author: 'Karolis Kundrotas'
branding:
icon: 'terminal'
color: 'blue'
inputs:
ssh-private-key:
description: 'SSH private key for authentication'
required: true
ssh-host:
description: 'SSH host to connect to'
required: true
ssh-user:
description: 'SSH username'
required: true
ssh-port:
description: 'SSH port'
required: false
default: '22'
ssh-known-hosts:
description: 'Known hosts content (optional, will use ssh-keyscan if not provided)'
required: false
default: ''
strict-host-key-checking:
description: 'Enable strict host key checking (yes/no/accept-new)'
required: false
default: 'accept-new'
use-shell-wrapper:
description: 'Create shell wrapper for remote execution (enables shell: ssh-remote)'
required: false
default: 'true'
remote-shell:
description: 'Shell to use on remote server (bash, sh, zsh, etc.)'
required: false
default: 'bash'
outputs:
ssh-config-path:
description: 'Path to the SSH config file'
value: ${{ steps.setup-ssh.outputs.ssh-config-path }}
ssh-key-path:
description: 'Path to the SSH private key'
value: ${{ steps.setup-ssh.outputs.ssh-key-path }}
shell-wrapper-path:
description: 'Path to the SSH remote shell wrapper script'
value: ${{ steps.setup-shell-wrapper.outputs.shell-wrapper-path }}
runs:
using: 'composite'
steps:
- name: Setup SSH
id: setup-ssh
shell: bash
run: |
# Create SSH directory
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# Setup SSH private key
SSH_KEY_PATH="$HOME/.ssh/github_action_key"
echo "${{ inputs.ssh-private-key }}" > "$SSH_KEY_PATH"
chmod 600 "$SSH_KEY_PATH"
echo "ssh-key-path=$SSH_KEY_PATH" >> $GITHUB_OUTPUT
# Setup known hosts
if [ -n "${{ inputs.ssh-known-hosts }}" ]; then
echo "${{ inputs.ssh-known-hosts }}" > ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
else
if [ "${{ inputs.strict-host-key-checking }}" = "yes" ]; then
echo "❌ strict-host-key-checking is 'yes' but no ssh-known-hosts provided. Refusing to auto-add host key via ssh-keyscan." >&2
echo "Provide the host's key (e.g. from a trusted source) via 'ssh-known-hosts' input." >&2
exit 1
fi
echo "Scanning host keys for ${{ inputs.ssh-host }}..."
ssh-keyscan -p ${{ inputs.ssh-port }} -H "${{ inputs.ssh-host }}" >> ~/.ssh/known_hosts 2>/dev/null || true
chmod 644 ~/.ssh/known_hosts
fi
# Create SSH config
SSH_CONFIG_PATH="$HOME/.ssh/config"
cat >> "$SSH_CONFIG_PATH" << EOF
Host github-action-host
HostName ${{ inputs.ssh-host }}
User ${{ inputs.ssh-user }}
Port ${{ inputs.ssh-port }}
IdentityFile $SSH_KEY_PATH
StrictHostKeyChecking ${{ inputs.strict-host-key-checking }}
UserKnownHostsFile ~/.ssh/known_hosts
EOF
chmod 600 "$SSH_CONFIG_PATH"
echo "ssh-config-path=$SSH_CONFIG_PATH" >> $GITHUB_OUTPUT
echo "✅ SSH client configured successfully"
echo "Connect using: ssh github-action-host"
- name: Test SSH Connection
shell: bash
run: |
echo "Testing SSH connection..."
if ssh -o ConnectTimeout=10 -o BatchMode=yes github-action-host "echo 'SSH connection successful'" 2>&1; then
echo "✅ SSH connection test passed"
else
echo "⚠️ SSH connection test failed - please verify your credentials and host"
exit 1
fi
- name: Create SSH Remote Shell Wrapper
id: setup-shell-wrapper
if: inputs.use-shell-wrapper == 'true'
shell: bash
run: |
# Create a unique temporary wrapper script. Prefer RUNNER_TEMP if set.
WRAPPER_DIR="${RUNNER_TEMP:-/tmp}"
mkdir -p "$WRAPPER_DIR"
WRAPPER_PATH="$(mktemp "$WRAPPER_DIR/ssh-remote-shell-XXXXXX.sh")"
cat << 'WRAPPER_EOF' > "$WRAPPER_PATH"
#!/bin/bash
set -e
# Check if input file is provided
if [ -z "$1" ]; then
echo "Error: No script file provided" >&2
exit 1
fi
SCRIPT_FILE="$1"
# Check if script file exists
if [ ! -f "$SCRIPT_FILE" ]; then
echo "Error: Script file '$SCRIPT_FILE' not found" >&2
exit 1
fi
# Execute script on remote server
# Use BatchMode to prevent interactive prompts
# ConnectTimeout to fail fast if connection issues
ssh -o BatchMode=yes \
-o ConnectTimeout=10 \
github-action-host \
"${{ inputs.remote-shell }} -s" < "$SCRIPT_FILE"
WRAPPER_EOF
chmod +x "$WRAPPER_PATH"
echo "shell-wrapper-path=$WRAPPER_PATH" >> $GITHUB_OUTPUT
echo "✅ SSH remote shell wrapper created at $WRAPPER_PATH"
echo ""
echo "To use the remote shell in subsequent steps, add:"
echo " shell: ssh-remote"
echo ""
echo "The 'ssh-remote' shell is now available for use."
- name: Register Custom Shell
if: inputs.use-shell-wrapper == 'true'
shell: bash
run: |
echo "ssh-remote=${{ steps.setup-shell-wrapper.outputs.shell-wrapper-path }} {0}" >> "$GITHUB_ENV"
echo "✅ Custom shell 'ssh-remote' registered for this job"