feat: add 'flatten' option to copy directory contents without parent folder structure

pull/216/head
Ayyadurai 2025-11-09 16:52:51 +05:30
parent 7179e72a3f
commit ae463107f9
5 changed files with 123 additions and 0 deletions

View File

@ -98,6 +98,7 @@ jobs:
| Variable | Description | Default | Security Note |
| ---------------- | ------------------------------------------------------- | ------- | ---------------------- |
| source | Local files/directories to transfer (comma-separated) | - | Use explicit paths |
| flatten | Copy directory contents without parent folder structure | false | Perfect for build dirs |
| 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 | - | |
@ -165,6 +166,7 @@ jobs:
- **Incremental/changed files only** → [Example 3](#example-3-changed-files-only)
- **Artifacts integration** → [Example 4](#example-4-artifacts-integration)
- **Windows server setup** → [Example 5](#example-5-windows-server)
- **Flatten directory structure (build outputs)** → [Example 6](#example-6-flatten-directory-structure)
---
@ -257,6 +259,25 @@ jobs:
rm: true
```
#### Example 6: Flatten Directory Structure
```yaml
- name: Deploy build folder contents
uses: appleboy/scp-action@v1
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
port: ${{ secrets.PORT }}
source: "build/*"
target: "/www/htdocs/production/"
flatten: true
```
**Result:**
- ✅ Without `flatten`: `/www/htdocs/production/build/index.html`
- ✅ With `flatten: true`: `/www/htdocs/production/index.html`
---
## 🗝️ SSH Key Setup
@ -341,6 +362,12 @@ sequenceDiagram
- **Q: How to copy to Windows?**
A: Set up Git Bash, use Unix-style paths, and enable `tar_dereference`.
- **Q: How do I copy only folder contents without the parent folder?**
A: Use `flatten: true`. This automatically handles directory structure flattening:
- `source: "build/*"` + `flatten: true` → copies contents directly to target
- `source: "dist/"` + `flatten: true` → copies contents without creating `dist/` subdirectory
- Perfect for deploying build outputs where you don't want the build folder name in the target path.
---
## 📝 License

View File

@ -98,6 +98,7 @@ jobs:
| 变量 | 说明 | 默认值 | 安全性说明 |
| ---------------- | --------------------------------- | ------ | -------------- |
| source | 本地要传输的文件/目录(逗号分隔) | - | 请使用明确路径 |
| flatten | 仅复制目录内容,不包含父文件夹 | false | 适用于构建目录 |
| target | 远程目标目录(必须为目录) | - | 避免使用根目录 |
| rm | 上传前移除目标目录 | - | 谨慎使用 |
| strip_components | 传输时移除前置路径元素 | - | |
@ -165,6 +166,7 @@ jobs:
- **仅传输变更文件** → [示例 3](#示例-3仅传输变更文件)
- **集成 Artifacts** → [示例 4](#示例-4集成-artifacts)
- **Windows 服务器设置** → [示例 5](#示例-5windows-服务器)
- **扁平化目录结构(构建输出)** → [示例 6](#示例-6扁平化目录结构)
---
@ -257,6 +259,25 @@ jobs:
rm: true
```
#### 示例 6扁平化目录结构
```yaml
- name: 部署构建文件夹内容
uses: appleboy/scp-action@v1
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
port: ${{ secrets.PORT }}
source: "build/*"
target: "/www/htdocs/production/"
flatten: true
```
**结果:**
- ✅ 不使用 `flatten``/www/htdocs/production/build/index.html`
- ✅ 使用 `flatten: true``/www/htdocs/production/index.html`
---
## 🗝️ SSH 密钥设置
@ -341,6 +362,12 @@ sequenceDiagram
- **Q: 如何复制到 Windows**
A: 设置 Git Bash使用类 Unix 路径,并启用 `tar_dereference`
- **Q: 如何只复制文件夹内容而不包含父文件夹?**
A: 使用 `flatten: true`。这会自动处理目录结构扁平化:
- `source: "build/*"` + `flatten: true` → 直接将内容复制到目标目录
- `source: "dist/"` + `flatten: true` → 复制内容而不创建 `dist/` 子目录
- 非常适合部署构建输出,避免在目标路径中包含构建文件夹名称。
---
## 📝 许可证

View File

@ -98,6 +98,7 @@ jobs:
| 變數 | 說明 | 預設值 | 安全性說明 |
| ---------------- | --------------------------------- | ------ | -------------- |
| source | 本地要傳送的檔案/目錄(逗號分隔) | - | 請使用明確路徑 |
| flatten | 僅複製目錄內容,不包含父資料夾 | false | 適用於建置目錄 |
| target | 遠端目標目錄(必須為目錄) | - | 避免使用根目錄 |
| rm | 上傳前移除目標目錄 | - | 請小心使用 |
| strip_components | 傳送時移除前置路徑元素 | - | |
@ -165,6 +166,7 @@ jobs:
- **僅傳送變更檔案** → [範例 3](#範例-3僅傳送變更檔案)
- **整合 Artifacts** → [範例 4](#範例-4整合-artifacts)
- **Windows 伺服器設定** → [範例 5](#範例-5windows-伺服器)
- **扁平化目錄結構(建置輸出)** → [範例 6](#範例-6扁平化目錄結構)
---
@ -257,6 +259,25 @@ jobs:
rm: true
```
#### 範例 6扁平化目錄結構
```yaml
- name: 部署建置資料夾內容
uses: appleboy/scp-action@v1
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
port: ${{ secrets.PORT }}
source: "build/*"
target: "/www/htdocs/production/"
flatten: true
```
**結果:**
- ✅ 不使用 `flatten``/www/htdocs/production/build/index.html`
- ✅ 使用 `flatten: true``/www/htdocs/production/index.html`
---
## 🗝️ SSH 金鑰設定
@ -341,6 +362,12 @@ sequenceDiagram
- **Q: 如何複製到 Windows**
A: 設定 Git Bash使用 Unix 風格路徑,並啟用 `tar_dereference`
- **Q: 如何只複製資料夾內容而不包含父資料夾?**
A: 使用 `flatten: true`。這會自動處理目錄結構扁平化:
- `source: "build/*"` + `flatten: true` → 直接將內容複製到目標目錄
- `source: "dist/"` + `flatten: true` → 複製內容而不建立 `dist/` 子目錄
- 非常適合部署建置輸出,避免在目標路徑中包含建置資料夾名稱。
---
## 📝 授權條款

View File

@ -49,6 +49,9 @@ inputs:
tar_exec:
description: "Path to the tar executable on the destination host. Default: tar."
default: "tar"
flatten:
description: "Copy only directory contents without parent folder structure. Useful for deploying build outputs."
default: "false"
proxy_host:
description: "Remote host address for SSH proxy."
proxy_port:
@ -132,6 +135,7 @@ runs:
INPUT_TAR_DEREFERENCE: ${{ inputs.tar_dereference }}
INPUT_TAR_TMP_PATH: ${{ inputs.tar_tmp_path }}
INPUT_TAR_EXEC: ${{ inputs.tar_exec }}
INPUT_FLATTEN: ${{ inputs.flatten }}
INPUT_PROXY_TIMEOUT: ${{ inputs.proxy_timeout }}
INPUT_CAPTURE_STDOUT: ${{ inputs.capture_stdout }}
INPUT_CURL_INSECURE: ${{ inputs.curl_insecure }}

View File

@ -29,7 +29,45 @@ function detect_client_info() {
esac
}
function process_flatten() {
# Only process if flatten is enabled and strip_components is not manually set
if [[ "${INPUT_FLATTEN}" == 'true' ]] && [[ -z "${INPUT_STRIP_COMPONENTS}" ]]; then
# Parse the source paths (comma-separated)
IFS=',' read -ra SOURCE_PATHS <<< "${INPUT_SOURCE}"
local max_depth=0
for source_path in "${SOURCE_PATHS[@]}"; do
# Trim whitespace
source_path=$(echo "$source_path" | xargs)
# Calculate directory depth (count slashes before wildcard or end)
if [[ "$source_path" == *"*"* ]]; then
# Has wildcard - count slashes before the *
local path_before_wildcard="${source_path%%\**}"
local depth=$(echo "$path_before_wildcard" | tr -cd '/' | wc -c)
else
# No wildcard - treat as directory, count all slashes
local depth=$(echo "$source_path" | sed 's:/*$::' | tr -cd '/' | wc -c)
# Add 1 to strip the directory itself
depth=$((depth + 1))
fi
# Track maximum depth for multiple sources
if [[ $depth -gt $max_depth ]]; then
max_depth=$depth
fi
done
# Set strip_components if we found paths to flatten
if [[ $max_depth -gt 0 ]]; then
export INPUT_STRIP_COMPONENTS="$max_depth"
echo "Flatten enabled: automatically setting strip_components=${max_depth}"
fi
fi
}
detect_client_info
process_flatten
DOWNLOAD_URL_PREFIX="${DRONE_SCP_RELEASE_URL}/v${DRONE_SCP_VERSION}"
CLIENT_BINARY="drone-scp-${DRONE_SCP_VERSION}-${CLIENT_PLATFORM}-${CLIENT_ARCH}"
TARGET="${GITHUB_ACTION_PATH}/${CLIENT_BINARY}"