scp-action/README.zh-cn.md
appleboy 7f18bf0ec8
Some checks failed
v1 version / test deploy artifact (push) Failing after 49s
v1 version / test changed-files (push) Failing after 2m36s
v1 version / test target folder (push) Failing after 5m20s
lint and test / test scp action (push) Failing after 2m50s
lint and test / test deploy artifact (push) Failing after 31s
lint and test / test changed-files (push) Failing after 51s
v1 version / test Multiple Host (push) Failing after 7m10s
lint and test / test target folder (push) Failing after 1m58s
lint and test / test Multiple Host (push) Failing after 1m57s
v1 version / test scp action (push) Failing after 11m12s
docs: add v1 workflow version badge to all README files
- Add a v1 version badge for the stable workflow to all README files

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-04-27 12:46:41 +08:00

349 lines
12 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 🚀 GitHub Actions 的 SCP
[English](README.md) | [繁體中文](README.zh-tw.md)
[GitHub Action](https://github.com/features/actions) 用于通过 SSH 复制文件和构建产物。
[![v1 version](https://github.com/appleboy/scp-action/actions/workflows/stable.yml/badge.svg)](https://github.com/appleboy/scp-action/actions/workflows/stable.yml)
[![lint and test](https://github.com/appleboy/scp-action/actions/workflows/testing.yml/badge.svg)](https://github.com/appleboy/scp-action/actions/workflows/testing.yml)
> **注意:** 仅支持 **Linux** [docker](https://www.docker.com/) 容器。
---
## ✨ 功能特性
- ✅ 通过 SSH 将文件和产物复制到一台或多台远程服务器
- ✅ 支持 SSH 密钥和密码认证
- ✅ 完全支持 SSH 代理(跳板机)
- ✅ 处理 Linux ↔ Windows 路径转换
- ✅ 集成 GitHub Artifacts 工作流
- ✅ 支持增量与差异文件传输
- ✅ 丰富的高级配置选项
---
## 📦 目录
- [🚀 GitHub Actions 的 SCP](#-github-actions-的-scp)
- [✨ 功能特性](#-功能特性)
- [📦 目录](#-目录)
- [🚀 快速开始](#-快速开始)
- [⚙️ 配置说明](#-配置说明)
- [🔌 连接设置](#-连接设置)
- [📁 文件传输设置](#-文件传输设置)
- [🌐 代理设置](#-代理设置)
- [🛡️ 最佳实践与安全性](#-最佳实践与安全性)
- [🖥️ 跨平台注意事项](#-跨平台注意事项)
- [💡 使用示例](#-使用示例)
- [🧩 场景导览](#-场景导览)
- [示例 1基本 SSH 密码](#示例-1基本-ssh-密码)
- [示例 2多台服务器](#示例-2多台服务器)
- [示例 3仅传输变更文件](#示例-3仅传输变更文件)
- [示例 4集成 Artifacts](#示例-4集成-artifacts)
- [示例 5Windows 服务器](#示例-5windows-服务器)
- [🗝️ SSH 密钥设置](#-ssh-密钥设置)
- [🧰 常见错误代码](#-常见错误代码)
- [🔄 工作流程图](#-工作流程图)
- [FAQ 与故障排查](#faq-与故障排查)
- [📝 许可证](#-许可证)
---
## 🚀 快速开始
在 GitHub Actions 工作流中通过 SSH 复制文件和产物:
```yaml
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 BashOpenSSH |
> 🚩 **重要提醒:**
> 复制到 Windows 服务器时:
>
> - 安装 Git for Windows 并将 OpenSSH 默认 shell 设为 Git Bash
> - 使用类 Unix 目标路径(如 `/c/Users/...`
> - 启用 `tar_dereference` 处理符号链接
---
## 💡 使用示例
### 🧩 场景导览
- **基本文件传输** → [示例 1](#示例-1基本-ssh-密码)
- **多台服务器部署** → [示例 2](#示例-2多台服务器)
- **仅传输变更文件** → [示例 3](#示例-3仅传输变更文件)
- **集成 Artifacts** → [示例 4](#示例-4集成-artifacts)
- **Windows 服务器设置** → [示例 5](#示例-5windows-服务器)
---
#### 示例 1基本 SSH 密码
```yaml
- 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多台服务器
```yaml
- 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仅传输变更文件
```yaml
- 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
```yaml
- 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
```
#### 示例 5Windows 服务器
```yaml
- 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 密钥设置
1. **生成 SSH 密钥**(在本地执行):
```bash
# 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. **将公钥添加到服务器**
```bash
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'
```
3. **将私钥内容复制到 GitHub Secrets**
```bash
clip < ~/.ssh/id_rsa
# 或
clip < ~/.ssh/id_ed25519
```
> 更多细节请参考 [SSH 免密登录](http://www.linuxproblem.org/art_9.html)。
**OpenSSH 注意事项:**
如遇到 `ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey]`,请确认密钥算法已被支持。
Ubuntu 20.04+ 可在 `/etc/ssh/sshd_config``/etc/ssh/sshd_config.d/` 添加:
```sh
CASignatureAlgorithms +ssh-rsa
```
或使用 ed25519 密钥(默认支持)。
---
## 🧰 常见错误代码
| 错误代码 | 可能原因 | 解决方法 |
| -------------- | ------------------- | --------------------------------- |
| `ECONNREFUSED` | 端口错误/防火墙阻挡 | 检查端口和防火墙设置 |
| `ENOENT` | 找不到源文件 | 使用绝对路径或检查 checkout 步骤 |
| `EAUTH` | 认证失败 | 检查密钥格式和权限(需 PEM 格式) |
---
## 🔄 工作流程图
```mermaid
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