diff --git a/.github/workflows/example.yml b/.github/workflows/example.yml index 2a0a7a4..338a119 100644 --- a/.github/workflows/example.yml +++ b/.github/workflows/example.yml @@ -21,7 +21,7 @@ jobs: ssh-user: ${{ secrets.SSH_USER }} - name: Check system info - shell: ssh-remote + shell: ssh-remote {0} run: | echo "=== System Information ===" whoami @@ -30,7 +30,7 @@ jobs: pwd - name: Run deployment script - shell: ssh-remote + shell: ssh-remote {0} run: | echo "=== Starting Deployment ===" cd /var/www || cd ~ diff --git a/README.md b/README.md index 4c39a67..3e731b6 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ jobs: ssh-user: ${{ secrets.SSH_USER }} - name: Run remote commands with custom shell - shell: ssh-remote + shell: ssh-remote {0} run: | cd /var/www git pull origin main @@ -135,7 +135,7 @@ jobs: | `ssh-port` | SSH port | No | `22` | | `ssh-known-hosts` | Known hosts content (uses ssh-keyscan if not provided) | No | `''` | | `strict-host-key-checking` | Enable strict host key checking (`yes`/`no`/`accept-new`) | No | `accept-new` | -| `use-shell-wrapper` | Create shell wrapper for remote execution (enables `shell: ssh-remote`) | No | `true` | +| `use-shell-wrapper` | Create shell wrapper for remote execution (enables `shell: ssh-remote {0}`) | No | `true` | | `remote-shell` | Shell to use on remote server (`bash`, `sh`, `zsh`, etc.) | No | `bash` | ## Outputs @@ -152,11 +152,11 @@ This action provides two ways to execute commands remotely: ### 1. Custom Shell Wrapper (Recommended) -Use `shell: ssh-remote` in any step to execute the entire script on the remote server: +Use `shell: ssh-remote {0}` in any step to execute the entire script on the remote server: ```yaml -- name: Deploy application - shell: ssh-remote + - name: Deploy application + shell: ssh-remote {0} run: | cd /var/www/myapp git pull origin main @@ -166,13 +166,12 @@ Use `shell: ssh-remote` in any step to execute the entire script on the remote s **Benefits:** - Natural multi-line script syntax -- Automatic error handling with `set -e` + shell: ssh-remote {0} - Works like a local shell - No need to wrap commands in SSH ### 2. SSH Host Alias (Direct) -Use the `github-action-host` alias for direct SSH commands: ```yaml - name: Run single commands @@ -183,7 +182,6 @@ Use the `github-action-host` alias for direct SSH commands: This eliminates the need to specify the host, user, port, and key path in every SSH command. -## Security Best Practices ### Generating SSH Keys @@ -191,8 +189,7 @@ This eliminates the need to specify the host, user, port, and key path in every # Generate a dedicated SSH key pair for GitHub Actions ssh-keygen -t ed25519 -C "github-actions" -f github_actions_key -# Or use RSA if ed25519 is not supported -ssh-keygen -t rsa -b 4096 -C "github-actions" -f github_actions_key + shell: ssh-remote {0} ``` ### Setting up Secrets @@ -201,7 +198,6 @@ ssh-keygen -t rsa -b 4096 -C "github-actions" -f github_actions_key ```bash cat github_actions_key ``` - 2. Add it to GitHub Secrets: - Go to your repository → Settings → Secrets and variables → Actions - Click "New repository secret" @@ -216,8 +212,7 @@ ssh-keygen -t rsa -b 4096 -C "github-actions" -f github_actions_key ### Getting Known Hosts To pre-populate known hosts (recommended for security): - -```bash + shell: ssh-remote {0} ssh-keyscan -H your-server.com ``` diff --git a/action.yml b/action.yml index 1186113..7ff83c3 100644 --- a/action.yml +++ b/action.yml @@ -183,16 +183,25 @@ runs: cat << 'WRAPPER_EOF' > "$WRAPPER_PATH" #!/bin/bash - set -e - - # Check if input file is provided - if [ -z "$1" ]; then + set -euo pipefail + + # Runner normally passes a temp script path as the first argument. + # If that isn't present, allow script to be piped to stdin. + TMPDIR="${TMPDIR:-/tmp}" + SCRIPT_FILE="" + if [ -n "${1-}" ]; then + SCRIPT_FILE="$1" + elif ! [ -t 0 ]; then + # Write stdin to a temp file + TMP_SCRIPT=$(mktemp "$TMPDIR/ssh-remote-stdin-XXXXXX.sh" 2>/dev/null || mktemp -t ssh-remote-stdin-XXXXXX) + cat - > "$TMP_SCRIPT" + chmod +x "$TMP_SCRIPT" + SCRIPT_FILE="$TMP_SCRIPT" + else 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 @@ -217,7 +226,7 @@ runs: if [ "${{ inputs.use-shell-wrapper }}" = "true" ]; then echo "" echo "To use the remote shell in subsequent steps, add:" - echo " shell: ssh-remote" + echo " shell: ssh-remote {0}" echo "" echo "The 'ssh-remote' shell is now available for use." fi