appleboy/scp-action

GitHub Action that copy files and artifacts via SSH.

Shell

1,579

152 commits

updated Aug 9, 2026

See the code

README

๐Ÿš€ SCP for GitHub Actions

็น้ซ”ไธญๆ–‡ | ็ฎ€ไฝ“ไธญๆ–‡

GitHub Action for copying files and artifacts via SSH.

v1 version lint and test

Note: Only supports Linux docker containers.


โœจ Features

  • โœ… Copy files and artifacts to one or multiple remote servers via SSH
  • โœ… Supports both SSH key and password authentication
  • โœ… Full SSH Proxy (jump host) support
  • โœ… Handles Linux โ†” Windows path conversion
  • โœ… Integrates with GitHub Artifacts workflow
  • โœ… Incremental and differential file transfer
  • โœ… Rich configuration options for advanced use cases

๐Ÿ“ฆ Table of Contents


๐Ÿš€ Quick Start

Copy files and artifacts via SSH in your GitHub Actions workflow:

name: scp files
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Copy files via SSH
        uses: appleboy/scp-action@v1
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          password: ${{ secrets.PASSWORD }}
          port: ${{ secrets.PORT }}
          source: "tests/a.txt,tests/b.txt"
          target: your_server_target_folder_path

โš™๏ธ Configuration

๐Ÿ”Œ Connection Settings

VariableDescriptionDefaultRequired
hostRemote host(s), comma-separated for multiple-โœ“
portSSH port22
usernameSSH username-โœ“
passwordSSH password (prefer SSH key for security)-
keySSH private key content-
key_pathPath to SSH private key file-
passphrasePassphrase for SSH private key-
fingerprintSHA256 fingerprint for host key verification-
protocolIP protocol: 'tcp', 'tcp4', or 'tcp6'tcp
timeoutSSH connection timeout30s
command_timeoutSCP command timeout10m

๐Ÿ“ File Transfer Settings

VariableDescriptionDefaultSecurity Note
sourceLocal files/directories to transfer (comma-separated)-Use explicit paths
targetTarget directory on remote server (must be a directory)-Avoid root directories
rmRemove target directory before upload-Use with caution
strip_componentsRemove leading path elements when extracting-
overwriteOverwrite existing files with tar-
tar_dereferenceFollow symlinks with tar-
tar_tmp_pathTemp path for tar file on destination-
tar_execPath to tar executable on destinationtar
debugEnable debug output-
curl_insecureUse --insecure with curlfalseNot recommended
capture_stdoutCapture command stdout as action outputfalse
versionVersion of drone-scp to use-

๐ŸŒ Proxy Settings

VariableDescriptionDefaultRequired
proxy_hostSSH proxy host-
proxy_portSSH proxy port22
proxy_usernameSSH proxy username-
proxy_passwordSSH proxy password-
proxy_keySSH proxy private key content-
proxy_key_pathPath to SSH proxy private key file-
proxy_passphrasePassphrase for SSH proxy private key-
proxy_fingerprintSHA256 fingerprint for proxy host-
proxy_use_insecure_cipherEnable less secure ciphers for proxy-
proxy_timeoutSSH proxy connection timeout30s

๐Ÿ›ก๏ธ Best Practices & Security

  • Prefer SSH key authentication over passwords for better security.
  • Store all sensitive values (host, username, password, key) in GitHub Secrets.
  • Regularly rotate deployment keys (suggested every 90 days).
  • Restrict write permissions on the target server directory.
  • Enable host key fingerprint verification to prevent MITM attacks.
  • Avoid using root as the SSH user.

๐Ÿ–ฅ๏ธ Cross-Platform Notes

ScenarioLinux ServerWindows Server
Path Format/path/to/dir/c/path/to/dir
Required SettingNonetar_dereference: true
PermissionsPreservedMay require manual ACL
Shellbash (default)Git Bash via OpenSSH

๐Ÿšฉ Important:
When copying to Windows servers:

  • Install Git for Windows and set OpenSSH default shell to Git Bash
  • Use Unix-style target paths (e.g., /c/Users/...)
  • Enable tar_dereference for symlink handling

๐Ÿ’ก Usage Examples

๐Ÿงฉ Scenario Guide


Example 1: Basic SSH Password

