8 Commits

Author SHA1 Message Date
appleboy
823bd89e13 ci: trigger GitHub Actions workflows only on version tags
- Restrict the GitHub Actions workflow to trigger only on tags matching the pattern vMAJOR.MINOR.PATCH

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-11-28 23:09:09 +08:00
appleboy
f6208e096d docs: document and demonstrate capturing and using command output
- Add documentation outlining usage of output variables, specifically the captured command standard output
- Introduce the `capture_stdout` parameter to command options tables
- Update Quick Start examples to use a secret for the username, and clarify output handling
- Provide example workflows showing how to capture and use command output in subsequent steps
- Change code block language from bash to text for SSH configuration snippets

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-11-28 23:07:52 +08:00
appleboy
652a0bee3c docs: update CI documentation and workflow references
- Clarify that the main CI workflow tests the local action, not just Docker containers
- Add references to new workflows for testing the published tag and for automated security scanning
- Explain the naming difference for the `INPUT_SCRIPT_FILE` environment variable
- Update documentation to reflect default drone-ssh version change from 1.8.1 to 1.8.2

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-11-28 22:55:57 +08:00
appleboy
4e3535e14e chore: bump default DRONE_SSH_VERSION to 1.8.2
- Update the default DRONE_SSH_VERSION from 1.8.1 to 1.8.2

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-11-28 22:51:52 +08:00
appleboy
91f3272fc5 docs: add Trivy security scan badge to all documentation
- Add Trivy Security Scan badge to the documentation in all language versions

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-11-08 10:27:34 +08:00
appleboy
53f5c5cedf ci: add automated Trivy security scanning via GitHub Actions
- Add a GitHub Action workflow to perform Trivy security scans on the repository
- Configure scheduled, push, and pull request triggers for the scan
- Upload vulnerability scan results to the GitHub Security tab in SARIF format
- Include additional scan step with table output and failure on detected vulnerabilities

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-11-08 10:25:32 +08:00
Bo-Yi Wu
170eebb2ee fix: enhance binary download flow with robust error handling (#394)
- Define specific error codes for common failure scenarios
- Improve platform and architecture error handling by using error codes
- Add check to reuse cached binary if already downloaded
- Enhance download process with better error handling and validation of the downloaded file
- Add post-download version check with error if binary execution fails

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-11-08 10:18:33 +08:00
appleboy
c680069d84 docs: add comprehensive documentation for project setup and usage
- Add CLAUDE.md with detailed guidelines for using Claude Code in this repository
- Document project architecture, key files, and composite action behavior
- Explain automated testing strategy using Docker containers and GitHub Actions
- Provide instructions for local testing and key troubleshooting tips
- Describe supported features: script execution methods, environment variable handling, multiple host support, and error handling patterns
- Outline steps for adding new action parameters and keeping documentation up to date
- Clarify version management and the release process for the action

Signed-off-by: appleboy <appleboy.tw@gmail.com>
2025-11-08 10:10:35 +08:00
7 changed files with 386 additions and 24 deletions

View File

@@ -3,7 +3,7 @@ name: Goreleaser
on:
push:
tags:
- "*"
- "v[0-9]+.[0-9]+.[0-9]+"
permissions:
contents: write

51
.github/workflows/trivy-scan.yml vendored Normal file
View File

@@ -0,0 +1,51 @@
name: Trivy Security Scan
on:
schedule:
- cron: '0 0 * * *'
pull_request:
branches:
- master
push:
branches:
- master
workflow_dispatch:
jobs:
trivy-scan:
name: Trivy Security Scan
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
actions: read
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner in repo mode
uses: aquasecurity/trivy-action@0.33.1
with:
scan-type: 'fs'
scan-ref: '.'
scanners: 'vuln,secret,misconfig'
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH,MEDIUM'
- name: Upload Trivy results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: 'trivy-results.sarif'
- name: Run Trivy vulnerability scanner (table format)
uses: aquasecurity/trivy-action@0.33.1
with:
scan-type: 'fs'
scan-ref: '.'
scanners: 'vuln,secret,misconfig'
format: 'table'
severity: 'CRITICAL,HIGH,MEDIUM'
exit-code: '1'

178
CLAUDE.md Normal file
View File

@@ -0,0 +1,178 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
This is a GitHub Action for executing remote SSH commands. Built using a composite action pattern, it downloads and runs the [drone-ssh](https://github.com/appleboy/drone-ssh) binary (written in Go) to execute SSH commands on remote hosts.
**Key characteristics:**
- No local compilation required - downloads pre-built binaries from drone-ssh releases
- Shell-based composite action using `entrypoint.sh`
- Supports password and SSH key authentication, proxies, multiple hosts, and environment variable passing
- All input parameters are passed via `INPUT_*` environment variables
## Architecture
### Execution Flow
1. **action.yml** - GitHub Actions composite action definition
- Defines all input parameters and their descriptions
- Sets up environment variables with `INPUT_*` prefix
- Calls `entrypoint.sh`
2. **entrypoint.sh** - Main entry point
- Detects platform (Linux/Darwin/Windows) and architecture (amd64/arm64)
- Downloads appropriate `drone-ssh` binary from GitHub releases
- Executes the binary with all environment variables
- Handles `capture_stdout` for output capture
3. **drone-ssh binary** - The actual SSH client (separate Go project)
- Performs SSH connection and command execution
- Not part of this repository
### Key Files
- `action.yml` - Action metadata and input/output definitions
- `entrypoint.sh` - Platform detection, binary download, and execution
- `testdata/` - Test scripts and SSH keys for CI workflows
- `.github/workflows/main.yml` - Comprehensive test suite using Docker containers (tests `./` local action)
- `.github/workflows/stable.yml` - Tests against published `appleboy/ssh-action@v1` tag
- `.github/workflows/trivy-scan.yml` - Automated security scanning for vulnerabilities and misconfigurations
## Testing
### Running Tests
Tests run automatically via GitHub Actions workflows. The test suite uses Docker containers running OpenSSH servers:
```bash
# Tests run automatically on push via .github/workflows/main.yml
# Tests create Docker containers with openssh-server and test various scenarios
```
### Test Categories (from main.yml)
The test workflow covers:
- **default-user-name-password**: Basic password authentication
- **check-ssh-key**: RSA key authentication, key priority over password
- **support-key-passphrase**: Encrypted SSH keys
- **multiple-server**: Multiple hosts with different ports
- **support-ed25519-key**: ED25519 key format
- **testing-with-env**: Environment variable passing, `allenvs`, custom formats
- **testing06**: IPv6 connectivity
- **testing07**: Special characters in passwords
- **testing-capturing-output**: Output capture functionality
- **testing-script-stop**: Script error handling with `set -e`
- **testing-script-error**: Error propagation
### Testing Locally
Since this action downloads binaries, local testing should:
1. Create a test SSH server (Docker or VM)
2. Test `entrypoint.sh` directly with appropriate `INPUT_*` environment variables
Example:
```bash
export INPUT_HOST="192.168.1.100"
export INPUT_USERNAME="testuser"
export INPUT_PASSWORD="testpass"
export INPUT_PORT="22"
export INPUT_SCRIPT="whoami"
export GITHUB_ACTION_PATH="$(pwd)"
./entrypoint.sh
```
## Important Patterns
### Script Execution
Users can provide scripts in two ways:
- `script`: Inline commands (via `INPUT_SCRIPT`)
- `script_path`: Path to a file in the repository (maps to `INPUT_SCRIPT_FILE` env var - note the naming difference)
### Error Handling
To stop execution on first error (mimics removed `script_stop` option), users should add `set -e` to their scripts:
```yaml
script: |
#!/usr/bin/env bash
set -e
command1
command2
```
### Environment Variables
The action passes GitHub Action inputs as environment variables with `INPUT_*` prefix. The drone-ssh binary reads these to configure SSH behavior.
Special handling:
- `envs`: Comma-separated list of environment variables to pass to remote script
- `allenvs`: Pass all `GITHUB_*` and `INPUT_*` variables
- `envs_format`: Custom format for environment variable export (e.g., `export TEST_{NAME}={VALUE}`)
### Multiple Hosts
- Comma-separated hosts: `"host1,host2"` (executes in parallel by default)
- With custom ports: `"host1:2222,host2:5678"`
- Synchronous execution: Set `sync: true`
## Common Issues
### Command Not Found
Non-interactive shells may skip `.bashrc`/`.bash_profile`. See README section "Command not found" for details. Solutions:
- Use absolute paths in commands
- Comment out early return in `/etc/bash.bashrc`
### OpenSSH Compatibility
Ubuntu 20.04+ may require enabling `ssh-rsa` algorithm in sshd_config:
```txt
CASignatureAlgorithms +ssh-rsa
```
Or use ED25519 keys instead (preferred).
## Development Guidelines
### Adding New Parameters
1. Add input definition to `action.yml` with description
2. Add corresponding `INPUT_*` environment variable mapping in `action.yml` runs.steps
3. Update README.md parameter tables
4. The drone-ssh binary handles the actual parameter logic (separate repo)
### Documentation
- Keep parameter tables in README.md synchronized with `action.yml`
- Maintain Chinese translations (README.zh-cn.md, README.zh-tw.md)
- Use clear examples for each feature
### Version Management
The action pins to specific drone-ssh versions via:
- Default: `DRONE_SSH_VERSION="1.8.2"` in `entrypoint.sh`
- Override: Users can specify `version` input parameter
Update the default version when new drone-ssh releases are available.
## Release Process
This action uses semantic versioning with major version tags:
- Tags: `v1.0.0`, `v1.0.1`, etc.
- Major version tag: `v1` (points to latest v1.x.x)
- Users reference: `uses: appleboy/ssh-action@v1`
GoReleaser config (`.goreleaser.yaml`) is present but set to `skip: true` since this action doesn't build Go code - it downloads pre-built binaries.

View File

@@ -11,6 +11,7 @@ English | [繁體中文](./README.zh-tw.md) | [简体中文](./README.zh-cn.md)
- [🔌 Connection Settings](#-connection-settings)
- [🛠️ SSH Command Settings](#-ssh-command-settings)
- [🌐 Proxy Settings](#-proxy-settings)
- [📤 Output Variables](#-output-variables)
- [⚡ Quick Start](#-quick-start)
- [🔑 SSH Key Setup \& OpenSSH Compatibility](#-ssh-key-setup--openssh-compatibility)
- [Setting Up SSH Keys](#setting-up-ssh-keys)
@@ -26,6 +27,7 @@ English | [繁體中文](./README.zh-tw.md) | [简体中文](./README.zh-cn.md)
- [Multiple hosts with different ports](#multiple-hosts-with-different-ports)
- [Synchronous execution on multiple hosts](#synchronous-execution-on-multiple-hosts)
- [Pass environment variables to shell script](#pass-environment-variables-to-shell-script)
- [Capturing command output](#capturing-command-output)
- [🌐 Proxy \& Jump Host Usage](#-proxy--jump-host-usage)
- [🛡️ Security Best Practices](#-security-best-practices)
- [Protecting Your Private Key](#protecting-your-private-key)
@@ -46,6 +48,7 @@ Built with [Golang](https://go.dev) and [drone-ssh](https://github.com/appleboy/
![ssh workflow](./images/ssh-workflow.png)
[![testing main branch](https://github.com/appleboy/ssh-action/actions/workflows/main.yml/badge.svg)](https://github.com/appleboy/ssh-action/actions/workflows/main.yml)
[![Trivy Security Scan](https://github.com/appleboy/ssh-action/actions/workflows/trivy-scan.yml/badge.svg)](https://github.com/appleboy/ssh-action/actions/workflows/trivy-scan.yml)
---
@@ -92,6 +95,7 @@ These parameters control the commands executed on the remote host and related be
| debug | Enable debug mode | false |
| request_pty | Request a pseudo-terminal from the server | false |
| curl_insecure | Allow curl to connect to SSL sites without certificates | false |
| capture_stdout | Capture standard output from commands as action output | false |
| version | drone-ssh binary version. If not specified, the latest version will be used. | |
---
@@ -119,6 +123,16 @@ These parameters control the use of a proxy (jump host) for connecting to your t
---
## 📤 Output Variables
This action provides the following outputs that you can use in subsequent steps:
| Output | Description |
| ------ | ----------------------------------------------------------------- |
| stdout | Standard output of the executed commands (requires `capture_stdout: true`) |
---
## ⚡ Quick Start
Run remote SSH commands in your workflow with minimal configuration:
@@ -135,7 +149,7 @@ jobs:
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.HOST }}
username: linuxserver.io
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
port: ${{ secrets.PORT }}
script: whoami
@@ -147,7 +161,7 @@ jobs:
======CMD======
whoami
======END======
linuxserver.io
out: your_username
===============================================
✅ Successfully executed commands to all hosts.
===============================================
@@ -221,7 +235,7 @@ ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publ
On Ubuntu 20.04+ you may need to explicitly allow the `ssh-rsa` algorithm. Add this to your OpenSSH daemon config (`/etc/ssh/sshd_config` or a drop-in under `/etc/ssh/sshd_config.d/`):
```bash
```text
CASignatureAlgorithms +ssh-rsa
```
@@ -365,6 +379,28 @@ Default `port` is `22`.
> _All environment variables in the `env` object must be strings. Using integers or other types may cause unexpected results._
### Capturing command output
You can capture the standard output of remote commands and use it in subsequent steps:
```yaml
- name: Execute and capture output
id: ssh
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
port: ${{ secrets.PORT }}
capture_stdout: true
script: |
echo "Hello World"
hostname
- name: Use captured output
run: echo "SSH output was ${{ steps.ssh.outputs.stdout }}"
```
---
## 🌐 Proxy & Jump Host Usage
@@ -379,7 +415,7 @@ You can connect to remote hosts via a proxy (jump host) for advanced network top
Example `~/.ssh/config`:
```bash
```text
Host Jumphost
HostName Jumphost
User ubuntu

View File

@@ -11,6 +11,7 @@
- [🔌 连接设置](#-连接设置)
- [🛠️ 指令设置](#-指令设置)
- [🌐 代理设置](#-代理设置)
- [📤 输出变量](#-输出变量)
- [⚡ 快速开始](#-快速开始)
- [🔑 SSH 密钥配置与 OpenSSH 兼容性](#-ssh-密钥配置与-openssh-兼容性)
- [配置 SSH 密钥](#配置-ssh-密钥)
@@ -26,6 +27,7 @@
- [多主机不同端口](#多主机不同端口)
- [多主机同步执行](#多主机同步执行)
- [传递环境变量到 shell 脚本](#传递环境变量到-shell-脚本)
- [捕获命令输出](#捕获命令输出)
- [🌐 代理与跳板机用法](#-代理与跳板机用法)
- [🛡️ 安全最佳实践](#-安全最佳实践)
- [保护你的私钥](#保护你的私钥)
@@ -46,6 +48,7 @@
![ssh workflow](./images/ssh-workflow.png)
[![testing main branch](https://github.com/appleboy/ssh-action/actions/workflows/main.yml/badge.svg)](https://github.com/appleboy/ssh-action/actions/workflows/main.yml)
[![Trivy Security Scan](https://github.com/appleboy/ssh-action/actions/workflows/trivy-scan.yml/badge.svg)](https://github.com/appleboy/ssh-action/actions/workflows/trivy-scan.yml)
---
@@ -92,6 +95,7 @@
| debug | 启用调试模式 | false |
| request_pty | 向服务器请求伪终端 | false |
| curl_insecure | 允许 curl 连接无证书的 SSL 站点 | false |
| capture_stdout | 捕获命令的标准输出作为 Action 输出 | false |
| version | drone-ssh 二进制版本,未指定时使用最新版本 | |
---
@@ -119,6 +123,16 @@
---
## 📤 输出变量
本 Action 提供以下输出,可在后续步骤中使用:
| 输出 | 描述 |
| ------ | ----------------------------------------------------- |
| stdout | 执行命令的标准输出(需设置 `capture_stdout: true` |
---
## ⚡ 快速开始
只需简单配置,即可在工作流中执行远程 SSH 命令:
@@ -135,7 +149,7 @@ jobs:
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.HOST }}
username: linuxserver.io
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
port: ${{ secrets.PORT }}
script: whoami
@@ -147,7 +161,7 @@ jobs:
======CMD======
whoami
======END======
linuxserver.io
out: your_username
===============================================
✅ Successfully executed commands to all hosts.
===============================================
@@ -221,7 +235,7 @@ ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publ
在 Ubuntu 20.04+,你可能需要显式允许 `ssh-rsa` 算法。请在 OpenSSH 配置文件(`/etc/ssh/sshd_config``/etc/ssh/sshd_config.d/` 下的 drop-in 文件)中添加:
```bash
```text
CASignatureAlgorithms +ssh-rsa
```
@@ -365,6 +379,28 @@ ssh-keygen -t ed25519 -a 200 -C "your_email@example.com"
> _`env` 对象中的所有环境变量必须为字符串。传递整数或其他类型可能导致意外结果。_
### 捕获命令输出
你可以捕获远程命令的标准输出,并在后续步骤中使用:
```yaml
- name: 执行并捕获输出
id: ssh
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
port: ${{ secrets.PORT }}
capture_stdout: true
script: |
echo "Hello World"
hostname
- name: 使用捕获的输出
run: echo "SSH 输出为 ${{ steps.ssh.outputs.stdout }}"
```
---
## 🌐 代理与跳板机用法
@@ -379,7 +415,7 @@ ssh-keygen -t ed25519 -a 200 -C "your_email@example.com"
示例 `~/.ssh/config`
```bash
```text
Host Jumphost
HostName Jumphost
User ubuntu

View File

@@ -11,6 +11,7 @@
- [🔌 連線設定](#-連線設定)
- [🛠️ 指令設定](#-指令設定)
- [🌐 代理設定](#-代理設定)
- [📤 輸出變數](#-輸出變數)
- [⚡ 快速開始](#-快速開始)
- [🔑 SSH 金鑰設定與 OpenSSH 相容性](#-ssh-金鑰設定與-openssh-相容性)
- [設定 SSH 金鑰](#設定-ssh-金鑰)
@@ -26,6 +27,7 @@
- [多主機不同埠號](#多主機不同埠號)
- [多主機同步執行](#多主機同步執行)
- [傳遞環境變數到 shell 腳本](#傳遞環境變數到-shell-腳本)
- [擷取指令輸出](#擷取指令輸出)
- [🌐 代理與跳板機用法](#-代理與跳板機用法)
- [🛡️ 安全最佳實踐](#-安全最佳實踐)
- [保護你的私鑰](#保護你的私鑰)
@@ -46,6 +48,7 @@
![ssh workflow](./images/ssh-workflow.png)
[![testing main branch](https://github.com/appleboy/ssh-action/actions/workflows/main.yml/badge.svg)](https://github.com/appleboy/ssh-action/actions/workflows/main.yml)
[![Trivy Security Scan](https://github.com/appleboy/ssh-action/actions/workflows/trivy-scan.yml/badge.svg)](https://github.com/appleboy/ssh-action/actions/workflows/trivy-scan.yml)
---
@@ -92,6 +95,7 @@
| debug | 啟用除錯模式 | false |
| request_pty | 向伺服器請求偽終端 | false |
| curl_insecure | 允許 curl 連線無憑證的 SSL 網站 | false |
| capture_stdout | 擷取指令的標準輸出作為 Action 輸出 | false |
| version | drone-ssh 執行檔版本,未指定時使用最新版本 | |
---
@@ -119,6 +123,16 @@
---
## 📤 輸出變數
本 Action 提供以下輸出,可在後續步驟中使用:
| 輸出 | 說明 |
| ------ | ----------------------------------------------------- |
| stdout | 執行指令的標準輸出(需設定 `capture_stdout: true` |
---
## ⚡ 快速開始
只需簡單設定,即可在工作流程中執行遠端 SSH 指令:
@@ -135,7 +149,7 @@ jobs:
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.HOST }}
username: linuxserver.io
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
port: ${{ secrets.PORT }}
script: whoami
@@ -147,7 +161,7 @@ jobs:
======CMD======
whoami
======END======
linuxserver.io
out: your_username
===============================================
✅ Successfully executed commands to all hosts.
===============================================
@@ -221,7 +235,7 @@ ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publ
在 Ubuntu 20.04+,你可能需明確允許 `ssh-rsa` 演算法。請於 OpenSSH 設定檔(`/etc/ssh/sshd_config``/etc/ssh/sshd_config.d/` 下的 drop-in 檔案)加入:
```bash
```text
CASignatureAlgorithms +ssh-rsa
```
@@ -365,6 +379,28 @@ ssh-keygen -t ed25519 -a 200 -C "your_email@example.com"
> _`env` 物件中的所有環境變數必須為字串。傳遞整數或其他型別可能導致非預期結果。_
### 擷取指令輸出
你可以擷取遠端指令的標準輸出,並在後續步驟中使用:
```yaml
- name: 執行並擷取輸出
id: ssh
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
port: ${{ secrets.PORT }}
capture_stdout: true
script: |
echo "Hello World"
hostname
- name: 使用擷取的輸出
run: echo "SSH 輸出為 ${{ steps.ssh.outputs.stdout }}"
```
---
## 🌐 代理與跳板機用法
@@ -379,7 +415,7 @@ ssh-keygen -t ed25519 -a 200 -C "your_email@example.com"
範例 `~/.ssh/config`
```bash
```text
Host Jumphost
HostName Jumphost
User ubuntu

View File

@@ -6,7 +6,14 @@ export GITHUB="true"
GITHUB_ACTION_PATH="${GITHUB_ACTION_PATH%/}"
DRONE_SSH_RELEASE_URL="${DRONE_SSH_RELEASE_URL:-https://github.com/appleboy/drone-ssh/releases/download}"
DRONE_SSH_VERSION="${DRONE_SSH_VERSION:-1.8.1}"
DRONE_SSH_VERSION="${DRONE_SSH_VERSION:-1.8.2}"
# Error codes
readonly ERR_UNKNOWN_PLATFORM=2
readonly ERR_UNKNOWN_ARCH=3
readonly ERR_DOWNLOAD_FAILED=4
readonly ERR_INVALID_BINARY=5
readonly ERR_VERSION_CHECK_FAILED=6
function log_error() {
echo "$1" >&2
@@ -19,13 +26,13 @@ function detect_client_info() {
case "${CLIENT_PLATFORM}" in
darwin | linux | windows) ;;
*) log_error "Unknown or unsupported platform: ${CLIENT_PLATFORM}. Supported platforms are Linux, Darwin, and Windows." 2 ;;
*) log_error "Unknown or unsupported platform: ${CLIENT_PLATFORM}. Supported platforms are Linux, Darwin, and Windows." "${ERR_UNKNOWN_PLATFORM}" ;;
esac
case "${CLIENT_ARCH}" in
x86_64* | i?86_64* | amd64*) CLIENT_ARCH="amd64" ;;
aarch64* | arm64*) CLIENT_ARCH="arm64" ;;
*) log_error "Unknown or unsupported architecture: ${CLIENT_ARCH}. Supported architectures are x86_64, i686, and arm64." 3 ;;
*) log_error "Unknown or unsupported architecture: ${CLIENT_ARCH}. Supported architectures are x86_64, i686, and arm64." "${ERR_UNKNOWN_ARCH}" ;;
esac
}
@@ -33,17 +40,35 @@ detect_client_info
DOWNLOAD_URL_PREFIX="${DRONE_SSH_RELEASE_URL}/v${DRONE_SSH_VERSION}"
CLIENT_BINARY="drone-ssh-${DRONE_SSH_VERSION}-${CLIENT_PLATFORM}-${CLIENT_ARCH}"
TARGET="${GITHUB_ACTION_PATH}/${CLIENT_BINARY}"
echo "Downloading ${CLIENT_BINARY} from ${DOWNLOAD_URL_PREFIX}"
INSECURE_OPTION=""
if [[ "${INPUT_CURL_INSECURE}" == 'true' ]]; then
# Check if binary already exists and is executable (caching)
if [[ -f "${TARGET}" ]] && [[ -x "${TARGET}" ]]; then
echo "Binary ${CLIENT_BINARY} already exists, skipping download"
else
echo "Downloading ${CLIENT_BINARY} from ${DOWNLOAD_URL_PREFIX}"
INSECURE_OPTION=""
if [[ "${INPUT_CURL_INSECURE}" == 'true' ]]; then
INSECURE_OPTION="--insecure"
fi
# Download with better error handling
if ! curl -fsSL --retry 5 --keepalive-time 2 --location ${INSECURE_OPTION} \
"${DOWNLOAD_URL_PREFIX}/${CLIENT_BINARY}" -o "${TARGET}"; then
log_error "Failed to download ${CLIENT_BINARY} from ${DOWNLOAD_URL_PREFIX}. Please check the URL and your network connection." "${ERR_DOWNLOAD_FAILED}"
fi
# Validate downloaded file
if [[ ! -f "${TARGET}" ]] || [[ ! -s "${TARGET}" ]]; then
log_error "Downloaded file is missing or empty: ${TARGET}" "${ERR_INVALID_BINARY}"
fi
chmod +x "${TARGET}"
fi
curl -fsSL --retry 5 --keepalive-time 2 ${INSECURE_OPTION} "${DOWNLOAD_URL_PREFIX}/${CLIENT_BINARY}" -o "${TARGET}"
chmod +x "${TARGET}"
echo "======= CLI Version Information ======="
"${TARGET}" --version
if ! "${TARGET}" --version; then
log_error "Failed to execute ${TARGET} --version. The binary may be corrupted." "${ERR_VERSION_CHECK_FAILED}"
fi
echo "======================================="
if [[ "${INPUT_CAPTURE_STDOUT}" == 'true' ]]; then
{