mirror of
				https://github.com/appleboy/scp-action.git
				synced 2025-10-23 08:55:54 +08:00 
			
		
		
		
	- Add a v1 version badge for the stable workflow to all README files Signed-off-by: appleboy <appleboy.tw@gmail.com>
		
			
				
	
	
	
		
			12 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	
			12 KiB
		
	
	
	
	
	
	
	
🚀 GitHub Actions 的 SCP
GitHub Action 用于通过 SSH 复制文件和构建产物。
注意: 仅支持 Linux docker 容器。
✨ 功能特性
- ✅ 通过 SSH 将文件和产物复制到一台或多台远程服务器
- ✅ 支持 SSH 密钥和密码认证
- ✅ 完全支持 SSH 代理(跳板机)
- ✅ 处理 Linux ↔ Windows 路径转换
- ✅ 集成 GitHub Artifacts 工作流
- ✅ 支持增量与差异文件传输
- ✅ 丰富的高级配置选项
📦 目录
🚀 快速开始
在 GitHub Actions 工作流中通过 SSH 复制文件和产物:
name: scp files
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: 通过 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
⚙️ 配置说明
🔌 连接设置
| 变量 | 说明 | 默认值 | 必填 | 
|---|---|---|---|
| host | 远程主机(多台用逗号分隔) | - | ✓ | 
| port | SSH 端口 | 22 | |
| username | SSH 用户名 | - | ✓ | 
| password | SSH 密码(建议优先使用密钥认证) | - | |
| key | SSH 私钥内容 | - | |
| key_path | SSH 私钥文件路径 | - | |
| passphrase | SSH 私钥密码 | - | |
| fingerprint | 主机密钥 SHA256 指纹验证 | - | |
| protocol | IP 协议:'tcp'、'tcp4' 或 'tcp6' | tcp | |
| timeout | SSH 连接超时 | 30s | |
| command_timeout | SCP 命令超时 | 10m | 
📁 文件传输设置
| 变量 | 说明 | 默认值 | 安全性说明 | 
|---|---|---|---|
| source | 本地要传输的文件/目录(逗号分隔) | - | 请使用明确路径 | 
| target | 远程目标目录(必须为目录) | - | 避免使用根目录 | 
| rm | 上传前移除目标目录 | - | 谨慎使用 | 
| strip_components | 传输时移除前置路径元素 | - | |
| overwrite | 使用 tar 覆盖现有文件 | - | |
| tar_dereference | tar 传输时跟随符号链接 | - | |
| tar_tmp_path | 目标端 tar 临时文件路径 | - | |
| tar_exec | 目标端 tar 执行文件路径 | tar | |
| debug | 启用调试输出 | - | |
| curl_insecure | curl 使用 --insecure | false | 不推荐 | 
| capture_stdout | 将命令 stdout 作为 action 输出 | false | |
| version | 指定 drone-scp 版本 | - | 
🌐 代理设置
| 变量 | 说明 | 默认值 | 必填 | 
|---|---|---|---|
| proxy_host | SSH 代理主机 | - | |
| proxy_port | SSH 代理端口 | 22 | |
| proxy_username | SSH 代理用户名 | - | |
| proxy_password | SSH 代理密码 | - | |
| proxy_key | SSH 代理私钥内容 | - | |
| proxy_key_path | SSH 代理私钥文件路径 | - | |
| proxy_passphrase | SSH 代理私钥密码 | - | |
| proxy_fingerprint | 代理主机 SHA256 指纹验证 | - | |
| proxy_use_insecure_cipher | 启用较不安全的代理加密算法 | - | |
| proxy_timeout | SSH 代理连接超时 | 30s | 
🛡️ 最佳实践与安全性
- 建议优先使用 SSH 密钥认证,提升安全性。
- 将所有敏感信息(host、username、password、key)存放于 GitHub Secrets。
- 定期更换部署密钥(建议每 90 天一次)。
- 限制目标服务器目录的写入权限。
- 启用主机密钥指纹验证以防止中间人攻击。
- 避免使用 root 用户登录 SSH。
🖥️ 跨平台注意事项
| 场景 | Linux 服务器 | Windows 服务器 | 
|---|---|---|
| 路径格式 | /path/to/dir | /c/path/to/dir | 
| 必要设置 | 无 | tar_dereference: true | 
| 权限 | 保留 | 可能需手动设置 ACL | 
| Shell | bash(默认) | Git Bash(OpenSSH) | 
🚩 重要提醒:
复制到 Windows 服务器时:
- 安装 Git for Windows 并将 OpenSSH 默认 shell 设为 Git Bash
- 使用类 Unix 目标路径(如
/c/Users/...)- 启用
tar_dereference处理符号链接
💡 使用示例
🧩 场景导览
示例 1:基本 SSH 密码
- name: 通过 SSH 密码复制文件
  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