- name: Copy file via SSH password
  uses: appleboy/scp-action@v1
  with:
    host: example.com
    username: foo
    password: bar
    port: 22
    source: "tests/a.txt,tests/b.txt"
    target: your_server_target_folder_path

Example 2: Multi-server

- name: Copy to multiple servers
  uses: appleboy/scp-action@v1
  with:
    host: "foo.com,bar.com"
    username: foo
    password: bar
    port: 22
    source: "tests/a.txt,tests/b.txt"
    target: your_server_target_folder_path

Example 3: Changed Files Only

- name: Get changed files
  id: changed-files
  uses: tj-actions/changed-files@v35
  with:
    since_last_remote_commit: true
    separator: ","

- name: Copy changed files to server
  uses: appleboy/scp-action@v1
  with:
    host: ${{ secrets.HOST }}
    username: ${{ secrets.USERNAME }}
    key: ${{ secrets.KEY }}
    port: ${{ secrets.PORT }}
    source: ${{ steps.changed-files.outputs.all_changed_files }}
    target: your_server_target_folder_path

Example 4: Artifacts Integration

- uses: actions/upload-artifact@v4
  with:
    name: my-artifact
    path: world.txt

- uses: actions/download-artifact@v4
  with:
    name: my-artifact
    path: distfiles

