GitHub Action that copy files and artifacts via SSH.
Shell
1,579
152 commits
updated Aug 9, 2026
GitHub Action for copying files and artifacts via SSH.
Note: Only supports Linux docker containers.
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
| Variable | Description | Default | Required |
|---|---|---|---|
| host | Remote host(s), comma-separated for multiple | - | โ |
| port | SSH port | 22 | |
| username | SSH username | - | โ |
| password | SSH password (prefer SSH key for security) | - | |
| key | SSH private key content | - | |
| key_path | Path to SSH private key file | - | |
| passphrase | Passphrase for SSH private key | - | |
| fingerprint | SHA256 fingerprint for host key verification | - | |
| protocol | IP protocol: 'tcp', 'tcp4', or 'tcp6' | tcp | |
| timeout | SSH connection timeout | 30s | |
| command_timeout | SCP command timeout | 10m |
| Variable | Description | Default | Security Note |
|---|---|---|---|
| source | Local files/directories to transfer (comma-separated) | - | Use explicit paths |
| target | Target directory on remote server (must be a directory) | - | Avoid root directories |
| rm | Remove target directory before upload | - | Use with caution |
| strip_components | Remove leading path elements when extracting | - | |
| overwrite | Overwrite existing files with tar | - | |
| tar_dereference | Follow symlinks with tar | - | |
| tar_tmp_path | Temp path for tar file on destination | - | |
| tar_exec | Path to tar executable on destination | tar | |
| debug | Enable debug output | - | |
| curl_insecure | Use --insecure with curl | false | Not recommended |
| capture_stdout | Capture command stdout as action output | false | |
| version | Version of drone-scp to use | - |
| Variable | Description | Default | Required |
|---|---|---|---|
| proxy_host | SSH proxy host | - | |
| proxy_port | SSH proxy port | 22 | |
| proxy_username | SSH proxy username | - | |
| proxy_password | SSH proxy password | - | |
| proxy_key | SSH proxy private key content | - | |
| proxy_key_path | Path to SSH proxy private key file | - | |
| proxy_passphrase | Passphrase for SSH proxy private key | - | |
| proxy_fingerprint | SHA256 fingerprint for proxy host | - | |
| proxy_use_insecure_cipher | Enable less secure ciphers for proxy | - | |
| proxy_timeout | SSH proxy connection timeout | 30s |
| Scenario | Linux Server | Windows Server |
|---|---|---|
| Path Format | /path/to/dir | /c/path/to/dir |
| Required Setting | None | tar_dereference: true |
| Permissions | Preserved | May require manual ACL |
| Shell | bash (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_dereferencefor symlink handling
- 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
- 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
- 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
- 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
- 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
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"
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'
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.
| Error Code | Possible Cause | Solution |
|---|---|---|
ECONNREFUSED | Wrong port / firewall blocks | Check port and firewall settings |
ENOENT | Source file not found | Use absolute path or check checkout step |
EAUTH | Authentication failed | Check key format and permissions (PEM format) |
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
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.
MIT License
499 followers ยท starred Oct 2024
40,758 followers ยท starred Apr 2023
2,631 followers ยท starred Nov 2022
27 followers ยท starred Jul 2023
GitHub Action that copy files and artifacts via SSH.
Shell
1,579
152 commits
updated Aug 9, 2026
GitHub Action for copying files and artifacts via SSH.
Note: Only supports Linux docker containers.
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
| Variable | Description | Default | Required |
|---|---|---|---|
| host | Remote host(s), comma-separated for multiple | - | โ |
| port | SSH port | 22 | |
| username | SSH username | - | โ |
| password | SSH password (prefer SSH key for security) | - | |
| key | SSH private key content | - | |
| key_path | Path to SSH private key file | - | |
| passphrase | Passphrase for SSH private key | - | |
| fingerprint | SHA256 fingerprint for host key verification | - | |
| protocol | IP protocol: 'tcp', 'tcp4', or 'tcp6' | tcp | |
| timeout | SSH connection timeout | 30s | |
| command_timeout | SCP command timeout | 10m |
| Variable | Description | Default | Security Note |
|---|---|---|---|
| source | Local files/directories to transfer (comma-separated) | - | Use explicit paths |
| target | Target directory on remote server (must be a directory) | - | Avoid root directories |
| rm | Remove target directory before upload | - | Use with caution |
| strip_components | Remove leading path elements when extracting | - | |
| overwrite | Overwrite existing files with tar | - | |
| tar_dereference | Follow symlinks with tar | - | |
| tar_tmp_path | Temp path for tar file on destination | - | |
| tar_exec | Path to tar executable on destination | tar | |
| debug | Enable debug output | - | |
| curl_insecure | Use --insecure with curl | false | Not recommended |
| capture_stdout | Capture command stdout as action output | false | |
| version | Version of drone-scp to use | - |
| Variable | Description | Default | Required |
|---|---|---|---|
| proxy_host | SSH proxy host | - | |
| proxy_port | SSH proxy port | 22 | |
| proxy_username | SSH proxy username | - | |
| proxy_password | SSH proxy password | - | |
| proxy_key | SSH proxy private key content | - | |
| proxy_key_path | Path to SSH proxy private key file | - | |
| proxy_passphrase | Passphrase for SSH proxy private key | - | |
| proxy_fingerprint | SHA256 fingerprint for proxy host | - | |
| proxy_use_insecure_cipher | Enable less secure ciphers for proxy | - | |
| proxy_timeout | SSH proxy connection timeout | 30s |
| Scenario | Linux Server | Windows Server |
|---|---|---|
| Path Format | /path/to/dir | /c/path/to/dir |
| Required Setting | None | tar_dereference: true |
| Permissions | Preserved | May require manual ACL |
| Shell | bash (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_dereferencefor symlink handling
- 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
- 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
- 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
- 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
- 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
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"
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'
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.
| Error Code | Possible Cause | Solution |
|---|---|---|
ECONNREFUSED | Wrong port / firewall blocks | Check port and firewall settings |
ENOENT | Source file not found | Use absolute path or check checkout step |
EAUTH | Authentication failed | Check key format and permissions (PEM format) |
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
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.
MIT License
499 followers ยท starred Oct 2024
40,758 followers ยท starred Apr 2023
2,631 followers ยท starred Nov 2022
27 followers ยท starred Jul 2023