Compare commits
92 Commits
v0.0.5
...
bf323b8729
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf323b8729 | ||
|
|
e55e4eabdc | ||
|
|
bc835cba55 | ||
|
|
98b7132065 | ||
|
|
3d59448764 | ||
|
|
2a829c0ed2 | ||
|
|
4f2c27bbc2 | ||
|
|
b03d7257ae | ||
|
|
f042d742db | ||
|
|
ad9a378b7f | ||
|
|
172d4632fe | ||
|
|
93e17a47f9 | ||
|
|
c6ff96b7f6 | ||
|
|
7622c01418 | ||
|
|
9ba62064d2 | ||
|
|
f314a5399e | ||
|
|
699fa1181c | ||
|
|
9f34cc3e55 | ||
|
|
917f8b81df | ||
|
|
78e7f475f3 | ||
|
|
dfde1f50eb | ||
|
|
35093a99f9 | ||
|
|
96947ea2bd | ||
|
|
aef31a66e3 | ||
|
|
950981a11d | ||
|
|
5878fc908f | ||
|
|
abb6d70bee | ||
|
|
b03ad1c124 | ||
|
|
d398e64fcf | ||
|
|
3710327b67 | ||
|
|
d47d818ab7 | ||
|
|
7435be3541 | ||
|
|
11da0c97f9 | ||
|
|
ec73feb854 | ||
|
|
cdeb36bbf9 | ||
|
|
c209399d24 | ||
|
|
952a6e3250 | ||
|
|
82ebdbe3ed | ||
|
|
2cd029d317 | ||
|
|
e0dbae8ff0 | ||
|
|
3e84ad0651 | ||
|
|
8a92fcdb1e | ||
|
|
6cd4f0cace | ||
|
|
43abfa778d | ||
|
|
c8e0cef94a | ||
|
|
d47875703f | ||
|
|
a4e63f0f1a | ||
|
|
7cc0f645c7 | ||
|
|
dcb457bb6f | ||
|
|
11c56b52d3 | ||
|
|
51b937b31f | ||
|
|
98930d398c | ||
|
|
9ec0623f29 | ||
|
|
7f8a7c1019 | ||
|
|
2ce642f289 | ||
|
|
6291b9e86b | ||
|
|
6d1fc191a8 | ||
|
|
233f762873 | ||
|
|
b3f8d37ead | ||
|
|
f57f59fba9 | ||
|
|
8a54b39459 | ||
|
|
eb319b796f | ||
|
|
3c3575eb49 | ||
|
|
edc8ec9139 | ||
|
|
167d6d7ff4 | ||
|
|
ecd6a3623b | ||
|
|
31b514c281 | ||
|
|
5924b2b6d4 | ||
|
|
a2fea1040d | ||
|
|
8535291767 | ||
|
|
faff4f4218 | ||
|
|
ddd9176502 | ||
|
|
326e14ddd1 | ||
|
|
0329cffdaa | ||
|
|
6df9245376 | ||
|
|
4df1959b05 | ||
|
|
1c43a9662a | ||
|
|
2949c755a2 | ||
|
|
aefa39daef | ||
|
|
2305e4000a | ||
|
|
c51573a06a | ||
|
|
d068cd7f84 | ||
|
|
8ba3cfe760 | ||
|
|
1a6b426141 | ||
|
|
8b3eebcc8d | ||
|
|
861f2e0e7b | ||
|
|
6971270956 | ||
|
|
bac6c9e026 | ||
|
|
b04405242e | ||
|
|
5cb36bda99 | ||
|
|
6c5771fab8 | ||
|
|
193fd4eaa9 |
13
.github/FUNDING.yml
vendored
Normal file
13
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||||
|
patreon: # Replace with a single Patreon username
|
||||||
|
open_collective: # Replace with a single Open Collective username
|
||||||
|
ko_fi: # Replace with a single Ko-fi username
|
||||||
|
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||||
|
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||||
|
liberapay: # Replace with a single Liberapay username
|
||||||
|
issuehunt: # Replace with a single IssueHunt username
|
||||||
|
otechie: # Replace with a single Otechie username
|
||||||
|
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||||
|
custom: ['https://www.paypal.me/appleboy46']
|
||||||
10
.github/dependabot.yml
vendored
Normal file
10
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: github-actions
|
||||||
|
directory: /
|
||||||
|
schedule:
|
||||||
|
interval: weekly
|
||||||
|
- package-ecosystem: gomod
|
||||||
|
directory: /
|
||||||
|
schedule:
|
||||||
|
interval: weekly
|
||||||
175
.github/workflows/ci.yml
vendored
175
.github/workflows/ci.yml
vendored
@@ -1,39 +1,150 @@
|
|||||||
name: scp files
|
name: scp files
|
||||||
on: [push]
|
on: [push]
|
||||||
jobs:
|
jobs:
|
||||||
|
testing:
|
||||||
build:
|
name: test scp action
|
||||||
name: Build
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- name: checkout
|
||||||
- name: copy file via ssh password
|
uses: actions/checkout@v4
|
||||||
uses: appleboy/scp-action@master
|
|
||||||
with:
|
|
||||||
host: ${{ secrets.HOST }}
|
|
||||||
username: ${{ secrets.USERNAME }}
|
|
||||||
password: ${{ secrets.PASSWORD }}
|
|
||||||
port: ${{ secrets.PORT }}
|
|
||||||
source: "tests/a.txt,tests/b.txt"
|
|
||||||
target: "test"
|
|
||||||
|
|
||||||
- name: copy file via ssh key
|
- name: copy file via ssh password
|
||||||
uses: appleboy/scp-action@master
|
uses: ./
|
||||||
with:
|
with:
|
||||||
host: ${{ secrets.HOST }}
|
host: ${{ secrets.HOST }}
|
||||||
username: ${{ secrets.USERNAME }}
|
username: ${{ secrets.USERNAME }}
|
||||||
key: ${{ secrets.KEY }}
|
password: ${{ secrets.PASSWORD }}
|
||||||
port: ${{ secrets.PORT }}
|
port: ${{ secrets.PORT }}
|
||||||
source: "tests/a.txt,tests/b.txt"
|
source: "tests/a.txt,tests/b.txt"
|
||||||
target: "test"
|
target: "test"
|
||||||
|
|
||||||
- name: remove the specified number of leading path elements
|
- name: copy file via ssh key
|
||||||
uses: appleboy/scp-action@master
|
uses: ./
|
||||||
with:
|
with:
|
||||||
host: ${{ secrets.HOST }}
|
host: ${{ secrets.HOST }}
|
||||||
username: ${{ secrets.USERNAME }}
|
username: ${{ secrets.USERNAME }}
|
||||||
key: ${{ secrets.KEY }}
|
key: ${{ secrets.KEY }}
|
||||||
port: ${{ secrets.PORT }}
|
port: ${{ secrets.PORT }}
|
||||||
source: "tests/a.txt,tests/b.txt"
|
source: "tests/a.txt,tests/b.txt"
|
||||||
target: "foobar"
|
target: "test"
|
||||||
strip_components: 1
|
|
||||||
|
- name: remove the specified number of leading path elements
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.HOST }}
|
||||||
|
username: ${{ secrets.USERNAME }}
|
||||||
|
key: ${{ secrets.KEY }}
|
||||||
|
port: ${{ secrets.PORT }}
|
||||||
|
source: "tests/a.txt,tests/b.txt"
|
||||||
|
target: "foobar"
|
||||||
|
strip_components: 1
|
||||||
|
|
||||||
|
- name: ssh key with passphrase
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.HOST }}
|
||||||
|
username: ${{ secrets.USERNAME }}
|
||||||
|
key: ${{ secrets.SSH2 }}
|
||||||
|
passphrase: ${{ secrets.PASSPHRASE }}
|
||||||
|
port: ${{ secrets.PORT }}
|
||||||
|
source: "tests/a.txt,tests/b.txt"
|
||||||
|
target: "test"
|
||||||
|
|
||||||
|
- name: use insecure cipher
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.HOST }}
|
||||||
|
username: ${{ secrets.USERNAME }}
|
||||||
|
key: ${{ secrets.SSH2 }}
|
||||||
|
passphrase: ${{ secrets.PASSPHRASE }}
|
||||||
|
port: ${{ secrets.PORT }}
|
||||||
|
source: "tests/a.txt,tests/b.txt"
|
||||||
|
target: "test"
|
||||||
|
use_insecure_cipher: true
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
name: test deploy artifact
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- run: echo hello > world.txt
|
||||||
|
|
||||||
|
- 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 file to server
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.HOST }}
|
||||||
|
username: ${{ secrets.USERNAME }}
|
||||||
|
key: ${{ secrets.KEY }}
|
||||||
|
port: ${{ secrets.PORT }}
|
||||||
|
source: distfiles/*
|
||||||
|
target: test
|
||||||
|
|
||||||
|
changes:
|
||||||
|
name: test changed-files
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Get changed files
|
||||||
|
id: changed-files
|
||||||
|
uses: tj-actions/changed-files@v45
|
||||||
|
with:
|
||||||
|
since_last_remote_commit: true
|
||||||
|
separator: ","
|
||||||
|
|
||||||
|
- name: copy file to server
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.HOST }}
|
||||||
|
username: ${{ secrets.USERNAME }}
|
||||||
|
key: ${{ secrets.KEY }}
|
||||||
|
port: ${{ secrets.PORT }}
|
||||||
|
source: ${{ steps.changed-files.outputs.all_changed_files }}
|
||||||
|
target: test
|
||||||
|
|
||||||
|
target:
|
||||||
|
name: test target folder
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: copy file to server
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.HOST }}
|
||||||
|
username: ${{ secrets.USERNAME }}
|
||||||
|
key: ${{ secrets.KEY }}
|
||||||
|
port: ${{ secrets.PORT }}
|
||||||
|
source: tests/a.txt,tests/b.txt
|
||||||
|
target: foobar foobar 1234
|
||||||
|
|
||||||
|
multipleHost:
|
||||||
|
name: test Multiple Host
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: copy file to server
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.HOST }}:${{ secrets.PORT }},${{ secrets.HOST }}:${{ secrets.PORT }}
|
||||||
|
username: ${{ secrets.USERNAME }}
|
||||||
|
key: ${{ secrets.KEY }}
|
||||||
|
port: 1024
|
||||||
|
source: tests/a.txt,tests/b.txt
|
||||||
|
target: foobar
|
||||||
|
|||||||
33
.github/workflows/goreleaser.yml
vendored
Normal file
33
.github/workflows/goreleaser.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
name: Goreleaser
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "*"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
goreleaser:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Setup go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: "^1"
|
||||||
|
|
||||||
|
- name: Run GoReleaser
|
||||||
|
uses: goreleaser/goreleaser-action@v6
|
||||||
|
with:
|
||||||
|
# either 'goreleaser' (default) or 'goreleaser-pro'
|
||||||
|
distribution: goreleaser
|
||||||
|
version: latest
|
||||||
|
args: release --clean
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
28
.goreleaser.yaml
Normal file
28
.goreleaser.yaml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
builds:
|
||||||
|
- # If true, skip the build.
|
||||||
|
# Useful for library projects.
|
||||||
|
# Default is false
|
||||||
|
skip: true
|
||||||
|
|
||||||
|
changelog:
|
||||||
|
use: github
|
||||||
|
groups:
|
||||||
|
- title: Features
|
||||||
|
regexp: "^.*feat[(\\w)]*:+.*$"
|
||||||
|
order: 0
|
||||||
|
- title: "Bug fixes"
|
||||||
|
regexp: "^.*fix[(\\w)]*:+.*$"
|
||||||
|
order: 1
|
||||||
|
- title: "Enhancements"
|
||||||
|
regexp: "^.*chore[(\\w)]*:+.*$"
|
||||||
|
order: 2
|
||||||
|
- title: "Refactor"
|
||||||
|
regexp: "^.*refactor[(\\w)]*:+.*$"
|
||||||
|
order: 3
|
||||||
|
- title: "Build process updates"
|
||||||
|
regexp: ^.*?(build|ci)(\(.+\))??!?:.+$
|
||||||
|
order: 4
|
||||||
|
- title: "Documentation updates"
|
||||||
|
regexp: ^.*?docs?(\(.+\))??!?:.+$
|
||||||
|
order: 4
|
||||||
|
- title: Others
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
FROM appleboy/drone-scp:1.5.4-linux-amd64
|
|
||||||
|
|
||||||
ADD entrypoint.sh /entrypoint.sh
|
|
||||||
RUN chmod +x /entrypoint.sh
|
|
||||||
ENTRYPOINT ["/entrypoint.sh"]
|
|
||||||
378
README.md
378
README.md
@@ -2,142 +2,344 @@
|
|||||||
|
|
||||||
[GitHub Action](https://github.com/features/actions) for copying files and artifacts via SSH.
|
[GitHub Action](https://github.com/features/actions) for copying files and artifacts via SSH.
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
[](https://github.com/appleboy/scp-action/actions)
|
[](https://github.com/appleboy/scp-action/actions)
|
||||||
|
|
||||||
## Usage
|
> **Note:** Only supports **Linux** [docker](https://www.docker.com/) containers.
|
||||||
|
|
||||||
copy files and artifacts via SSH as blow.
|
---
|
||||||
|
|
||||||
|
## ✨ Features
|
||||||
|
|
||||||
|
- ✅ Copy files and artifacts to one or multiple remote servers via SSH
|
||||||
|
- ✅ Supports both SSH key and password authentication
|
||||||
|
- ✅ Full SSH Proxy (jump host) support
|
||||||
|
- ✅ Handles Linux ↔ Windows path conversion
|
||||||
|
- ✅ Integrates with GitHub Artifacts workflow
|
||||||
|
- ✅ Incremental and differential file transfer
|
||||||
|
- ✅ Rich configuration options for advanced use cases
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📦 Table of Contents
|
||||||
|
|
||||||
|
- [🚀 SCP for GitHub Actions](#-scp-for-github-actions)
|
||||||
|
- [✨ Features](#-features)
|
||||||
|
- [📦 Table of Contents](#-table-of-contents)
|
||||||
|
- [🚀 Quick Start](#-quick-start)
|
||||||
|
- [⚙️ Configuration](#️-configuration)
|
||||||
|
- [🔌 Connection Settings](#-connection-settings)
|
||||||
|
- [📁 File Transfer Settings](#-file-transfer-settings)
|
||||||
|
- [🌐 Proxy Settings](#-proxy-settings)
|
||||||
|
- [🛡️ Best Practices \& Security](#️-best-practices--security)
|
||||||
|
- [🖥️ Cross-Platform Notes](#️-cross-platform-notes)
|
||||||
|
- [💡 Usage Examples](#-usage-examples)
|
||||||
|
- [🧩 Scenario Guide](#-scenario-guide)
|
||||||
|
- [Example 1: Basic SSH Password](#example-1-basic-ssh-password)
|
||||||
|
- [Example 2: Multi-server](#example-2-multi-server)
|
||||||
|
- [Example 3: Changed Files Only](#example-3-changed-files-only)
|
||||||
|
- [Example 4: Artifacts Integration](#example-4-artifacts-integration)
|
||||||
|
- [Example 5: Windows Server](#example-5-windows-server)
|
||||||
|
- [🗝️ SSH Key Setup](#️-ssh-key-setup)
|
||||||
|
- [🧰 Common Error Codes](#-common-error-codes)
|
||||||
|
- [🔄 Workflow Diagram](#-workflow-diagram)
|
||||||
|
- [FAQ \& Troubleshooting](#faq--troubleshooting)
|
||||||
|
- [📝 License](#-license)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Quick Start
|
||||||
|
|
||||||
|
Copy files and artifacts via SSH in your GitHub Actions workflow:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
name: scp files
|
name: scp files
|
||||||
on: [push]
|
on: [push]
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
build:
|
build:
|
||||||
name: Build
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@v4
|
||||||
- name: copy file via ssh password
|
- name: Copy files via SSH
|
||||||
uses: appleboy/scp-action@master
|
uses: appleboy/scp-action@v0.1.7
|
||||||
with:
|
with:
|
||||||
host: ${{ secrets.HOST }}
|
host: ${{ secrets.HOST }}
|
||||||
username: ${{ secrets.USERNAME }}
|
username: ${{ secrets.USERNAME }}
|
||||||
password: ${{ secrets.PASSWORD }}
|
password: ${{ secrets.PASSWORD }}
|
||||||
port: ${{ secrets.PORT }}
|
port: ${{ secrets.PORT }}
|
||||||
source: "tests/a.txt,tests/b.txt"
|
source: "tests/a.txt,tests/b.txt"
|
||||||
target: "test"
|
target: your_server_target_folder_path
|
||||||
```
|
```
|
||||||
|
|
||||||
## Input variables
|
---
|
||||||
|
|
||||||
see the [action.yml](./action.yml) file for more detail imformation.
|
## ⚙️ Configuration
|
||||||
|
|
||||||
* host - scp remote host
|
### 🔌 Connection Settings
|
||||||
* port - scp remote port, default is `22`
|
|
||||||
* username - scp username
|
|
||||||
* password - scp password
|
|
||||||
* timeout - timeout for ssh to remote host, default is `30s`
|
|
||||||
* command_timeout - timeout for scp command, default is `10m`
|
|
||||||
* key - content of ssh private key. ex raw content of ~/.ssh/id_rsa
|
|
||||||
* key_path - path of ssh private key
|
|
||||||
* target - target path on the server
|
|
||||||
* source - scp file list
|
|
||||||
* rm - remove target folder before upload data
|
|
||||||
* strip_components - remove the specified number of leading path elements.
|
|
||||||
* overwrite - use `--overwrite` flag with tar
|
|
||||||
* tar_tmp_path - temporary path for tar file on the dest host
|
|
||||||
|
|
||||||
### Example
|
| 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 | |
|
||||||
|
|
||||||
Copy file via ssh password
|
### 📁 File Transfer Settings
|
||||||
|
|
||||||
|
| 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 | - | |
|
||||||
|
|
||||||
|
### 🌐 Proxy Settings
|
||||||
|
|
||||||
|
| 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 | |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛡️ Best Practices & Security
|
||||||
|
|
||||||
|
- **Prefer SSH key authentication** over passwords for better security.
|
||||||
|
- Store all sensitive values (host, username, password, key) in **GitHub Secrets**.
|
||||||
|
- Regularly **rotate deployment keys** (suggested every 90 days).
|
||||||
|
- Restrict write permissions on the target server directory.
|
||||||
|
- Enable host key fingerprint verification to prevent MITM attacks.
|
||||||
|
- Avoid using root as the SSH user.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🖥️ Cross-Platform Notes
|
||||||
|
|
||||||
|
| 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_dereference` for symlink handling
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💡 Usage Examples
|
||||||
|
|
||||||
|
### 🧩 Scenario Guide
|
||||||
|
|
||||||
|
- **Basic file transfer** → [Example 1](#example-1-basic-ssh-password)
|
||||||
|
- **Multi-server deployment** → [Example 2](#example-2-multi-server)
|
||||||
|
- **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)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Example 1: Basic SSH Password
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: copy file via ssh password
|
- name: Copy file via SSH password
|
||||||
uses: appleboy/scp-action@master
|
uses: appleboy/scp-action@v0.1.7
|
||||||
with:
|
with:
|
||||||
host: example.com
|
host: example.com
|
||||||
username: foo
|
username: foo
|
||||||
password: bar
|
password: bar
|
||||||
port: 22
|
port: 22
|
||||||
source: "tests/a.txt,tests/b.txt"
|
source: "tests/a.txt,tests/b.txt"
|
||||||
target: "test"
|
target: your_server_target_folder_path
|
||||||
```
|
```
|
||||||
|
|
||||||
Copy file via ssh key
|
#### Example 2: Multi-server
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: copy file via ssh key
|
- name: Copy to multiple servers
|
||||||
uses: appleboy/scp-action@master
|
uses: appleboy/scp-action@v0.1.7
|
||||||
env:
|
|
||||||
HOST: ${{ secrets.HOST }}
|
|
||||||
USERNAME: ${{ secrets.USERNAME }}
|
|
||||||
PORT: ${{ secrets.PORT }}
|
|
||||||
KEY: ${{ secrets.KEY }}
|
|
||||||
with:
|
with:
|
||||||
source: "tests/a.txt,tests/b.txt"
|
host: "foo.com,bar.com"
|
||||||
target: "test"
|
|
||||||
```
|
|
||||||
|
|
||||||
Example configuration for ignore list:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- name: copy file via ssh key
|
|
||||||
uses: appleboy/scp-action@master
|
|
||||||
env:
|
|
||||||
HOST: ${{ secrets.HOST }}
|
|
||||||
USERNAME: ${{ secrets.USERNAME }}
|
|
||||||
PORT: ${{ secrets.PORT }}
|
|
||||||
KEY: ${{ secrets.KEY }}
|
|
||||||
with:
|
|
||||||
source: "tests/*.txt,!tests/a.txt"
|
|
||||||
target: "test"
|
|
||||||
```
|
|
||||||
|
|
||||||
Example configuration for multiple server
|
|
||||||
|
|
||||||
```diff
|
|
||||||
uses: appleboy/scp-action@master
|
|
||||||
with:
|
|
||||||
- host: "example.com"
|
|
||||||
+ host: "foo.com,bar.com"
|
|
||||||
username: foo
|
username: foo
|
||||||
password: bar
|
password: bar
|
||||||
port: 22
|
port: 22
|
||||||
source: "tests/a.txt,tests/b.txt"
|
source: "tests/a.txt,tests/b.txt"
|
||||||
target: "test"
|
target: your_server_target_folder_path
|
||||||
```
|
```
|
||||||
|
|
||||||
remove the specified number of leading path elements
|
#### Example 3: Changed Files Only
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: remove the specified number of leading path elements
|
- name: Get changed files
|
||||||
uses: appleboy/scp-action@master
|
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@v0.1.7
|
||||||
with:
|
with:
|
||||||
host: ${{ secrets.HOST }}
|
host: ${{ secrets.HOST }}
|
||||||
username: ${{ secrets.USERNAME }}
|
username: ${{ secrets.USERNAME }}
|
||||||
key: ${{ secrets.KEY }}
|
key: ${{ secrets.KEY }}
|
||||||
port: ${{ secrets.PORT }}
|
port: ${{ secrets.PORT }}
|
||||||
source: "tests/a.txt,tests/b.txt"
|
source: ${{ steps.changed-files.outputs.all_changed_files }}
|
||||||
target: "foobar"
|
target: your_server_target_folder_path
|
||||||
strip_components: 1
|
|
||||||
```
|
```
|
||||||
|
|
||||||
old target structure:
|
#### Example 4: Artifacts Integration
|
||||||
|
|
||||||
|
```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: Copy artifact to server
|
||||||
|
uses: appleboy/scp-action@v0.1.7
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.HOST }}
|
||||||
|
username: ${{ secrets.USERNAME }}
|
||||||
|
key: ${{ secrets.KEY }}
|
||||||
|
port: ${{ secrets.PORT }}
|
||||||
|
source: distfiles/*
|
||||||
|
target: your_server_target_folder_path
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Example 5: Windows Server
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Copy to Windows
|
||||||
|
uses: appleboy/scp-action@v0.1.7
|
||||||
|
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 Key Setup
|
||||||
|
|
||||||
|
1. **Generate SSH Key** (on your local machine):
|
||||||
|
|
||||||
|
```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. **Add Public Key to Server**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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'
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Copy Private Key Content to GitHub Secrets**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
clip < ~/.ssh/id_rsa
|
||||||
|
# or
|
||||||
|
clip < ~/.ssh/id_ed25519
|
||||||
|
```
|
||||||
|
|
||||||
|
> See [SSH login without password](http://www.linuxproblem.org/art_9.html) 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/`:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
foobar
|
CASignatureAlgorithms +ssh-rsa
|
||||||
└── tests
|
|
||||||
├── a.txt
|
|
||||||
└── b.txt
|
|
||||||
```
|
```
|
||||||
|
|
||||||
new target structure:
|
Or use ed25519 keys, which are accepted by default.
|
||||||
|
|
||||||
```sh
|
---
|
||||||
foobar
|
|
||||||
├── a.txt
|
## 🧰 Common Error Codes
|
||||||
└── b.txt
|
|
||||||
|
| 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) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔄 Workflow Diagram
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
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
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## FAQ & Troubleshooting
|
||||||
|
|
||||||
|
- **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`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 License
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|||||||
146
action.yml
146
action.yml
@@ -1,44 +1,142 @@
|
|||||||
name: 'SCP Command to Transfer Files'
|
name: "SCP Command to Transfer Files"
|
||||||
description: 'How to Use SCP Command to Transfer Files/Folders in Linux'
|
description: "Easily transfer files and folders using the SCP command in Linux."
|
||||||
author: 'Bo-Yi Wu'
|
author: "Bo-Yi Wu"
|
||||||
inputs:
|
inputs:
|
||||||
host:
|
host:
|
||||||
description: 'scp remote host'
|
description: "Remote host address for SCP (e.g., example.com or 192.168.1.1)."
|
||||||
port:
|
port:
|
||||||
description: 'scp remote port'
|
description: "Remote SSH port for SCP. Default: 22."
|
||||||
default: 22
|
default: "22"
|
||||||
username:
|
username:
|
||||||
description: 'scp username'
|
description: "Username for SSH authentication."
|
||||||
password:
|
password:
|
||||||
description: 'scp password'
|
description: "Password for SSH authentication (not recommended; use SSH keys if possible)."
|
||||||
|
protocol:
|
||||||
|
description: "IP protocol to use. Valid values: 'tcp', 'tcp4', or 'tcp6'. Default: tcp."
|
||||||
|
default: "tcp"
|
||||||
timeout:
|
timeout:
|
||||||
description: 'timeout for ssh to remote host'
|
description: "Timeout for establishing SSH connection to the remote host. Default: 30s."
|
||||||
default: "30s"
|
default: "30s"
|
||||||
command_timeout:
|
command_timeout:
|
||||||
description: 'timeout for scp command'
|
description: "Timeout for the SCP command execution. Default: 10m."
|
||||||
default: "10m"
|
default: "10m"
|
||||||
key:
|
key:
|
||||||
description: 'content of ssh private key. ex raw content of ~/.ssh/id_rsa'
|
description: "Content of the SSH private key (e.g., the raw content of ~/.ssh/id_rsa)."
|
||||||
key_path:
|
key_path:
|
||||||
description: 'path of ssh private key'
|
description: "Path to the SSH private key file."
|
||||||
|
passphrase:
|
||||||
|
description: "Passphrase for the SSH private key, if required."
|
||||||
|
fingerprint:
|
||||||
|
description: "SHA256 fingerprint of the host's public key. If not set, host key verification is skipped (not recommended for production)."
|
||||||
|
use_insecure_cipher:
|
||||||
|
description: "Enable additional, less secure ciphers for compatibility. Not recommended unless required."
|
||||||
target:
|
target:
|
||||||
description: 'target path on the server'
|
description: "Target directory path on the remote server. Must be a directory."
|
||||||
source:
|
source:
|
||||||
description: 'scp file list'
|
description: "List of files or directories to transfer (local paths)."
|
||||||
rm:
|
rm:
|
||||||
description: 'remove target folder before upload data'
|
description: "Remove the target directory on the server before uploading new data."
|
||||||
|
debug:
|
||||||
|
description: "Enable debug messages for troubleshooting."
|
||||||
strip_components:
|
strip_components:
|
||||||
description: 'remove the specified number of leading path elements'
|
description: "Remove the specified number of leading path elements when extracting files."
|
||||||
default: 0
|
|
||||||
overwrite:
|
overwrite:
|
||||||
description: 'use `--overwrite` flag with tar'
|
description: "Use the --overwrite flag with tar to overwrite existing files."
|
||||||
default: false
|
tar_dereference:
|
||||||
|
description: "Use the --dereference flag with tar to follow symlinks."
|
||||||
tar_tmp_path:
|
tar_tmp_path:
|
||||||
description: 'temporary path for tar file on the dest host'
|
description: "Temporary path for the tar file on the destination host."
|
||||||
|
tar_exec:
|
||||||
|
description: "Path to the tar executable on the destination host. Default: tar."
|
||||||
|
default: "tar"
|
||||||
|
proxy_host:
|
||||||
|
description: "Remote host address for SSH proxy."
|
||||||
|
proxy_port:
|
||||||
|
description: "SSH proxy port. Default: 22."
|
||||||
|
default: "22"
|
||||||
|
proxy_username:
|
||||||
|
description: "Username for SSH proxy authentication."
|
||||||
|
proxy_password:
|
||||||
|
description: "Password for SSH proxy authentication."
|
||||||
|
proxy_passphrase:
|
||||||
|
description: "Passphrase for the SSH proxy private key, if required."
|
||||||
|
proxy_timeout:
|
||||||
|
description: "Timeout for establishing SSH connection to the proxy host. Default: 30s."
|
||||||
|
default: "30s"
|
||||||
|
proxy_key:
|
||||||
|
description: "Content of the SSH proxy private key (e.g., the raw content of ~/.ssh/id_rsa)."
|
||||||
|
proxy_key_path:
|
||||||
|
description: "Path to the SSH proxy private key file."
|
||||||
|
proxy_fingerprint:
|
||||||
|
description: "SHA256 fingerprint of the proxy host's public key. If not set, host key verification is skipped (not recommended for production)."
|
||||||
|
proxy_use_insecure_cipher:
|
||||||
|
description: "Enable additional, less secure ciphers for the proxy connection. Not recommended unless required."
|
||||||
|
curl_insecure:
|
||||||
|
description: "When true, uses the --insecure option with curl for insecure downloads."
|
||||||
|
default: "false"
|
||||||
|
capture_stdout:
|
||||||
|
description: "When true, captures and returns standard output from the commands as action output."
|
||||||
|
default: "false"
|
||||||
|
version:
|
||||||
|
description: |
|
||||||
|
The version of drone-scp to use.
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
stdout:
|
||||||
|
description: "Standard output of the executed commands when capture_stdout is enabled."
|
||||||
|
value: ${{ steps.entrypoint.outputs.stdout }}
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: 'docker'
|
using: "composite"
|
||||||
image: 'Dockerfile'
|
steps:
|
||||||
|
- name: Set GitHub Path
|
||||||
|
run: echo "$GITHUB_ACTION_PATH" >> $GITHUB_PATH
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
GITHUB_ACTION_PATH: ${{ github.action_path }}
|
||||||
|
- id: entrypoint
|
||||||
|
name: Run entrypoint.sh
|
||||||
|
run: entrypoint.sh
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
GITHUB_ACTION_PATH: ${{ github.action_path }}
|
||||||
|
INPUT_HOST: ${{ inputs.host }}
|
||||||
|
INPUT_PORT: ${{ inputs.port }}
|
||||||
|
INPUT_PROTOCOL: ${{ inputs.protocol }}
|
||||||
|
INPUT_USERNAME: ${{ inputs.username }}
|
||||||
|
INPUT_PASSWORD: ${{ inputs.password }}
|
||||||
|
INPUT_PASSPHRASE: ${{ inputs.passphrase }}
|
||||||
|
INPUT_KEY: ${{ inputs.key }}
|
||||||
|
INPUT_KEY_PATH: ${{ inputs.key_path }}
|
||||||
|
INPUT_FINGERPRINT: ${{ inputs.fingerprint }}
|
||||||
|
INPUT_PROXY_HOST: ${{ inputs.proxy_host }}
|
||||||
|
INPUT_PROXY_PORT: ${{ inputs.proxy_port }}
|
||||||
|
INPUT_PROXY_USERNAME: ${{ inputs.proxy_username }}
|
||||||
|
INPUT_PROXY_PASSWORD: ${{ inputs.proxy_password }}
|
||||||
|
INPUT_PROXY_PASSPHRASE: ${{ inputs.proxy_passphrase }}
|
||||||
|
INPUT_PROXY_KEY: ${{ inputs.proxy_key }}
|
||||||
|
INPUT_PROXY_KEY_PATH: ${{ inputs.proxy_key_path }}
|
||||||
|
INPUT_PROXY_FINGERPRINT: ${{ inputs.proxy_fingerprint }}
|
||||||
|
INPUT_USE_INSECURE_CIPHER: ${{ inputs.use_insecure_cipher }}
|
||||||
|
INPUT_CIPHER: ${{ inputs.cipher }}
|
||||||
|
INPUT_PROXY_USE_INSECURE_CIPHER: ${{ inputs.proxy_use_insecure_cipher }}
|
||||||
|
INPUT_PROXY_CIPHER: ${{ inputs.proxy_cipher }}
|
||||||
|
INPUT_DEBUG: ${{ inputs.debug }}
|
||||||
|
INPUT_TIMEOUT: ${{ inputs.timeout }}
|
||||||
|
INPUT_COMMAND_TIMEOUT: ${{ inputs.command_timeout }}
|
||||||
|
INPUT_TARGET: ${{ inputs.target }}
|
||||||
|
INPUT_SOURCE: ${{ inputs.source }}
|
||||||
|
INPUT_RM: ${{ inputs.rm }}
|
||||||
|
INPUT_STRIP_COMPONENTS: ${{ inputs.strip_components }}
|
||||||
|
INPUT_OVERWRITE: ${{ inputs.overwrite }}
|
||||||
|
INPUT_TAR_DEREFERENCE: ${{ inputs.tar_dereference }}
|
||||||
|
INPUT_TAR_TMP_PATH: ${{ inputs.tar_tmp_path }}
|
||||||
|
INPUT_TAR_EXEC: ${{ inputs.tar_exec }}
|
||||||
|
INPUT_PROXY_TIMEOUT: ${{ inputs.proxy_timeout }}
|
||||||
|
INPUT_CAPTURE_STDOUT: ${{ inputs.capture_stdout }}
|
||||||
|
INPUT_CURL_INSECURE: ${{ inputs.curl_insecure }}
|
||||||
|
DRONE_SCP_VERSION: ${{ inputs.version }}
|
||||||
|
|
||||||
branding:
|
branding:
|
||||||
icon: 'copy'
|
icon: "copy"
|
||||||
color: 'gray-dark'
|
color: "gray-dark"
|
||||||
|
|||||||
@@ -1,9 +1,56 @@
|
|||||||
#!/bin/sh
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -eu
|
set -euo pipefail
|
||||||
|
|
||||||
export GITHUB="true"
|
export GITHUB="true"
|
||||||
|
|
||||||
[ -n "$INPUT_STRIP_COMPONENTS" ] && export INPUT_STRIP_COMPONENTS=$((INPUT_STRIP_COMPONENTS + 0))
|
GITHUB_ACTION_PATH="${GITHUB_ACTION_PATH%/}"
|
||||||
|
DRONE_SCP_RELEASE_URL="${DRONE_SCP_RELEASE_URL:-https://github.com/appleboy/drone-scp/releases/download}"
|
||||||
|
DRONE_SCP_VERSION="${DRONE_SCP_VERSION:-1.7.0}"
|
||||||
|
|
||||||
sh -c "/bin/drone-scp $*"
|
function log_error() {
|
||||||
|
echo "$1" >&2
|
||||||
|
exit "$2"
|
||||||
|
}
|
||||||
|
|
||||||
|
function detect_client_info() {
|
||||||
|
CLIENT_PLATFORM="${SCP_CLIENT_OS:-$(uname -s | tr '[:upper:]' '[:lower:]')}"
|
||||||
|
CLIENT_ARCH="${SCP_CLIENT_ARCH:-$(uname -m)}"
|
||||||
|
|
||||||
|
case "${CLIENT_PLATFORM}" in
|
||||||
|
darwin | linux | windows) ;;
|
||||||
|
*) log_error "Unknown or unsupported platform: ${CLIENT_PLATFORM}. Supported platforms are Linux, Darwin, and Windows." 2 ;;
|
||||||
|
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 ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
detect_client_info
|
||||||
|
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}"
|
||||||
|
echo "Downloading ${CLIENT_BINARY} from ${DOWNLOAD_URL_PREFIX}"
|
||||||
|
INSECURE_OPTION=""
|
||||||
|
if [[ "${INPUT_CURL_INSECURE}" == 'true' ]]; then
|
||||||
|
INSECURE_OPTION="--insecure"
|
||||||
|
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
|
||||||
|
echo "======================================="
|
||||||
|
if [[ "${INPUT_CAPTURE_STDOUT}" == 'true' ]]; then
|
||||||
|
{
|
||||||
|
echo 'stdout<<EOF'
|
||||||
|
"${TARGET}" "$@" | tee -a "${GITHUB_OUTPUT}"
|
||||||
|
echo 'EOF'
|
||||||
|
} >>"${GITHUB_OUTPUT}"
|
||||||
|
else
|
||||||
|
"${TARGET}" "$@"
|
||||||
|
fi
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
foo
|
foo
|
||||||
|
foobar
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
bar
|
bar
|
||||||
|
foobar
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
c
|
c
|
||||||
|
foobar
|
||||||
|
test1234
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
d
|
d
|
||||||
|
foobar
|
||||||
|
foobar
|
||||||
|
|||||||
Reference in New Issue
Block a user