示例 2:多台服务器
- name: 复制到多台服务器
  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
示例 3:仅传输变更文件
- name: 获取变更文件
  id: changed-files
  uses: tj-actions/changed-files@v35
  with:
    since_last_remote_commit: true
    separator: ","
- name: 复制变更文件到服务器
  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
示例 4:集成 Artifacts
- uses: actions/upload-artifact@v4
  with:
    name: my-artifact
    path: world.txt
- uses: actions/download-artifact@v4
  with:
    name: my-artifact
    path: distfiles
- name: 复制 artifact 到服务器
  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
示例 5:Windows 服务器
- name: 复制到 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 密钥设置
- 
生成 SSH 密钥(在本地执行): # RSA ssh-keygen -t rsa -b 4096 -C "your_email@example.com" # ED25519 ssh-keygen -t ed25519 -a 200 -C "your_email@example.com"
- 
将公钥添加到服务器: cat .ssh/id_rsa.pub | ssh user@host 'cat >> .ssh/authorized_keys' # 或 ed25519 cat .ssh/id_ed25519.pub | ssh user@host 'cat >> .ssh/authorized_keys'
- 
将私钥内容复制到 GitHub Secrets: clip < ~/.ssh/id_rsa # 或 clip < ~/.ssh/id_ed25519
更多细节请参考 SSH 免密登录。
OpenSSH 注意事项:
如遇到 ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey],请确认密钥算法已被支持。
Ubuntu 20.04+ 可在 /etc/ssh/sshd_config 或 /etc/ssh/sshd_config.d/ 添加:
CASignatureAlgorithms +ssh-rsa
或使用 ed25519 密钥(默认支持)。
🧰 常见错误代码
| 错误代码 | 可能原因 | 解决方法 | 
|---|---|---|
| ECONNREFUSED | 端口错误/防火墙阻挡 | 检查端口和防火墙设置 | 
| ENOENT | 找不到源文件 | 使用绝对路径或检查 checkout 步骤 | 
| EAUTH | 认证失败 | 检查密钥格式和权限(需 PEM 格式) | 
🔄 工作流程图
sequenceDiagram
    participant G as GitHub Runner
    participant S as Target Server
    G->>S: 建立 SSH 连接
    S-->>G: 验证凭证
    G->>S: (可选)移除目标目录
    G->>G: 打包源文件
    G->>S: 传输打包文件
    S->>S: 解压和处理文件
    S-->>G: 返回结果
FAQ 与故障排查
- 
Q: 为什么认证失败? 
 A: 请检查 SSH 密钥格式、权限,以及密钥是否已添加到服务器。
- 
Q: 如何只复制变更文件? 
 A: 使用tj-actions/changed-files获取变更文件并传递给source。
- 
Q: 如何部署到多台服务器? 
 A:host参数用逗号分隔多台主机,例如:host: "foo.com,bar.com"
- 
Q: 如何复制到 Windows? 
 A: 设置 Git Bash,使用类 Unix 路径,并启用tar_dereference。
📝 许可证
MIT License