- name: Copy artifact to server
  uses: appleboy/scp-action@v1
  with:
    host: ${{ secrets.HOST }}
    username: ${{ secrets.USERNAME }}
    key: ${{ secrets.KEY }}
    port: ${{ secrets.PORT }}
    source: distfiles/*
    target: your_server_target_folder_path

Example 5: Windows Server

- name: Copy to Windows
  uses: appleboy/scp-action@v1
  with:
    host: ${{ secrets.HOST }}
    username: ${{ secrets.USERNAME }}
    key: ${{ secrets.SSH_PRIVATE_KEY }}
    port: 22
    source: "your_source_path"
    target: "/c/path/to/target/"
    tar_dereference: true
    rm: true

๐Ÿ—๏ธ SSH Key Setup

  1. Generate SSH Key (on your local machine):

    # RSA
    ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
    # ED25519
    ssh-keygen -t ed25519 -a 200 -C "your_email@example.com"
    
  2. Add Public Key to Server:

    cat .ssh/id_rsa.pub | ssh user@host 'cat >> .ssh/authorized_keys'
    # or for ed25519
    cat .ssh/id_ed25519.pub | ssh user@host 'cat >> .ssh/authorized_keys'
    
  3. Copy Private Key Content to GitHub Secrets:

    clip < ~/.ssh/id_rsa
    # or
    clip < ~/.ssh/id_ed25519
    

See SSH login without password for more details.

OpenSSH Note:
If you see ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], ensure your key algorithm is supported.
On Ubuntu 20.04+, add to /etc/ssh/sshd_config or /etc/ssh/sshd_config.d/:

CASignatureAlgorithms +ssh-rsa

Or use ed25519 keys, which are accepted by default.


๐Ÿงฐ Common Error Codes

Error CodePossible CauseSolution
ECONNREFUSEDWrong port / firewall blocksCheck port and firewall settings
ENOENTSource file not foundUse absolute path or check checkout step
EAUTHAuthentication failedCheck key format and permissions (PEM format)

๐Ÿ”„ Workflow Diagram

sequenceDiagram
    participant G as GitHub Runner
    participant S as Target Server
    G->>S: Establish SSH connection
    S-->>G: Authenticate credentials
    G->>S: (Optional) Remove target directory
    G->>G: Archive source files
    G->>S: Transfer archive
    S->>S: Extract and process files
    S-->>G: Return result

FAQ & Troubleshooting

  • Q: Why does authentication fail?
    A: Check SSH key format, permissions, and that the key is added to the server.

  • Q: How do I copy only changed files?
    A: Use tj-actions/changed-files to get changed files and pass to source.

  • Q: How to deploy to multiple servers?
    A: Use comma-separated host list: host: "foo.com,bar.com"

  • Q: How to copy to Windows?
    A: Set up Git Bash, use Unix-style paths, and enable tar_dereference.


๐Ÿ“ License

MIT License

github-action
github-actions
scp

appleboy/scp-action

GitHub Action that copy files and artifacts via SSH.

Shell

1,579

152 commits

updated Aug 9, 2026

See the code

README

๐Ÿš€ SCP for GitHub Actions

็น้ซ”ไธญๆ–‡ | ็ฎ€ไฝ“ไธญๆ–‡

GitHub Action for copying files and artifacts via SSH.

v1 version lint and test

Note: Only supports Linux docker containers.


โœจ Features

  • โœ… Copy files and artifacts to one or multiple remote servers via SSH
  • โœ… Supports both SSH key and password authentication
  • โœ… Full SSH Proxy (jump host) support
  • โœ… Handles Linux โ†” Windows path conversion
  • โœ… Integrates with GitHub Artifacts workflow
  • โœ… Incremental and differential file transfer
  • โœ… Rich configuration options for advanced use cases

๐Ÿ“ฆ Table of Contents


๐Ÿš€ Quick Start

Copy files and artifacts via SSH in your GitHub Actions workflow:

name: scp files
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Copy files via SSH
        uses: appleboy/scp-action@v1
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          password: ${{ secrets.PASSWORD }}
          port: ${{ secrets.PORT }}
          source: "tests/a.txt,tests/b.txt"
          target: your_server_target_folder_path

โš™๏ธ Configuration

๐Ÿ”Œ Connection Settings

VariableDescriptionDefaultRequired
hostRemote host(s), comma-separated for multiple-โœ“
portSSH port22
usernameSSH username-โœ“
passwordSSH password (prefer SSH key for security)-
keySSH private key content-
key_pathPath to SSH private key file-
passphrasePassphrase for SSH private key-
fingerprintSHA256 fingerprint for host key verification-
protocolIP protocol: 'tcp', 'tcp4', or 'tcp6'tcp
timeoutSSH connection timeout30s
command_timeoutSCP command timeout10m

๐Ÿ“ File Transfer Settings

VariableDescriptionDefaultSecurity Note
sourceLocal files/directories to transfer (comma-separated)-Use explicit paths
targetTarget directory on remote server (must be a directory)-Avoid root directories
rmRemove target directory before upload-Use with caution
strip_componentsRemove leading path elements when extracting-
overwriteOverwrite existing files with tar-
tar_dereferenceFollow symlinks with tar-
tar_tmp_pathTemp path for tar file on destination-
tar_execPath to tar executable on destinationtar
debugEnable debug output-
curl_insecureUse --insecure with curlfalseNot recommended
capture_stdoutCapture command stdout as action outputfalse
versionVersion of drone-scp to use-

๐ŸŒ Proxy Settings

VariableDescriptionDefaultRequired
proxy_hostSSH proxy host-
proxy_portSSH proxy port22
proxy_usernameSSH proxy username-
proxy_passwordSSH proxy password-
proxy_keySSH proxy private key content-
proxy_key_pathPath to SSH proxy private key file-
proxy_passphrasePassphrase for SSH proxy private key-
proxy_fingerprintSHA256 fingerprint for proxy host-
proxy_use_insecure_cipherEnable less secure ciphers for proxy-
proxy_timeoutSSH proxy connection timeout30s

๐Ÿ›ก๏ธ Best Practices & Security

  • Prefer SSH key authentication over passwords for better security.
  • Store all sensitive values (host, username, password, key) in GitHub Secrets.
  • Regularly rotate deployment keys (suggested every 90 days).
  • Restrict write permissions on the target server directory.
  • Enable host key fingerprint verification to prevent MITM attacks.
  • Avoid using root as the SSH user.

๐Ÿ–ฅ๏ธ Cross-Platform Notes

ScenarioLinux ServerWindows Server
Path Format/path/to/dir/c/path/to/dir
Required SettingNonetar_dereference: true
PermissionsPreservedMay require manual ACL
Shellbash (default)Git Bash via OpenSSH

๐Ÿšฉ Important:
When copying to Windows servers:

  • Install Git for Windows and set OpenSSH default shell to Git Bash
  • Use Unix-style target paths (e.g., /c/Users/...)
  • Enable tar_dereference for symlink handling

๐Ÿ’ก Usage Examples

๐Ÿงฉ Scenario Guide


Example 1: Basic SSH Password

- name: Copy file via SSH password
  uses: appleboy/scp-action@v1
  with:
    host: example.com
    username: foo
    password: bar
    port: 22
    source: "tests/a.txt,tests/b.txt"
    target: your_server_target_folder_path

Example 2: Multi-server

- name: Copy to multiple servers
  uses: appleboy/scp-action@v1
  with:
    host: "foo.com,bar.com"
    username: foo
    password: bar
    port: 22
    source: "tests/a.txt,tests/b.txt"
    target: your_server_target_folder_path

Example 3: Changed Files Only

- name: Get changed files
  id: changed-files
  uses: tj-actions/changed-files@v35
  with:
    since_last_remote_commit: true
    separator: ","

- name: Copy changed files to server
  uses: appleboy/scp-action@v1
  with:
    host: ${{ secrets.HOST }}
    username: ${{ secrets.USERNAME }}
    key: ${{ secrets.KEY }}
    port: ${{ secrets.PORT }}
    source: ${{ steps.changed-files.outputs.all_changed_files }}
    target: your_server_target_folder_path

Example 4: Artifacts Integration

- uses: actions/upload-artifact@v4
  with:
    name: my-artifact
    path: world.txt

- uses: actions/download-artifact@v4
  with:
    name: my-artifact
    path: distfiles

- name: Copy artifact to server
  uses: appleboy/scp-action@v1
  with:
    host: ${{ secrets.HOST }}
    username: ${{ secrets.USERNAME }}
    key: ${{ secrets.KEY }}
    port: ${{ secrets.PORT }}
    source: distfiles/*
    target: your_server_target_folder_path

Example 5: Windows Server

- name: Copy to Windows
  uses: appleboy/scp-action@v1
  with:
    host: ${{ secrets.HOST }}
    username: ${{ secrets.USERNAME }}
    key: ${{ secrets.SSH_PRIVATE_KEY }}
    port: 22
    source: "your_source_path"
    target: "/c/path/to/target/"
    tar_dereference: true
    rm: true

๐Ÿ—๏ธ SSH Key Setup

  1. Generate SSH Key (on your local machine):

    # RSA
    ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
    # ED25519
    ssh-keygen -t ed25519 -a 200 -C "your_email@example.com"
    
  2. Add Public Key to Server:

    cat .ssh/id_rsa.pub | ssh user@host 'cat >> .ssh/authorized_keys'
    # or for ed25519
    cat .ssh/id_ed25519.pub | ssh user@host 'cat >> .ssh/authorized_keys'
    
  3. Copy Private Key Content to GitHub Secrets:

    clip < ~/.ssh/id_rsa
    # or
    clip < ~/.ssh/id_ed25519
    

See SSH login without password for more details.

OpenSSH Note:
If you see ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], ensure your key algorithm is supported.
On Ubuntu 20.04+, add to /etc/ssh/sshd_config or /etc/ssh/sshd_config.d/:

CASignatureAlgorithms +ssh-rsa

Or use ed25519 keys, which are accepted by default.


๐Ÿงฐ Common Error Codes

Error CodePossible CauseSolution
ECONNREFUSEDWrong port / firewall blocksCheck port and firewall settings
ENOENTSource file not foundUse absolute path or check checkout step
EAUTHAuthentication failedCheck key format and permissions (PEM format)

๐Ÿ”„ Workflow Diagram

sequenceDiagram
    participant G as GitHub Runner
    participant S as Target Server
    G->>S: Establish SSH connection
    S-->>G: Authenticate credentials
    G->>S: (Optional) Remove target directory
    G->>G: Archive source files
    G->>S: Transfer archive
    S->>S: Extract and process files
    S-->>G: Return result

FAQ & Troubleshooting

  • Q: Why does authentication fail?
    A: Check SSH key format, permissions, and that the key is added to the server.

  • Q: How do I copy only changed files?
    A: Use tj-actions/changed-files to get changed files and pass to source.

  • Q: How to deploy to multiple servers?
    A: Use comma-separated host list: host: "foo.com,bar.com"

  • Q: How to copy to Windows?
    A: Set up Git Bash, use Unix-style paths, and enable tar_dereference.


๐Ÿ“ License

MIT License

github-action
github-actions
scp

Project health

Overall

2.9/10

Maintained

1/10

Code review

0/10
OpenSSF Scorecard

Significant stargazers

Renรฉe

499 followers ยท starred Oct 2024

Kamran Ahmed

40,758 followers ยท starred Apr 2023

Harminder Virk

2,631 followers ยท starred Nov 2022

xingkong

27 followers ยท starred Jul 2023