mirror of
https://github.com/appleboy/ssh-action.git
synced 2025-04-16 17:43:29 +00:00
Compare commits
176 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0e19dd962d | ||
![]() |
bd83ba7e2b | ||
![]() |
9ca1cd2174 | ||
![]() |
20d5c5bbc9 | ||
![]() |
b27b9f8968 | ||
![]() |
689de3cf64 | ||
![]() |
b6690ee817 | ||
![]() |
52a1840ca6 | ||
![]() |
2b3c6504b3 | ||
![]() |
2ead5e3657 | ||
![]() |
a0a0326939 | ||
![]() |
b0a8f324e1 | ||
![]() |
039c9e07bb | ||
![]() |
48992f2e2c | ||
![]() |
01a53594eb | ||
![]() |
d99ccf8c09 | ||
![]() |
92737056c0 | ||
![]() |
9817ef4a17 | ||
![]() |
8faa84277b | ||
![]() |
49751ff516 | ||
![]() |
86aa40ddb7 | ||
![]() |
66aa4d343b | ||
![]() |
102c0d2e5f | ||
![]() |
e13c387332 | ||
![]() |
1c1ad10f6d | ||
![]() |
48531853a7 | ||
![]() |
b76e6173e8 | ||
![]() |
6137f733fb | ||
![]() |
43d4ebbb72 | ||
![]() |
a9e2fdf08d | ||
![]() |
cec69ef231 | ||
![]() |
a8952ebe2a | ||
![]() |
8fdfeb034e | ||
![]() |
7eaf76671a | ||
![]() |
176437b548 | ||
![]() |
25259c3d50 | ||
![]() |
bf84378588 | ||
![]() |
362a7f1677 | ||
![]() |
ab698e59d8 | ||
![]() |
703ffa3c1e | ||
![]() |
8b84eaec3a | ||
![]() |
2763143a97 | ||
![]() |
3f1416813d | ||
![]() |
bb32884d53 | ||
![]() |
25ce8cbbcb | ||
![]() |
58164d0dc2 | ||
![]() |
d732991ab0 | ||
![]() |
b4a07ca594 | ||
![]() |
eaeb06998d | ||
![]() |
06fa62e61c | ||
![]() |
28428a13f5 | ||
![]() |
5ade826485 | ||
![]() |
8b6078208d | ||
![]() |
036cad7df7 | ||
![]() |
71d43ea0f7 | ||
![]() |
43895f2cd5 | ||
![]() |
b6941ae5d5 | ||
![]() |
0c7561b1a3 | ||
![]() |
5a8776fd15 | ||
![]() |
97f8d752b5 | ||
![]() |
9c32aa61f8 | ||
![]() |
f0e5a23d53 | ||
![]() |
fc1c1fce51 | ||
![]() |
aa293c24bb | ||
![]() |
378323e4c8 | ||
![]() |
815c5743ac | ||
![]() |
a39b3cce7d | ||
![]() |
15b64dc891 | ||
![]() |
e40b597081 | ||
![]() |
f05aefe351 | ||
![]() |
acd41e5091 | ||
![]() |
da612c8015 | ||
![]() |
2eeab5bdba | ||
![]() |
977b74a12d | ||
![]() |
0b0e77098a | ||
![]() |
40aad53c5a | ||
![]() |
c8594ae37d | ||
![]() |
aabaf1254d | ||
![]() |
f916346256 | ||
![]() |
551964ebda | ||
![]() |
d2d6858859 | ||
![]() |
dd0f09ca07 | ||
![]() |
1991c553ec | ||
![]() |
fe44be0b96 | ||
![]() |
c78141851a | ||
![]() |
8a779a5b1a | ||
![]() |
9b978f09f2 | ||
![]() |
029f5b4aee | ||
![]() |
d134a26a1f | ||
![]() |
2451745138 | ||
![]() |
1f3c338936 | ||
![]() |
8f94919856 | ||
![]() |
2344d97573 | ||
![]() |
b9f6bf6223 | ||
![]() |
4330a1ea48 | ||
![]() |
55dabf81b4 | ||
![]() |
8d9094f3b1 | ||
![]() |
5ac43dd762 | ||
![]() |
a01d3ea1df | ||
![]() |
c7d850f6cd | ||
![]() |
f579d71942 | ||
![]() |
d87d276960 | ||
![]() |
3130c7a2bc | ||
![]() |
2b7de38eed | ||
![]() |
334f9259f2 | ||
![]() |
6268c80dd6 | ||
![]() |
5f64c95280 | ||
![]() |
3cd1bcf771 | ||
![]() |
6a1b59d972 | ||
![]() |
e4a881008d | ||
![]() |
51b83ba474 | ||
![]() |
495830820f | ||
![]() |
b601429988 | ||
![]() |
ae2bb3c3dc | ||
![]() |
7bf58514db | ||
![]() |
c1965ddd25 | ||
![]() |
d91a1af6f5 | ||
![]() |
4a03da89e5 | ||
![]() |
0d5a3d0e48 | ||
![]() |
db9be1d5f2 | ||
![]() |
9a7da95c8c | ||
![]() |
f23dd5c681 | ||
![]() |
cc051b07ed | ||
![]() |
f9010ff7f1 | ||
![]() |
e1116226a0 | ||
![]() |
a8d82ec39b | ||
![]() |
f82e23f1a3 | ||
![]() |
ed1f3fc7c1 | ||
![]() |
dce9d565de | ||
![]() |
ea5c23a2b5 | ||
![]() |
c732d38392 | ||
![]() |
ba1d4fb0eb | ||
![]() |
c7671d858f | ||
![]() |
1a8b3784ea | ||
![]() |
29007ce6fb | ||
![]() |
e59c0ee97a | ||
![]() |
c7104ccac4 | ||
![]() |
63dd9dd662 | ||
![]() |
61e292b601 | ||
![]() |
1d1b21ca96 | ||
![]() |
9fb11fb1f5 | ||
![]() |
fd39ef0f18 | ||
![]() |
ffff33f8fe | ||
![]() |
8bd4933b73 | ||
![]() |
bf84735fa9 | ||
![]() |
d09b6e0211 | ||
![]() |
3ac4675689 | ||
![]() |
269a4479eb | ||
![]() |
a2f91cbad1 | ||
![]() |
e2cbea5f00 | ||
![]() |
5711a203b3 | ||
![]() |
b315fb5f98 | ||
![]() |
682eb0ddda | ||
![]() |
03b440e441 | ||
![]() |
1cb5cd31c9 | ||
![]() |
c9eebc1cde | ||
![]() |
6b00175bad | ||
![]() |
a912e225ec | ||
![]() |
ad6643f705 | ||
![]() |
26dd2b3a38 | ||
![]() |
122f35dca5 | ||
![]() |
03b5d10ad6 | ||
![]() |
fcfb760891 | ||
![]() |
fd81fae289 | ||
![]() |
242a8e2e57 | ||
![]() |
cfe9c45db6 | ||
![]() |
73767290ca | ||
![]() |
e5c07fceef | ||
![]() |
d690bdebf8 | ||
![]() |
f478af9b34 | ||
![]() |
d520c19f4f | ||
![]() |
0dee98b334 | ||
![]() |
9085f3ea5b | ||
![]() |
696aab4627 | ||
![]() |
a88f6f2013 | ||
![]() |
6f091cd9e3 |
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: ssh-action
|
||||
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']
|
41
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
41
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ""
|
||||
labels: bug
|
||||
assignees: appleboy
|
||||
---
|
||||
|
||||
## Describe the bug
|
||||
|
||||
A clear and concise description of what the bug is. If applicable, add screenshots to help explain your problem.
|
||||
|
||||
## Yaml Config
|
||||
|
||||
Please post your Yaml configuration file along with the output results.
|
||||
|
||||
```yaml
|
||||
name: remote ssh command
|
||||
on: [push]
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: executing remote ssh commands using password
|
||||
uses: appleboy/ssh-action@v1.2.2
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
password: ${{ secrets.PASSWORD }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: whoami
|
||||
```
|
||||
|
||||
## Related environment
|
||||
|
||||
Please provide the following information:
|
||||
|
||||
1. Your hosting provider information, such as DigitalOcean, Linode, AWS, or GCP.
|
||||
2. The version information of your host's SSH service.
|
||||
3. The information from your host's SSH configuration file.
|
60
.github/workflows/ci.yml
vendored
60
.github/workflows/ci.yml
vendored
@ -1,60 +0,0 @@
|
||||
name: remote ssh command
|
||||
on: [push]
|
||||
jobs:
|
||||
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: executing remote ssh commands using password
|
||||
uses: appleboy/ssh-action@master
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
password: ${{ secrets.PASSWORD }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: whoami
|
||||
|
||||
- name: executing remote ssh commands using ssh key
|
||||
uses: appleboy/ssh-action@master
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: whoami
|
||||
|
||||
- name: multiple command
|
||||
uses: appleboy/ssh-action@master
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
|
||||
# - name: stop script if command error
|
||||
# uses: appleboy/ssh-action@master
|
||||
# with:
|
||||
# host: ${{ secrets.HOST }}
|
||||
# username: ${{ secrets.USERNAME }}
|
||||
# key: ${{ secrets.KEY }}
|
||||
# port: ${{ secrets.PORT }}
|
||||
# script_stop: true
|
||||
# script: "mkdir abc/def,ls -al"
|
||||
|
||||
- name: pass environment
|
||||
uses: appleboy/ssh-action@master
|
||||
env:
|
||||
FOO: "BAR"
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
envs: FOO
|
||||
script: |
|
||||
echo "I am $FOO"
|
||||
echo "I am $BAR"
|
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 }}
|
724
.github/workflows/main.yml
vendored
Normal file
724
.github/workflows/main.yml
vendored
Normal file
@ -0,0 +1,724 @@
|
||||
name: testing main branch
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
default-user-name-password:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: create new ssh server
|
||||
run: |
|
||||
docker run -d \
|
||||
--name=openssh-server \
|
||||
--hostname=openssh-server \
|
||||
-p 2222:2222 \
|
||||
-e SUDO_ACCESS=false \
|
||||
-e PASSWORD_ACCESS=true \
|
||||
-e USER_PASSWORD=password \
|
||||
-e USER_NAME=linuxserver.io \
|
||||
--restart unless-stopped \
|
||||
lscr.io/linuxserver/openssh-server:latest
|
||||
docker exec openssh-server sh -c "hostname -i" > ip.txt
|
||||
echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV
|
||||
cat ip.txt >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= container ip address ========="
|
||||
cat ip.txt
|
||||
echo "======================================"
|
||||
sleep 2
|
||||
|
||||
- name: ssh by username and password
|
||||
uses: ./
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
password: password
|
||||
port: 2222
|
||||
script: |
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
whoami
|
||||
|
||||
- name: ssh commands from a file
|
||||
uses: ./
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
password: password
|
||||
port: 2222
|
||||
script_path: testdata/test.sh
|
||||
|
||||
check-ssh-key:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: add public key to env
|
||||
run: |
|
||||
echo "PUBLIC_KEY<<EOF" >> $GITHUB_ENV
|
||||
cat testdata/.ssh/id_rsa.pub >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= public key ========="
|
||||
cat testdata/.ssh/id_rsa.pub
|
||||
echo "============================"
|
||||
echo "PRIVATE_KEY<<EOF" >> $GITHUB_ENV
|
||||
cat testdata/.ssh/id_rsa >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= private key ========="
|
||||
cat testdata/.ssh/id_rsa
|
||||
echo "============================"
|
||||
|
||||
- name: create new ssh server
|
||||
run: |
|
||||
docker run -d \
|
||||
--name=openssh-server \
|
||||
--hostname=openssh-server \
|
||||
-p 2222:2222 \
|
||||
-e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \
|
||||
-e SUDO_ACCESS=false \
|
||||
-e PASSWORD_ACCESS=true \
|
||||
-e USER_PASSWORD=password \
|
||||
-e USER_NAME=linuxserver.io \
|
||||
--restart unless-stopped \
|
||||
lscr.io/linuxserver/openssh-server:latest
|
||||
docker exec openssh-server sh -c "hostname -i" > ip.txt
|
||||
echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV
|
||||
cat ip.txt >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= container ip address ========="
|
||||
cat ip.txt
|
||||
echo "======================================"
|
||||
sleep 2
|
||||
|
||||
- name: ssh by private key
|
||||
uses: ./
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
script: whoami
|
||||
|
||||
- name: wrong password but correct key
|
||||
uses: ./
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
password: "abcdef"
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
script: whoami
|
||||
|
||||
- name: correct password but wrong key
|
||||
uses: ./
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
password: password
|
||||
key: password
|
||||
port: 2222
|
||||
script: whoami
|
||||
|
||||
support-key-passphrase:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: add public key to env
|
||||
run: |
|
||||
echo "PUBLIC_KEY<<EOF" >> $GITHUB_ENV
|
||||
cat testdata/.ssh/id_passphrase.pub >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= public key ========="
|
||||
cat testdata/.ssh/id_passphrase.pub
|
||||
echo "============================"
|
||||
echo "PRIVATE_KEY<<EOF" >> $GITHUB_ENV
|
||||
cat testdata/.ssh/id_passphrase >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= private key ========="
|
||||
cat testdata/.ssh/id_passphrase
|
||||
echo "============================"
|
||||
|
||||
- name: create new ssh server
|
||||
run: |
|
||||
docker run -d \
|
||||
--name=openssh-server \
|
||||
--hostname=openssh-server \
|
||||
-p 2222:2222 \
|
||||
-e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \
|
||||
-e SUDO_ACCESS=false \
|
||||
-e PASSWORD_ACCESS=true \
|
||||
-e USER_PASSWORD=password \
|
||||
-e USER_NAME=linuxserver.io \
|
||||
--restart unless-stopped \
|
||||
lscr.io/linuxserver/openssh-server:latest
|
||||
docker exec openssh-server sh -c "hostname -i" > ip.txt
|
||||
echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV
|
||||
cat ip.txt >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= container ip address ========="
|
||||
cat ip.txt
|
||||
echo "======================================"
|
||||
sleep 2
|
||||
|
||||
- name: ssh key passphrase
|
||||
uses: ./
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
passphrase: 1234
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
|
||||
- name: missing ssh key passphrase
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
|
||||
# https://github.com/appleboy/ssh-action/issues/75#issuecomment-668314271
|
||||
- name: Multiline SSH commands interpreted as single lines
|
||||
uses: ./
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
passphrase: 1234
|
||||
script: |
|
||||
ls \
|
||||
-lah
|
||||
use_insecure_cipher: true
|
||||
|
||||
multiple-server:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: add public key to env
|
||||
run: |
|
||||
echo "PUBLIC_KEY<<EOF" >> $GITHUB_ENV
|
||||
cat testdata/.ssh/id_passphrase.pub >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= public key ========="
|
||||
cat testdata/.ssh/id_passphrase.pub
|
||||
echo "============================"
|
||||
echo "PRIVATE_KEY<<EOF" >> $GITHUB_ENV
|
||||
cat testdata/.ssh/id_passphrase >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= private key ========="
|
||||
cat testdata/.ssh/id_passphrase
|
||||
echo "============================"
|
||||
|
||||
- name: create new ssh server
|
||||
run: |
|
||||
docker run -d \
|
||||
--name=openssh-server-01 \
|
||||
--hostname=openssh-server-01 \
|
||||
-p 2222:2222 \
|
||||
-e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \
|
||||
-e SUDO_ACCESS=false \
|
||||
-e PASSWORD_ACCESS=true \
|
||||
-e USER_PASSWORD=password \
|
||||
-e USER_NAME=linuxserver.io \
|
||||
--restart unless-stopped \
|
||||
lscr.io/linuxserver/openssh-server:latest
|
||||
docker exec openssh-server-01 sh -c "hostname -i" > ip01.txt
|
||||
echo "REMOTE_HOST_01<<EOF" >> $GITHUB_ENV
|
||||
cat ip01.txt >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= container ip address ========="
|
||||
cat ip01.txt
|
||||
echo "======================================"
|
||||
|
||||
docker run -d \
|
||||
--name=openssh-server-02 \
|
||||
--hostname=openssh-server-02 \
|
||||
-p 2223:2222 \
|
||||
-e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \
|
||||
-e SUDO_ACCESS=false \
|
||||
-e PASSWORD_ACCESS=true \
|
||||
-e USER_PASSWORD=password \
|
||||
-e USER_NAME=linuxserver.io \
|
||||
--restart unless-stopped \
|
||||
lscr.io/linuxserver/openssh-server:latest
|
||||
docker exec openssh-server-02 sh -c "hostname -i" > ip02.txt
|
||||
echo "REMOTE_HOST_02<<EOF" >> $GITHUB_ENV
|
||||
cat ip02.txt >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= container ip address ========="
|
||||
cat ip02.txt
|
||||
echo "======================================"
|
||||
|
||||
sleep 2
|
||||
|
||||
# https://github.com/appleboy/ssh-action/issues/85
|
||||
- name: Deployment to multiple hosts with different ports
|
||||
uses: ./
|
||||
with:
|
||||
host: "${{ env.REMOTE_HOST_01 }}:2222,${{ env.REMOTE_HOST_02 }}:2222"
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
passphrase: 1234
|
||||
script: |
|
||||
whoami
|
||||
|
||||
support-ed25519-key:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: add public key to env
|
||||
run: |
|
||||
echo "PUBLIC_KEY<<EOF" >> $GITHUB_ENV
|
||||
cat testdata/.ssh/id_ed25519.pub >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= public key ========="
|
||||
cat testdata/.ssh/id_ed25519.pub
|
||||
echo "============================"
|
||||
echo "PRIVATE_KEY<<EOF" >> $GITHUB_ENV
|
||||
cat testdata/.ssh/id_ed25519 >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= private key ========="
|
||||
cat testdata/.ssh/id_ed25519
|
||||
echo "============================"
|
||||
|
||||
- name: create new ssh server
|
||||
run: |
|
||||
docker run -d \
|
||||
--name=openssh-server \
|
||||
--hostname=openssh-server \
|
||||
-p 2222:2222 \
|
||||
-e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \
|
||||
-e SUDO_ACCESS=false \
|
||||
-e PASSWORD_ACCESS=true \
|
||||
-e USER_PASSWORD=password \
|
||||
-e USER_NAME=linuxserver.io \
|
||||
--restart unless-stopped \
|
||||
lscr.io/linuxserver/openssh-server:latest
|
||||
docker exec openssh-server sh -c "hostname -i" > ip.txt
|
||||
echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV
|
||||
cat ip.txt >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= container ip address ========="
|
||||
cat ip.txt
|
||||
echo "======================================"
|
||||
sleep 2
|
||||
|
||||
- name: testing id_ed25519 key
|
||||
uses: ./
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
|
||||
testing-with-env:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: add public key to env
|
||||
run: |
|
||||
echo "PUBLIC_KEY<<EOF" >> $GITHUB_ENV
|
||||
cat testdata/.ssh/id_ed25519.pub >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= public key ========="
|
||||
cat testdata/.ssh/id_ed25519.pub
|
||||
echo "============================"
|
||||
echo "PRIVATE_KEY<<EOF" >> $GITHUB_ENV
|
||||
cat testdata/.ssh/id_ed25519 >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= private key ========="
|
||||
cat testdata/.ssh/id_ed25519
|
||||
echo "============================"
|
||||
|
||||
- name: create new ssh server
|
||||
run: |
|
||||
docker run -d \
|
||||
--name=openssh-server \
|
||||
--hostname=openssh-server \
|
||||
-p 2222:2222 \
|
||||
-e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \
|
||||
-e SUDO_ACCESS=true \
|
||||
-e PASSWORD_ACCESS=true \
|
||||
-e USER_NAME=linuxserver.io \
|
||||
--restart unless-stopped \
|
||||
lscr.io/linuxserver/openssh-server:latest
|
||||
docker exec openssh-server sh -c "hostname -i" > ip.txt
|
||||
echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV
|
||||
cat ip.txt >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= container ip address ========="
|
||||
cat ip.txt
|
||||
echo "======================================"
|
||||
sleep 2
|
||||
|
||||
- name: testing id_ed25519 key
|
||||
uses: ./
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
|
||||
- name: pass environment
|
||||
uses: ./
|
||||
env:
|
||||
FOO: "BAR"
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
envs: FOO
|
||||
script: |
|
||||
echo "I am $FOO, thanks"
|
||||
echo "I am $BAR, thanks"
|
||||
|
||||
- name: pass multiple environment
|
||||
uses: ./
|
||||
env:
|
||||
FOO: "BAR"
|
||||
BAR: "FOO"
|
||||
SHA: ${{ github.sha }}
|
||||
PORT: ${{ secrets.PORT }}
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
envs: FOO,BAR,SHA,PORT
|
||||
script: |
|
||||
echo "I am $FOO, thanks"
|
||||
echo "I am $BAR, thanks"
|
||||
echo "sha: $SHA"
|
||||
echo "port: $PORT"
|
||||
|
||||
- name: custom envs format
|
||||
uses: ./
|
||||
env:
|
||||
FOO: "BAR"
|
||||
AAA: "BBB"
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
envs: FOO,BAR,AAA
|
||||
envs_format: export TEST_{NAME}={VALUE}
|
||||
script: |
|
||||
echo "I am $TEST_FOO, thanks"
|
||||
echo "I am $TEST_BAR, thanks"
|
||||
echo "I am $BAR, thanks"
|
||||
echo "I am $TEST_AAA, thanks"
|
||||
|
||||
- name: pass all ENV variables to script
|
||||
uses: ./
|
||||
env:
|
||||
INPUT_FOO: "BAR"
|
||||
INPUT_AAA: "BBB"
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
allenvs: true
|
||||
script: |
|
||||
echo "I am $INPUT_FOO, thanks"
|
||||
echo "I am $INPUT_AAA, thanks"
|
||||
echo "$GITHUB_BASE_REF"
|
||||
echo "$GITHUB_REF"
|
||||
|
||||
- name: pass secret variable in shell
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
script: cd ${{ secrets.PORT }}
|
||||
|
||||
- name: switch to root user
|
||||
uses: ./
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
request_pty: true
|
||||
command_timeout: 30s
|
||||
script: |
|
||||
whoami && echo 'hello world' && touch todo.txt
|
||||
sudo whoami
|
||||
|
||||
testing06:
|
||||
name: testing ipv6
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up WARP
|
||||
uses: fscarmen/warp-on-actions@v1.1
|
||||
with:
|
||||
stack: dual
|
||||
|
||||
- name: testing ipv6 for command
|
||||
run: |
|
||||
curl -m 9 --ipv6 --verbose https://google.com
|
||||
|
||||
- name: testing ipv6
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
with:
|
||||
host: 2402:1f00:8000:800::2628
|
||||
username: ubuntu
|
||||
password: ${{ secrets.OVH_PASSWORD }}
|
||||
protocol: tcp6
|
||||
port: 22
|
||||
command_timeout: 30s
|
||||
script: |
|
||||
whoami
|
||||
|
||||
testing07:
|
||||
name: some special character
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set Environment Variables
|
||||
run: |
|
||||
PASS='3HUS$?8kLu)}'
|
||||
printf "PASS=${PASS}" >> $GITHUB_ENV
|
||||
|
||||
- name: create new ssh server
|
||||
run: |
|
||||
docker run -d \
|
||||
--name=openssh-server \
|
||||
--hostname=openssh-server \
|
||||
-p 2222:2222 \
|
||||
-e SUDO_ACCESS=false \
|
||||
-e PASSWORD_ACCESS=true \
|
||||
-e USER_PASSWORD='${{ env.PASS }}' \
|
||||
-e USER_NAME=linuxserver.io \
|
||||
--restart unless-stopped \
|
||||
lscr.io/linuxserver/openssh-server:latest
|
||||
docker exec openssh-server sh -c "hostname -i" > ip.txt
|
||||
echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV
|
||||
cat ip.txt >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= container ip address ========="
|
||||
cat ip.txt
|
||||
echo "======================================"
|
||||
sleep 2
|
||||
|
||||
- name: ssh by username and password
|
||||
uses: ./
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
password: ${{ env.PASS }}
|
||||
port: 2222
|
||||
script: |
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
whoami
|
||||
|
||||
testing-capturing-output:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: create new ssh server
|
||||
run: |
|
||||
docker run -d \
|
||||
--name=openssh-server \
|
||||
--hostname=openssh-server \
|
||||
-p 2222:2222 \
|
||||
-e SUDO_ACCESS=false \
|
||||
-e PASSWORD_ACCESS=true \
|
||||
-e USER_PASSWORD=password \
|
||||
-e USER_NAME=linuxserver.io \
|
||||
--restart unless-stopped \
|
||||
lscr.io/linuxserver/openssh-server:latest
|
||||
docker exec openssh-server sh -c "hostname -i" > ip.txt
|
||||
echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV
|
||||
cat ip.txt >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= container ip address ========="
|
||||
cat ip.txt
|
||||
echo "======================================"
|
||||
sleep 2
|
||||
|
||||
- id: stdout
|
||||
name: ssh command with stdout
|
||||
uses: ./
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
password: password
|
||||
port: 2222
|
||||
capture_stdout: true
|
||||
script: |
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
whoami
|
||||
|
||||
- name: check stdout
|
||||
run: |
|
||||
echo "stdout: ${{ steps.stdout.outputs.stdout }}"
|
||||
|
||||
testing-script-stop:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: create new ssh server
|
||||
run: |
|
||||
docker run -d \
|
||||
--name=openssh-server \
|
||||
--hostname=openssh-server \
|
||||
-p 2222:2222 \
|
||||
-e SUDO_ACCESS=false \
|
||||
-e PASSWORD_ACCESS=true \
|
||||
-e USER_PASSWORD=password \
|
||||
-e USER_NAME=linuxserver.io \
|
||||
--restart unless-stopped \
|
||||
lscr.io/linuxserver/openssh-server:latest
|
||||
docker exec openssh-server sh -c "hostname -i" > ip.txt
|
||||
echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV
|
||||
cat ip.txt >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= container ip address ========="
|
||||
cat ip.txt
|
||||
echo "======================================"
|
||||
sleep 2
|
||||
|
||||
- id: stdout01
|
||||
name: ssh command with stdout 01
|
||||
uses: ./
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
password: password
|
||||
port: 2222
|
||||
capture_stdout: true
|
||||
script: |
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
echo "TMP TESTING IF"
|
||||
if [[ "2" == "1" ]]; then
|
||||
echo "True"
|
||||
else
|
||||
echo "False"
|
||||
fi
|
||||
|
||||
- name: check stdout 01
|
||||
run: |
|
||||
echo "stdout: ${{ steps.stdout01.outputs.stdout }}"
|
||||
if echo "${{ steps.stdout01.outputs.stdout }}" | grep -q "True"; then
|
||||
echo "Output contains 'True'"
|
||||
exit 1
|
||||
fi
|
||||
if echo "${{ steps.stdout01.outputs.stdout }}" | grep -q "False"; then
|
||||
echo "Output contains 'False'"
|
||||
fi
|
||||
|
||||
- id: stdout02
|
||||
name: ssh command with stdout 01
|
||||
uses: ./
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
password: password
|
||||
port: 2222
|
||||
capture_stdout: true
|
||||
script: |
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
echo "TMP TESTING IF"
|
||||
if [[ "1" == "1" ]]; then
|
||||
echo "True"
|
||||
else
|
||||
echo "False"
|
||||
fi
|
||||
|
||||
- name: check stdout 02
|
||||
run: |
|
||||
echo "stdout: ${{ steps.stdout02.outputs.stdout }}"
|
||||
if echo "${{ steps.stdout02.outputs.stdout }}" | grep -q "False"; then
|
||||
echo "Output contains 'False'"
|
||||
exit 1
|
||||
fi
|
||||
if echo "${{ steps.stdout02.outputs.stdout }}" | grep -q "True"; then
|
||||
echo "Output contains 'True'"
|
||||
fi
|
||||
|
||||
testing-script-error:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: create new ssh server
|
||||
run: |
|
||||
docker run -d \
|
||||
--name=openssh-server \
|
||||
--hostname=openssh-server \
|
||||
-p 2222:2222 \
|
||||
-e SUDO_ACCESS=false \
|
||||
-e PASSWORD_ACCESS=true \
|
||||
-e USER_PASSWORD=password \
|
||||
-e USER_NAME=linuxserver.io \
|
||||
--restart unless-stopped \
|
||||
lscr.io/linuxserver/openssh-server:latest
|
||||
docker exec openssh-server sh -c "hostname -i" > ip.txt
|
||||
echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV
|
||||
cat ip.txt >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= container ip address ========="
|
||||
cat ip.txt
|
||||
echo "======================================"
|
||||
sleep 2
|
||||
|
||||
- name: test script error
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
password: password
|
||||
port: 2222
|
||||
capture_stdout: true
|
||||
script: |
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
ls /nonexistent
|
467
.github/workflows/stable.yml
vendored
Normal file
467
.github/workflows/stable.yml
vendored
Normal file
@ -0,0 +1,467 @@
|
||||
name: testing stable version
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
default-user-name-password:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: create new ssh server
|
||||
run: |
|
||||
docker run -d \
|
||||
--name=openssh-server \
|
||||
--hostname=openssh-server \
|
||||
-p 2222:2222 \
|
||||
-e SUDO_ACCESS=false \
|
||||
-e PASSWORD_ACCESS=true \
|
||||
-e USER_PASSWORD=password \
|
||||
-e USER_NAME=linuxserver.io \
|
||||
--restart unless-stopped \
|
||||
lscr.io/linuxserver/openssh-server:latest
|
||||
docker exec openssh-server sh -c "hostname -i" > ip.txt
|
||||
echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV
|
||||
cat ip.txt >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= container ip address ========="
|
||||
cat ip.txt
|
||||
echo "======================================"
|
||||
sleep 2
|
||||
|
||||
- name: ssh by username and password
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
password: password
|
||||
port: 2222
|
||||
script: |
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
whoami
|
||||
|
||||
- name: ssh commands from a file
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
password: password
|
||||
port: 2222
|
||||
script_path: testdata/test.sh
|
||||
|
||||
check-ssh-key:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: add public key to env
|
||||
run: |
|
||||
echo "PUBLIC_KEY<<EOF" >> $GITHUB_ENV
|
||||
cat testdata/.ssh/id_rsa.pub >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= public key ========="
|
||||
cat testdata/.ssh/id_rsa.pub
|
||||
echo "============================"
|
||||
echo "PRIVATE_KEY<<EOF" >> $GITHUB_ENV
|
||||
cat testdata/.ssh/id_rsa >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= private key ========="
|
||||
cat testdata/.ssh/id_rsa
|
||||
echo "============================"
|
||||
|
||||
- name: create new ssh server
|
||||
run: |
|
||||
docker run -d \
|
||||
--name=openssh-server \
|
||||
--hostname=openssh-server \
|
||||
-p 2222:2222 \
|
||||
-e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \
|
||||
-e SUDO_ACCESS=false \
|
||||
-e PASSWORD_ACCESS=true \
|
||||
-e USER_PASSWORD=password \
|
||||
-e USER_NAME=linuxserver.io \
|
||||
--restart unless-stopped \
|
||||
lscr.io/linuxserver/openssh-server:latest
|
||||
docker exec openssh-server sh -c "hostname -i" > ip.txt
|
||||
echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV
|
||||
cat ip.txt >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= container ip address ========="
|
||||
cat ip.txt
|
||||
echo "======================================"
|
||||
sleep 2
|
||||
|
||||
- name: ssh by private key
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
script: whoami
|
||||
|
||||
- name: wrong password but correct key
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
password: "abcdef"
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
script: whoami
|
||||
|
||||
- name: correct password but wrong key
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
password: password
|
||||
key: password
|
||||
port: 2222
|
||||
script: whoami
|
||||
|
||||
support-key-passphrase:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: add public key to env
|
||||
run: |
|
||||
echo "PUBLIC_KEY<<EOF" >> $GITHUB_ENV
|
||||
cat testdata/.ssh/id_passphrase.pub >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= public key ========="
|
||||
cat testdata/.ssh/id_passphrase.pub
|
||||
echo "============================"
|
||||
echo "PRIVATE_KEY<<EOF" >> $GITHUB_ENV
|
||||
cat testdata/.ssh/id_passphrase >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= private key ========="
|
||||
cat testdata/.ssh/id_passphrase
|
||||
echo "============================"
|
||||
|
||||
- name: create new ssh server
|
||||
run: |
|
||||
docker run -d \
|
||||
--name=openssh-server \
|
||||
--hostname=openssh-server \
|
||||
-p 2222:2222 \
|
||||
-e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \
|
||||
-e SUDO_ACCESS=false \
|
||||
-e PASSWORD_ACCESS=true \
|
||||
-e USER_PASSWORD=password \
|
||||
-e USER_NAME=linuxserver.io \
|
||||
--restart unless-stopped \
|
||||
lscr.io/linuxserver/openssh-server:latest
|
||||
docker exec openssh-server sh -c "hostname -i" > ip.txt
|
||||
echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV
|
||||
cat ip.txt >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= container ip address ========="
|
||||
cat ip.txt
|
||||
echo "======================================"
|
||||
sleep 2
|
||||
|
||||
- name: ssh key passphrase
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
passphrase: 1234
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
|
||||
- name: missing ssh key passphrase
|
||||
uses: appleboy/ssh-action@v1
|
||||
continue-on-error: true
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
|
||||
# https://github.com/appleboy/ssh-action/issues/75#issuecomment-668314271
|
||||
- name: Multiline SSH commands interpreted as single lines
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
passphrase: 1234
|
||||
script: |
|
||||
ls \
|
||||
-lah
|
||||
use_insecure_cipher: true
|
||||
|
||||
multiple-server:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: add public key to env
|
||||
run: |
|
||||
echo "PUBLIC_KEY<<EOF" >> $GITHUB_ENV
|
||||
cat testdata/.ssh/id_passphrase.pub >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= public key ========="
|
||||
cat testdata/.ssh/id_passphrase.pub
|
||||
echo "============================"
|
||||
echo "PRIVATE_KEY<<EOF" >> $GITHUB_ENV
|
||||
cat testdata/.ssh/id_passphrase >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= private key ========="
|
||||
cat testdata/.ssh/id_passphrase
|
||||
echo "============================"
|
||||
|
||||
- name: create new ssh server
|
||||
run: |
|
||||
docker run -d \
|
||||
--name=openssh-server-01 \
|
||||
--hostname=openssh-server-01 \
|
||||
-p 2222:2222 \
|
||||
-e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \
|
||||
-e SUDO_ACCESS=false \
|
||||
-e PASSWORD_ACCESS=true \
|
||||
-e USER_PASSWORD=password \
|
||||
-e USER_NAME=linuxserver.io \
|
||||
--restart unless-stopped \
|
||||
lscr.io/linuxserver/openssh-server:latest
|
||||
docker exec openssh-server-01 sh -c "hostname -i" > ip01.txt
|
||||
echo "REMOTE_HOST_01<<EOF" >> $GITHUB_ENV
|
||||
cat ip01.txt >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= container ip address ========="
|
||||
cat ip01.txt
|
||||
echo "======================================"
|
||||
|
||||
docker run -d \
|
||||
--name=openssh-server-02 \
|
||||
--hostname=openssh-server-02 \
|
||||
-p 2223:2222 \
|
||||
-e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \
|
||||
-e SUDO_ACCESS=false \
|
||||
-e PASSWORD_ACCESS=true \
|
||||
-e USER_PASSWORD=password \
|
||||
-e USER_NAME=linuxserver.io \
|
||||
--restart unless-stopped \
|
||||
lscr.io/linuxserver/openssh-server:latest
|
||||
docker exec openssh-server-02 sh -c "hostname -i" > ip02.txt
|
||||
echo "REMOTE_HOST_02<<EOF" >> $GITHUB_ENV
|
||||
cat ip02.txt >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= container ip address ========="
|
||||
cat ip02.txt
|
||||
echo "======================================"
|
||||
|
||||
sleep 2
|
||||
|
||||
# https://github.com/appleboy/ssh-action/issues/85
|
||||
- name: Deployment to multiple hosts with different ports
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: "${{ env.REMOTE_HOST_01 }}:2222,${{ env.REMOTE_HOST_02 }}:2222"
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
passphrase: 1234
|
||||
script: |
|
||||
whoami
|
||||
|
||||
support-ed25519-key:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: add public key to env
|
||||
run: |
|
||||
echo "PUBLIC_KEY<<EOF" >> $GITHUB_ENV
|
||||
cat testdata/.ssh/id_ed25519.pub >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= public key ========="
|
||||
cat testdata/.ssh/id_ed25519.pub
|
||||
echo "============================"
|
||||
echo "PRIVATE_KEY<<EOF" >> $GITHUB_ENV
|
||||
cat testdata/.ssh/id_ed25519 >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= private key ========="
|
||||
cat testdata/.ssh/id_ed25519
|
||||
echo "============================"
|
||||
|
||||
- name: create new ssh server
|
||||
run: |
|
||||
docker run -d \
|
||||
--name=openssh-server \
|
||||
--hostname=openssh-server \
|
||||
-p 2222:2222 \
|
||||
-e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \
|
||||
-e SUDO_ACCESS=false \
|
||||
-e PASSWORD_ACCESS=true \
|
||||
-e USER_PASSWORD=password \
|
||||
-e USER_NAME=linuxserver.io \
|
||||
--restart unless-stopped \
|
||||
lscr.io/linuxserver/openssh-server:latest
|
||||
docker exec openssh-server sh -c "hostname -i" > ip.txt
|
||||
echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV
|
||||
cat ip.txt >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= container ip address ========="
|
||||
cat ip.txt
|
||||
echo "======================================"
|
||||
sleep 2
|
||||
|
||||
- name: testing id_ed25519 key
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
|
||||
testing-with-env:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: add public key to env
|
||||
run: |
|
||||
echo "PUBLIC_KEY<<EOF" >> $GITHUB_ENV
|
||||
cat testdata/.ssh/id_ed25519.pub >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= public key ========="
|
||||
cat testdata/.ssh/id_ed25519.pub
|
||||
echo "============================"
|
||||
echo "PRIVATE_KEY<<EOF" >> $GITHUB_ENV
|
||||
cat testdata/.ssh/id_ed25519 >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= private key ========="
|
||||
cat testdata/.ssh/id_ed25519
|
||||
echo "============================"
|
||||
|
||||
- name: create new ssh server
|
||||
run: |
|
||||
docker run -d \
|
||||
--name=openssh-server \
|
||||
--hostname=openssh-server \
|
||||
-p 2222:2222 \
|
||||
-e PUBLIC_KEY="${{ env.PUBLIC_KEY }}" \
|
||||
-e SUDO_ACCESS=true \
|
||||
-e PASSWORD_ACCESS=true \
|
||||
-e USER_NAME=linuxserver.io \
|
||||
--restart unless-stopped \
|
||||
lscr.io/linuxserver/openssh-server:latest
|
||||
docker exec openssh-server sh -c "hostname -i" > ip.txt
|
||||
echo "REMOTE_HOST<<EOF" >> $GITHUB_ENV
|
||||
cat ip.txt >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "======= container ip address ========="
|
||||
cat ip.txt
|
||||
echo "======================================"
|
||||
sleep 2
|
||||
|
||||
- name: testing id_ed25519 key
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
|
||||
- name: pass environment
|
||||
uses: appleboy/ssh-action@v1
|
||||
env:
|
||||
FOO: "BAR"
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
envs: FOO
|
||||
script: |
|
||||
echo "I am $FOO, thanks"
|
||||
echo "I am $BAR, thanks"
|
||||
|
||||
- name: pass multiple environment
|
||||
uses: appleboy/ssh-action@v1
|
||||
env:
|
||||
FOO: "BAR"
|
||||
BAR: "FOO"
|
||||
SHA: ${{ github.sha }}
|
||||
PORT: ${{ secrets.PORT }}
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
envs: FOO,BAR,SHA,PORT
|
||||
script: |
|
||||
echo "I am $FOO, thanks"
|
||||
echo "I am $BAR, thanks"
|
||||
echo "sha: $SHA"
|
||||
echo "port: $PORT"
|
||||
|
||||
- name: custom envs format
|
||||
uses: appleboy/ssh-action@v1
|
||||
env:
|
||||
FOO: "BAR"
|
||||
AAA: "BBB"
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
envs: FOO,BAR,AAA
|
||||
envs_format: export TEST_{NAME}={VALUE}
|
||||
script: |
|
||||
echo "I am $TEST_FOO, thanks"
|
||||
echo "I am $TEST_BAR, thanks"
|
||||
echo "I am $BAR, thanks"
|
||||
echo "I am $TEST_AAA, thanks"
|
||||
|
||||
- name: pass all ENV variables to script
|
||||
uses: appleboy/ssh-action@v1
|
||||
env:
|
||||
INPUT_FOO: "BAR"
|
||||
INPUT_AAA: "BBB"
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
allenvs: true
|
||||
script: |
|
||||
echo "I am $INPUT_FOO, thanks"
|
||||
echo "I am $INPUT_AAA, thanks"
|
||||
echo "$GITHUB_BASE_REF"
|
||||
echo "$GITHUB_REF"
|
||||
|
||||
- name: switch to root user
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ env.REMOTE_HOST }}
|
||||
username: linuxserver.io
|
||||
key: ${{ env.PRIVATE_KEY }}
|
||||
port: 2222
|
||||
request_pty: true
|
||||
command_timeout: 30s
|
||||
script: |
|
||||
whoami && echo 'hello world' && touch todo.txt
|
||||
sudo whoami
|
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: 5
|
||||
- title: Others
|
@ -1,5 +0,0 @@
|
||||
FROM appleboy/drone-ssh:1.5.2-linux-amd64
|
||||
|
||||
ADD entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
426
README.md
426
README.md
@ -1,32 +1,79 @@
|
||||
# 🚀 SSH for GitHub Actions
|
||||
|
||||
[GitHub Action](https://github.com/features/actions) for executing remote ssh commands.
|
||||
English | [繁體中文](./README.zh-tw.md) | [简体中文](./README.zh-cn.md)
|
||||
|
||||
A [GitHub Action](https://github.com/features/actions) for executing remote SSH commands.
|
||||
|
||||

|
||||
|
||||
[](https://github.com/appleboy/ssh-action/actions)
|
||||
[](https://github.com/appleboy/ssh-action/actions/workflows/main.yml)
|
||||
|
||||
This project is built with [Golang](https://go.dev) and [drone-ssh](https://github.com/appleboy/drone-ssh). 🚀
|
||||
|
||||
## Input variables
|
||||
|
||||
Refer to [action.yml](./action.yml) for more detailed information.
|
||||
|
||||
| Input Parameter | Description | Default Value |
|
||||
| ------------------------- | ---------------------------------------------------------------------------------------- | ------------- |
|
||||
| host | SSH host address | |
|
||||
| port | SSH port number | 22 |
|
||||
| passphrase | SSH key passphrase | |
|
||||
| username | SSH username | |
|
||||
| password | SSH password | |
|
||||
| protocol | SSH protocol version (tcp, tcp4, tcp6) | tcp |
|
||||
| sync | Enable synchronous execution if multiple hosts are specified | false |
|
||||
| use_insecure_cipher | Include more ciphers with use_insecure_cipher | false |
|
||||
| cipher | Allowed cipher algorithms. If unspecified, sensible defaults are used | |
|
||||
| timeout | Timeout duration for SSH to host | 30s |
|
||||
| command_timeout | Timeout duration for SSH command | 10m |
|
||||
| key | Content of SSH private key. e.g., raw content of ~/.ssh/id_rsa | |
|
||||
| key_path | Path of SSH private key | |
|
||||
| fingerprint | SHA256 fingerprint of the host public key | |
|
||||
| proxy_host | SSH proxy host | |
|
||||
| proxy_port | SSH proxy port | 22 |
|
||||
| proxy_protocol | SSH proxy protocol version (tcp, tcp4, tcp6) | tcp |
|
||||
| proxy_username | SSH proxy username | |
|
||||
| proxy_password | SSH proxy password | |
|
||||
| proxy_passphrase | SSH proxy key passphrase | |
|
||||
| proxy_timeout | Timeout for SSH to proxy host | 30s |
|
||||
| proxy_key | Content of SSH proxy private key | |
|
||||
| proxy_key_path | Path of SSH proxy private key | |
|
||||
| proxy_fingerprint | SHA256 fingerprint of the proxy host public key | |
|
||||
| proxy_cipher | Allowed cipher algorithms for the proxy | |
|
||||
| proxy_use_insecure_cipher | Include more ciphers with use_insecure_cipher for the proxy | false |
|
||||
| script | Execute commands | |
|
||||
| script_path | Execute commands from a file | |
|
||||
| envs | Pass environment variables to the shell script | |
|
||||
| envs_format | Flexible configuration of environment value transfer | |
|
||||
| debug | Enable debug mode | false |
|
||||
| allenvs | Pass the environment variables with prefix value of `GITHUB_` and `INPUT_` to the script | false |
|
||||
| request_pty | Request a pseudo-terminal from the server | false |
|
||||
| curl_insecure | Allow curl to connect to SSL sites without certificates | false |
|
||||
| version | drone-ssh binary version. If not specified, the latest version will be used. | |
|
||||
|
||||
**Note:** Users can add `set -e` in their shell script to achieve similar functionality to the removed `script_stop` option.
|
||||
|
||||
## Usage
|
||||
|
||||
Executing remote ssh commands.
|
||||
Executing remote SSH commands.
|
||||
|
||||
```yaml
|
||||
name: remote ssh command
|
||||
on: [push]
|
||||
jobs:
|
||||
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: executing remote ssh commands using password
|
||||
uses: appleboy/ssh-action@master
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
password: ${{ secrets.PASSWORD }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: whoami
|
||||
- name: executing remote ssh commands using password
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: linuxserver.io
|
||||
password: ${{ secrets.PASSWORD }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: whoami
|
||||
```
|
||||
|
||||
output:
|
||||
@ -35,36 +82,110 @@ output:
|
||||
======CMD======
|
||||
whoami
|
||||
======END======
|
||||
out: ***
|
||||
==========================================
|
||||
Successfully executed commands to all host.
|
||||
==========================================
|
||||
linuxserver.io
|
||||
===============================================
|
||||
✅ Successfully executed commands to all hosts.
|
||||
===============================================
|
||||
```
|
||||
|
||||
## Input variables
|
||||
### Setting up a SSH Key
|
||||
|
||||
see the [action.yml](./action.yml) file for more detail imformation.
|
||||
Follow the steps below to create and use SSH Keys.
|
||||
It is best practice to create SSH Keys on your local machine, not on a remote machine.
|
||||
Log in with the username specified in GitHub Secrets and generate an RSA Key-Pair:
|
||||
|
||||
* host - scp remote host
|
||||
* 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 `1m`
|
||||
* key - content of ssh private key. ex raw content of ~/.ssh/id_rsa
|
||||
* key_path - path of ssh private key
|
||||
* script - execute commands
|
||||
* script_stop - stop script after first failure
|
||||
* envs - pass environment variable to shell script
|
||||
* debug - enable debug mode
|
||||
### Generate rsa key
|
||||
|
||||
```bash
|
||||
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
|
||||
```
|
||||
|
||||
### Generate ed25519 key
|
||||
|
||||
```bash
|
||||
ssh-keygen -t ed25519 -a 200 -C "your_email@example.com"
|
||||
```
|
||||
|
||||
Add the newly generated key to the Authorized keys. Read more about authorized keys [here](https://www.ssh.com/ssh/authorized_keys/).
|
||||
|
||||
### Add rsa key into Authorized keys
|
||||
|
||||
```bash
|
||||
cat .ssh/id_rsa.pub | ssh b@B 'cat >> .ssh/authorized_keys'
|
||||
```
|
||||
|
||||
### Add ed25519 key into Authorized keys
|
||||
|
||||
```bash
|
||||
cat .ssh/id_ed25519.pub | ssh b@B 'cat >> .ssh/authorized_keys'
|
||||
```
|
||||
|
||||
Copy the Private Key content and paste it into GitHub Secrets.
|
||||
|
||||
### Copy rsa Private key
|
||||
|
||||
Before copying the private key, install the `clip` command as shown below:
|
||||
|
||||
```bash
|
||||
# Ubuntu
|
||||
sudo apt-get install xclip
|
||||
```
|
||||
|
||||
Copy the private key:
|
||||
|
||||
```bash
|
||||
# macOS
|
||||
pbcopy < ~/.ssh/id_rsa
|
||||
# Ubuntu
|
||||
xclip < ~/.ssh/id_rsa
|
||||
```
|
||||
|
||||
Starting from and including the comment section `-----BEGIN OPENSSH PRIVATE KEY-----` and ending at and including the comment section `-----END OPENSSH PRIVATE KEY-----`, copy the private key and paste it into GitHub Secrets.
|
||||
|
||||
### Copy ed25519 Private key
|
||||
|
||||
```bash
|
||||
# macOS
|
||||
pbcopy < ~/.ssh/id_ed25519
|
||||
# Ubuntu
|
||||
xclip < ~/.ssh/id_ed25519
|
||||
```
|
||||
|
||||
See detailed information about [SSH login without a password](http://www.linuxproblem.org/art_9.html).
|
||||
|
||||
**Note**: Depending on your version of SSH, you might also need to make the following changes:
|
||||
|
||||
- Put the public key in `.ssh/authorized_keys2`
|
||||
- Change the permissions of `.ssh` to 700
|
||||
- Change the permissions of `.ssh/authorized_keys2` to 640
|
||||
|
||||
### If you are using OpenSSH
|
||||
|
||||
If you are currently using OpenSSH and are getting the following error:
|
||||
|
||||
```bash
|
||||
ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey]
|
||||
```
|
||||
|
||||
Ensure that your chosen key algorithm is supported. On Ubuntu 20.04 or later, you must explicitly allow the use of the ssh-rsa algorithm. Add the following line to your OpenSSH daemon file (either `/etc/ssh/sshd_config` or a drop-in file under `/etc/ssh/sshd_config.d/`):
|
||||
|
||||
```bash
|
||||
CASignatureAlgorithms +ssh-rsa
|
||||
```
|
||||
|
||||
Alternatively, `ed25519` keys are accepted by default in OpenSSH. You can use this instead of rsa if needed:
|
||||
|
||||
```bash
|
||||
ssh-keygen -t ed25519 -a 200 -C "your_email@example.com"
|
||||
```
|
||||
|
||||
### Example
|
||||
|
||||
Executing remote ssh commands using password.
|
||||
#### Executing remote ssh commands using password
|
||||
|
||||
```yaml
|
||||
- name: executing remote ssh commands using password
|
||||
uses: appleboy/ssh-action@master
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
@ -73,11 +194,11 @@ Executing remote ssh commands using password.
|
||||
script: whoami
|
||||
```
|
||||
|
||||
Using private key
|
||||
#### Using private key
|
||||
|
||||
```yaml
|
||||
- name: executing remote ssh commands using ssh key
|
||||
uses: appleboy/ssh-action@master
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
@ -86,11 +207,11 @@ Using private key
|
||||
script: whoami
|
||||
```
|
||||
|
||||
Multiple Commands
|
||||
#### Multiple Commands
|
||||
|
||||
```yaml
|
||||
- name: multiple command
|
||||
uses: appleboy/ssh-action@master
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
@ -103,48 +224,207 @@ Multiple Commands
|
||||
|
||||

|
||||
|
||||
Multiple Hosts
|
||||
|
||||
```diff
|
||||
uses: appleboy/ssh-action@master
|
||||
with:
|
||||
- host: "foo.com"
|
||||
+ host: "foo.com,bar.com"
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
```
|
||||
|
||||
Pass environment variable to shell script
|
||||
|
||||
```diff
|
||||
uses: appleboy/ssh-action@master
|
||||
+ env:
|
||||
+ FOO: "BAR"
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
+ envs: FOO
|
||||
script: |
|
||||
echo "I am $FOO"
|
||||
echo "I am $BAR"
|
||||
```
|
||||
|
||||
Stop script after first failure. ex: missing `abc` folder
|
||||
#### Commands from a file
|
||||
|
||||
```yaml
|
||||
- name: stop script if command error
|
||||
uses: appleboy/ssh-action@master
|
||||
- name: file commands
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script_stop: true
|
||||
script: "mkdir abc/def,ls -al"
|
||||
script_path: scripts/script.sh
|
||||
```
|
||||
|
||||
#### Multiple Hosts
|
||||
|
||||
```diff
|
||||
- name: multiple host
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
- host: "foo.com"
|
||||
+ host: "foo.com,bar.com"
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
```
|
||||
|
||||
The default value of `port` is `22`.
|
||||
|
||||
#### Multiple hosts with different port
|
||||
|
||||
```diff
|
||||
- name: multiple host
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
- host: "foo.com"
|
||||
+ host: "foo.com:1234,bar.com:5678"
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
```
|
||||
|
||||
#### Synchronous execution on multiple hosts
|
||||
|
||||
```diff
|
||||
- name: multiple host
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: "foo.com,bar.com"
|
||||
+ sync: true
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
```
|
||||
|
||||
#### Pass environment variable to shell script
|
||||
|
||||
```diff
|
||||
- name: pass environment
|
||||
uses: appleboy/ssh-action@v1
|
||||
+ env:
|
||||
+ FOO: "BAR"
|
||||
+ BAR: "FOO"
|
||||
+ SHA: ${{ github.sha }}
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
+ envs: FOO,BAR,SHA
|
||||
script: |
|
||||
echo "I am $FOO"
|
||||
echo "I am $BAR"
|
||||
echo "sha: $SHA"
|
||||
```
|
||||
|
||||
_Inside `env` object, you need to pass every environment variable as a string, passing `Integer` data type or any other may output unexpected results._
|
||||
|
||||
#### How to connect remote server using `ProxyCommand`?
|
||||
|
||||
```bash
|
||||
+--------+ +----------+ +-----------+
|
||||
| Laptop | <--> | Jumphost | <--> | FooServer |
|
||||
+--------+ +----------+ +-----------+
|
||||
```
|
||||
|
||||
in your `~/.ssh/config`, you will see the following.
|
||||
|
||||
```bash
|
||||
Host Jumphost
|
||||
HostName Jumphost
|
||||
User ubuntu
|
||||
Port 22
|
||||
IdentityFile ~/.ssh/keys/jump_host.pem
|
||||
|
||||
Host FooServer
|
||||
HostName FooServer
|
||||
User ubuntu
|
||||
Port 22
|
||||
ProxyCommand ssh -q -W %h:%p Jumphost
|
||||
```
|
||||
|
||||
#### How to convert to YAML format of GitHubActions
|
||||
|
||||
```diff
|
||||
- name: ssh proxy command
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
+ proxy_host: ${{ secrets.PROXY_HOST }}
|
||||
+ proxy_username: ${{ secrets.PROXY_USERNAME }}
|
||||
+ proxy_key: ${{ secrets.PROXY_KEY }}
|
||||
+ proxy_port: ${{ secrets.PROXY_PORT }}
|
||||
script: |
|
||||
mkdir abc/def
|
||||
ls -al
|
||||
```
|
||||
|
||||
#### Protecting a Private Key
|
||||
|
||||
The purpose of the passphrase is usually to encrypt the private key.
|
||||
This makes the key file by itself useless to an attacker.
|
||||
It is not uncommon for files to leak from backups or decommissioned hardware, and hackers commonly exfiltrate files from compromised systems.
|
||||
|
||||
```diff
|
||||
- name: ssh key passphrase
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
+ passphrase: ${{ secrets.PASSPHRASE }}
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
```
|
||||
|
||||
#### Using host fingerprint verification
|
||||
|
||||
Setting up SSH host fingerprint verification can help to prevent Person-in-the-Middle attacks. Before setting this up, run the command below to get your SSH host fingerprint. Remember to replace `ed25519` with your appropriate key type (`rsa`, `dsa`, etc.) that your server is using and `example.com` with your host.
|
||||
|
||||
In modern OpenSSH releases, the _default_ key types to be fetched are `rsa` (since version 5.1), `ecdsa` (since version 6.0), and `ed25519` (since version 6.7).
|
||||
|
||||
```sh
|
||||
ssh example.com ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key.pub | cut -d ' ' -f2
|
||||
```
|
||||
|
||||
Now you can adjust you config:
|
||||
|
||||
```diff
|
||||
- name: ssh key passphrase
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
+ fingerprint: ${{ secrets.FINGERPRINT }}
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
```
|
||||
|
||||
## Q&A
|
||||
|
||||
### Command not found (npm or other command)
|
||||
|
||||
See the [issue comment](https://github.com/appleboy/ssh-action/issues/31#issuecomment-1006565847) about interactive vs non interactive shell. Thanks @kocyigityunus for the solution.
|
||||
|
||||
If you are running a command in a non-interactive shell, like ssh-action, on many Linux distros,
|
||||
|
||||
`/etc/bash.bashrc` file has a specific command that returns only, so some of the files didn't run and some specific commands doesn't add to path,
|
||||
|
||||
```sh
|
||||
# /etc/bash.bashrc
|
||||
# System-wide .bashrc file for interactive bash(1) shells.
|
||||
|
||||
# To enable the settings / commands in this file for login shells as well,
|
||||
# this file has to be sourced in /etc/profile.
|
||||
|
||||
# If not running interactively, don't do anything
|
||||
[ -z "$PS1" ] && return`
|
||||
```
|
||||
|
||||
comment out the line that returns early, and everything should work fine. Alternatively, you can use the real paths of the commands you want to use.
|
||||
|
||||
## Contributing
|
||||
|
||||
We would love for you to contribute to `appleboy/ssh-action`, pull requests are welcome!
|
||||
|
||||
## License
|
||||
|
||||
The scripts and documentation in this project are released under the [MIT License](LICENSE)
|
||||
|
405
README.zh-cn.md
Normal file
405
README.zh-cn.md
Normal file
@ -0,0 +1,405 @@
|
||||
# 🚀 用于 GitHub Actions 的 SSH
|
||||
|
||||
[English](./README.md) | [繁體中文](./README.zh-tw.md) | 简体中文
|
||||
|
||||
一个用于执行远程 SSH 命令的 [GitHub Action](https://github.com/features/actions)。
|
||||
|
||||

|
||||
|
||||
[](https://github.com/appleboy/ssh-action/actions/workflows/main.yml)
|
||||
|
||||
该项目使用 [Golang](https://go.dev) 和 [drone-ssh](https://github.com/appleboy/drone-ssh) 构建。🚀
|
||||
|
||||
## 输入变量
|
||||
|
||||
有关更详细的信息,请参阅 [action.yml](./action.yml)。
|
||||
|
||||
| 输入参数 | 描述 | 默认值 |
|
||||
| ------------------------- | ----------------------------------------------------- | ------ |
|
||||
| host | SSH 主机地址 | |
|
||||
| port | SSH 端口号 | 22 |
|
||||
| passphrase | SSH 密钥密码短语 | |
|
||||
| username | SSH 用户名 | |
|
||||
| password | SSH 密码 | |
|
||||
| protocol | SSH 协议版本(tcp, tcp4, tcp6) | tcp |
|
||||
| sync | 如果指定了多个主机,则启用同步执行 | false |
|
||||
| use_insecure_cipher | 使用不安全的密码算法 | false |
|
||||
| cipher | 允许的密码算法。如果未指定,则使用适当的默认值 | |
|
||||
| timeout | SSH 连接到主机的超时时间 | 30s |
|
||||
| command_timeout | SSH 命令的超时时间 | 10m |
|
||||
| key | SSH 私钥的内容,例如 ~/.ssh/id_rsa 的原始内容 | |
|
||||
| key_path | SSH 私钥的路径 | |
|
||||
| fingerprint | 主机公钥的 SHA256 指纹 | |
|
||||
| proxy_host | SSH 代理主机 | |
|
||||
| proxy_port | SSH 代理端口 | 22 |
|
||||
| proxy_protocol | SSH 代理协议版本(tcp, tcp4, tcp6) | tcp |
|
||||
| proxy_username | SSH 代理用户名 | |
|
||||
| proxy_password | SSH 代理密码 | |
|
||||
| proxy_passphrase | SSH 代理密钥密码短语 | |
|
||||
| proxy_timeout | SSH 连接到代理主机的超时时间 | 30s |
|
||||
| proxy_key | SSH 代理私钥的内容 | |
|
||||
| proxy_key_path | SSH 代理私钥的路径 | |
|
||||
| proxy_fingerprint | 代理主机公钥的 SHA256 指纹 | |
|
||||
| proxy_cipher | 代理允许的密码算法 | |
|
||||
| proxy_use_insecure_cipher | 使用不安全的密码算法 | false |
|
||||
| script | 执行命令 | |
|
||||
| script_path | 从文件执行命令 | |
|
||||
| envs | 传递环境变量到 shell 脚本 | |
|
||||
| envs_format | 环境变量传递的灵活配置 | |
|
||||
| debug | 启用调试模式 | false |
|
||||
| allenvs | 将带有 `GITHUB_` 和 `INPUT_` 前缀的环境变量传递给脚本 | false |
|
||||
| request_pty | 请求伪终端 | false |
|
||||
| curl_insecure | 在 curl 中使用不安全的证书验证 | false |
|
||||
| version | drone-ssh 版本号。若未指定,将使用最新版本。 | |
|
||||
|
||||
**注意:** 用户可以在他们的 shell 脚本中添加 `set -e` 以实现类似于已删除的 `script_stop` 选项的功能。
|
||||
|
||||
## 使用方法
|
||||
|
||||
执行远程 SSH 命令。
|
||||
|
||||
```yaml
|
||||
name: remote ssh command
|
||||
on: [push]
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: executing remote ssh commands using password
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: linuxserver.io
|
||||
password: ${{ secrets.PASSWORD }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: whoami
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```sh
|
||||
======CMD======
|
||||
whoami
|
||||
======END======
|
||||
linuxserver.io
|
||||
===============================================
|
||||
✅ Successfully executed commands to all hosts.
|
||||
===============================================
|
||||
```
|
||||
|
||||
### 设置 SSH 密钥
|
||||
|
||||
请按照以下步骤创建和使用 SSH 密钥。
|
||||
最佳做法是在本地机器上创建 SSH 密钥,而不是在远程机器上。
|
||||
使用 GitHub Secrets 中指定的用户名登录并生成 RSA 密钥对:
|
||||
|
||||
### 生成 RSA 密钥
|
||||
|
||||
```bash
|
||||
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
|
||||
```
|
||||
|
||||
### 生成 ed25519 密钥
|
||||
|
||||
```bash
|
||||
ssh-keygen -t ed25519 -a 200 -C "your_email@example.com"
|
||||
```
|
||||
|
||||
将新生成的密钥添加到已授权的密钥中。详细了解已授权的密钥请点[此处](https://www.ssh.com/ssh/authorized_keys/)。
|
||||
|
||||
### 将 RSA 密钥添加到已授权密钥中
|
||||
|
||||
```bash
|
||||
cat .ssh/id_rsa.pub | ssh b@B 'cat >> .ssh/authorized_keys'
|
||||
```
|
||||
|
||||
### 将 ed25519 密钥添加到已授权密钥中
|
||||
|
||||
```bash
|
||||
cat .ssh/id_ed25519.pub | ssh b@B 'cat >> .ssh/authorized_keys'
|
||||
```
|
||||
|
||||
复制私钥内容,然后将其粘贴到 GitHub Secrets 中。
|
||||
|
||||
### 复制 RSA 私钥内容
|
||||
|
||||
在复制私钥之前,按照以下步骤安装 `clip` 命令:
|
||||
|
||||
```bash
|
||||
# Ubuntu
|
||||
sudo apt-get install xclip
|
||||
```
|
||||
|
||||
复制私钥:
|
||||
|
||||
```bash
|
||||
# macOS
|
||||
pbcopy < ~/.ssh/id_rsa
|
||||
# Ubuntu
|
||||
xclip < ~/.ssh/id_rsa
|
||||
```
|
||||
|
||||
从包含注释部分 `-----BEGIN OPENSSH PRIVATE KEY-----` 开始,到包含注释部分 `-----END OPENSSH PRIVATE KEY-----` 结束,复制私钥并将其粘贴到 GitHub Secrets 中。
|
||||
|
||||
### 复制 ed25519 私钥内容
|
||||
|
||||
```bash
|
||||
# macOS
|
||||
pbcopy < ~/.ssh/id_ed25519
|
||||
# Ubuntu
|
||||
xclip < ~/.ssh/id_ed25519
|
||||
```
|
||||
|
||||
有关无需密码登录 SSH 的详细信息,请[见该网站](http://www.linuxproblem.org/art_9.html)。
|
||||
|
||||
**注意**:根据您的 SSH 版本,您可能还需要进行以下更改:
|
||||
|
||||
- 将公钥放在 `.ssh/authorized_keys2` 中
|
||||
- 将 `.ssh` 的权限更改为 700
|
||||
- 将 `.ssh/authorized_keys2` 的权限更改为 640
|
||||
|
||||
### 如果你使用的是 OpenSSH
|
||||
|
||||
如果您正在使用 OpenSSH,并出现以下错误:
|
||||
|
||||
```bash
|
||||
ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey]
|
||||
```
|
||||
|
||||
请确保您所选择的密钥算法得到支持。在 Ubuntu 20.04 或更高版本上,您必须明确允许使用 ssh-rsa 算法。请在 OpenSSH 守护进程文件中添加以下行(它可以是 `/etc/ssh/sshd_config` 或 `/etc/ssh/sshd_config.d/` 中的一个附加文件):
|
||||
|
||||
```bash
|
||||
CASignatureAlgorithms +ssh-rsa
|
||||
```
|
||||
|
||||
或者,`ed25519` 密钥在 OpenSSH 中默认被接受。如果需要,您可以使用它来替代 RSA:
|
||||
|
||||
```bash
|
||||
ssh-keygen -t ed25519 -a 200 -C "your_email@example.com"
|
||||
```
|
||||
|
||||
### 示例
|
||||
|
||||
#### 使用密码执行远程 SSH 命令
|
||||
|
||||
```yaml
|
||||
- name: executing remote ssh commands using password
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
password: ${{ secrets.PASSWORD }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: whoami
|
||||
```
|
||||
|
||||
#### 使用私钥
|
||||
|
||||
```yaml
|
||||
- name: executing remote ssh commands using ssh key
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: whoami
|
||||
```
|
||||
|
||||
#### 多个命令
|
||||
|
||||
```yaml
|
||||
- name: multiple command
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
```
|
||||
|
||||

|
||||
|
||||
#### 从文件执行命令
|
||||
|
||||
```yaml
|
||||
- name: file commands
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script_path: scripts/script.sh
|
||||
```
|
||||
|
||||
#### 多台主机
|
||||
|
||||
```diff
|
||||
- name: multiple host
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
- host: "foo.com"
|
||||
+ host: "foo.com,bar.com"
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
```
|
||||
|
||||
默认的 `port` 值是 `22`。
|
||||
|
||||
#### 多个不同端口的主机
|
||||
|
||||
```diff
|
||||
- name: multiple host
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
- host: "foo.com"
|
||||
+ host: "foo.com:1234,bar.com:5678"
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
```
|
||||
|
||||
#### 在多台主机上同步执行
|
||||
|
||||
```diff
|
||||
- name: multiple host
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: "foo.com,bar.com"
|
||||
+ sync: true
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
```
|
||||
|
||||
#### 将环境变量传递到 shell 脚本
|
||||
|
||||
```diff
|
||||
- name: pass environment
|
||||
uses: appleboy/ssh-action@v1
|
||||
+ env:
|
||||
+ FOO: "BAR"
|
||||
+ BAR: "FOO"
|
||||
+ SHA: ${{ github.sha }}
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
+ envs: FOO,BAR,SHA
|
||||
script: |
|
||||
echo "I am $FOO"
|
||||
echo "I am $BAR"
|
||||
echo "sha: $SHA"
|
||||
```
|
||||
|
||||
_在 `env` 对象中,您需要将每个环境变量作为字符串传递,传递 `Integer` 数据类型或任何其他类型可能会产生意外结果。_
|
||||
|
||||
#### 如何使用 `ProxyCommand` 连接远程服务器?
|
||||
|
||||
```bash
|
||||
+--------+ +----------+ +-----------+
|
||||
| Laptop | <--> | Jumphost | <--> | FooServer |
|
||||
+--------+ +----------+ +-----------+
|
||||
```
|
||||
|
||||
在您的 `~/.ssh/config` 文件中,您会看到以下内容。
|
||||
|
||||
```bash
|
||||
Host Jumphost
|
||||
HostName Jumphost
|
||||
User ubuntu
|
||||
Port 22
|
||||
IdentityFile ~/.ssh/keys/jump_host.pem
|
||||
|
||||
Host FooServer
|
||||
HostName FooServer
|
||||
User ubuntu
|
||||
Port 22
|
||||
ProxyCommand ssh -q -W %h:%p Jumphost
|
||||
```
|
||||
|
||||
#### 如何将其转换为 GitHubActions 的 YAML 格式?
|
||||
|
||||
```diff
|
||||
- name: ssh proxy command
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
+ proxy_host: ${{ secrets.PROXY_HOST }}
|
||||
+ proxy_username: ${{ secrets.PROXY_USERNAME }}
|
||||
+ proxy_key: ${{ secrets.PROXY_KEY }}
|
||||
+ proxy_port: ${{ secrets.PROXY_PORT }}
|
||||
script: |
|
||||
mkdir abc/def
|
||||
ls -al
|
||||
```
|
||||
|
||||
#### 保护私钥
|
||||
|
||||
密码短语通常用于加密私钥。这使得密钥文件本身对攻击者无用。文件泄露可能来自备份或停用的硬件,黑客通常可以从受攻击系统中泄露文件。
|
||||
|
||||
```diff
|
||||
- name: ssh key passphrase
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
+ passphrase: ${{ secrets.PASSPHRASE }}
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
```
|
||||
|
||||
#### 使用主机指纹验证
|
||||
|
||||
设置 SSH 主机指纹验证可以帮助防止中间人攻击。在设置之前,运行以下命令以获取 SSH 主机指纹。请记得将 `ed25519` 替换为您适当的密钥类型(`rsa`、 `dsa`等),而 `example.com` 则替换为您的主机。
|
||||
|
||||
在现代 OpenSSH 版本中,默认提取的密钥类型是 `rsa`(从版本 5.1 开始)、`ecdsa`(从版本 6.0 开始)和 `ed25519`(从版本 6.7 开始)。
|
||||
|
||||
```sh
|
||||
ssh example.com ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key.pub | cut -d ' ' -f2
|
||||
```
|
||||
|
||||
现在您可以调整您的配置:
|
||||
|
||||
```diff
|
||||
- name: ssh key passphrase
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
+ fingerprint: ${{ secrets.FINGERPRINT }}
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
```
|
||||
|
||||
## 贡献
|
||||
|
||||
我们非常希望您为 `appleboy/ssh-action` 做出贡献,欢迎提交请求!
|
||||
|
||||
## 授权方式
|
||||
|
||||
本项目中的脚本和文档采用 [MIT 许可证](LICENSE) 发布。
|
401
README.zh-tw.md
Normal file
401
README.zh-tw.md
Normal file
@ -0,0 +1,401 @@
|
||||
# 🚀 GitHub Actions 的 SSH
|
||||
|
||||
[English](./README.md) | 繁體中文 | [简体中文](./README.zh-cn.md)
|
||||
|
||||
[GitHub Action](https://github.com/features/actions) 用於執行遠端 SSH 命令。
|
||||
|
||||

|
||||
|
||||
[](https://github.com/appleboy/ssh-action/actions/workflows/main.yml)
|
||||
|
||||
此專案使用 [Golang](https://go.dev) 和 [drone-ssh](https://github.com/appleboy/drone-ssh) 建立。🚀
|
||||
|
||||
## 輸入變數
|
||||
|
||||
請參閱 [action.yml](./action.yml) 以獲取更詳細的信息。
|
||||
|
||||
| 輸入參數 | 描述 | 預設值 |
|
||||
| ------------------------- | ----------------------------------------------------- | ------ |
|
||||
| host | SSH 主機地址 | |
|
||||
| port | SSH 埠號 | 22 |
|
||||
| passphrase | SSH 金鑰密碼 | |
|
||||
| username | SSH 使用者名稱 | |
|
||||
| password | SSH 密碼 | |
|
||||
| protocol | SSH 協議版本 (tcp, tcp4, tcp6) | tcp |
|
||||
| sync | 如果有多個主機,啟用同步執行 | false |
|
||||
| use_insecure_cipher | 包含更多不安全的加密算法 | false |
|
||||
| cipher | 允許的加密算法。如果未指定,則使用合理的預設值 | |
|
||||
| timeout | SSH 連接主機的超時時間 | 30s |
|
||||
| command_timeout | SSH 命令的超時時間 | 10m |
|
||||
| key | SSH 私鑰的內容。例如,~/.ssh/id_rsa 的原始內容 | |
|
||||
| key_path | SSH 私鑰的路徑 | |
|
||||
| fingerprint | 主機公鑰的 SHA256 指紋 | |
|
||||
| proxy_host | SSH 代理主機 | |
|
||||
| proxy_port | SSH 代理埠號 | 22 |
|
||||
| proxy_protocol | SSH 代理協議版本 (tcp, tcp4, tcp6) | tcp |
|
||||
| proxy_username | SSH 代理使用者名稱 | |
|
||||
| proxy_password | SSH 代理密碼 | |
|
||||
| proxy_passphrase | SSH 代理金鑰密碼 | |
|
||||
| proxy_timeout | SSH 連接代理主機的超時時間 | 30s |
|
||||
| proxy_key | SSH 代理私鑰的內容 | |
|
||||
| proxy_key_path | SSH 代理私鑰的路徑 | |
|
||||
| proxy_fingerprint | 代理主機公鑰的 SHA256 指紋 | |
|
||||
| proxy_cipher | 代理允許的加密算法 | |
|
||||
| proxy_use_insecure_cipher | 包含更多不安全的加密算法 | false |
|
||||
| script | 執行命令 | |
|
||||
| script_path | 從文件中執行命令 | |
|
||||
| envs | 將環境變數傳遞給 shell 腳本 | |
|
||||
| envs_format | 環境值傳遞的靈活配置 | |
|
||||
| debug | 啟用調試模式 | false |
|
||||
| allenvs | 將帶有 `GITHUB_` 和 `INPUT_` 前綴的環境變數傳遞給腳本 | false |
|
||||
| request_pty | 從伺服器請求偽終端 | false |
|
||||
| curl_insecure | 在 curl 命令中使用不安全的 SSL 證書驗證 | false |
|
||||
| version | drone-ssh 版本號。若未指定,將使用最新版本。 | |
|
||||
|
||||
**注意:** 用戶可以在他們的 shell 腳本中添加 `set -e` 以實現類似於已刪除的 `script_stop` 選項的功能。
|
||||
|
||||
## 用法
|
||||
|
||||
執行遠端 SSH 命令
|
||||
|
||||
```yaml
|
||||
name: remote ssh command
|
||||
on: [push]
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: executing remote ssh commands using password
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: linuxserver.io
|
||||
password: ${{ secrets.PASSWORD }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: whoami
|
||||
```
|
||||
|
||||
畫面輸出
|
||||
|
||||
```sh
|
||||
======CMD======
|
||||
whoami
|
||||
======END======
|
||||
linuxserver.io
|
||||
===============================================
|
||||
✅ Successfully executed commands to all hosts.
|
||||
===============================================
|
||||
```
|
||||
|
||||
### 設置 SSH 金鑰
|
||||
|
||||
請在創建 SSH 金鑰並使用 SSH 金鑰時遵循以下步驟。最佳做法是在本地機器上創建 SSH 金鑰而不是遠端機器上。請使用 Github Secrets 中指定的用戶名登錄。生成 RSA 金鑰:
|
||||
|
||||
### 生成 RSA 金鑰
|
||||
|
||||
```bash
|
||||
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
|
||||
```
|
||||
|
||||
### 生成 ed25519 金鑰
|
||||
|
||||
```bash
|
||||
ssh-keygen -t ed25519 -a 200 -C "your_email@example.com"
|
||||
```
|
||||
|
||||
將新生成的金鑰添加到已授權的金鑰中。詳細了解已授權的金鑰請點擊[此處](https://www.ssh.com/ssh/authorized_keys/).
|
||||
|
||||
### 將 RSA 金鑰添加到已授權金鑰中
|
||||
|
||||
```bash
|
||||
cat .ssh/id_rsa.pub | ssh b@B 'cat >> .ssh/authorized_keys'
|
||||
```
|
||||
|
||||
### 將 ed25519 金鑰添加到已授權金鑰中
|
||||
|
||||
```bash
|
||||
cat .ssh/id_ed25519.pub | ssh b@B 'cat >> .ssh/authorized_keys'
|
||||
```
|
||||
|
||||
複製私鑰內容,然後將其粘貼到 Github Secrets 中。
|
||||
|
||||
### 複製 rsa 私鑰內容
|
||||
|
||||
在複製私鑰之前,請按照以下說明安裝 `clip` 命令:
|
||||
|
||||
```bash
|
||||
# Ubuntu
|
||||
sudo apt-get install xclip
|
||||
```
|
||||
|
||||
複製私鑰:
|
||||
|
||||
```bash
|
||||
# macOS
|
||||
pbcopy < ~/.ssh/id_rsa
|
||||
# Ubuntu
|
||||
xclip < ~/.ssh/id_rsa
|
||||
```
|
||||
|
||||
從包含註釋部分 `-----BEGIN OPENSSH PRIVATE KEY-----` 開始,到包含註釋部分 `-----END OPENSSH PRIVATE KEY-----` 結束,複製私鑰並將其粘貼到 GitHub Secrets 中。
|
||||
|
||||
### 複製 ed25519 私鑰內容
|
||||
|
||||
```bash
|
||||
# macOS
|
||||
pbcopy < ~/.ssh/id_ed25519
|
||||
# Ubuntu
|
||||
xclip < ~/.ssh/id_ed25519
|
||||
```
|
||||
|
||||
有關無需密碼登錄 SSH 的詳細信息,請[參見該網站](http://www.linuxproblem.org/art_9.html)。
|
||||
|
||||
**注意**:根據您的 SSH 版本,您可能還需要進行以下更改:
|
||||
|
||||
- 將公鑰放在 `.ssh/authorized_keys2` 中
|
||||
- 將 `.ssh` 的權限更改為 700
|
||||
- 將 `.ssh/authorized_keys2` 的權限更改為 640
|
||||
|
||||
### 如果你使用的是 OpenSSH
|
||||
|
||||
如果您正在使用 OpenSSH,並出現以下錯誤:
|
||||
|
||||
```bash
|
||||
ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey]
|
||||
```
|
||||
|
||||
請確保您所選擇的密鑰演算法得到支援。在 Ubuntu 20.04 或更高版本上,您必須明確允許使用 SSH-RSA 演算法。請在 OpenSSH 守護進程文件中添加以下行(它可以是 `/etc/ssh/sshd_config` 或 `/etc/ssh/sshd_config.d/` 中的一個附著文件):
|
||||
|
||||
```bash
|
||||
CASignatureAlgorithms +ssh-rsa
|
||||
```
|
||||
|
||||
或者,`Ed25519` 密鑰在 OpenSSH 中默認被接受。如果需要,您可以使用它來替代 RSA。
|
||||
|
||||
```bash
|
||||
ssh-keygen -t ed25519 -a 200 -C "your_email@example.com"
|
||||
```
|
||||
|
||||
### Example
|
||||
|
||||
#### 使用密碼執行遠端 SSH 命令
|
||||
|
||||
```yaml
|
||||
- name: executing remote ssh commands using password
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
password: ${{ secrets.PASSWORD }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: whoami
|
||||
```
|
||||
|
||||
#### 使用私鑰
|
||||
|
||||
```yaml
|
||||
- name: executing remote ssh commands using ssh key
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: whoami
|
||||
```
|
||||
|
||||
#### 多個命令
|
||||
|
||||
```yaml
|
||||
- name: multiple command
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
```
|
||||
|
||||

|
||||
|
||||
#### 從文件中執行命令
|
||||
|
||||
```yaml
|
||||
- name: file commands
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script_path: scripts/script.sh
|
||||
```
|
||||
|
||||
#### 多台主機
|
||||
|
||||
```diff
|
||||
- name: multiple host
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
- host: "foo.com"
|
||||
+ host: "foo.com,bar.com"
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
```
|
||||
|
||||
#### 多個不同端口的主機
|
||||
|
||||
```diff
|
||||
- name: multiple host
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
- host: "foo.com"
|
||||
+ host: "foo.com:1234,bar.com:5678"
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
```
|
||||
|
||||
#### 在多個主機上同步執行
|
||||
|
||||
```diff
|
||||
- name: multiple host
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: "foo.com,bar.com"
|
||||
+ sync: true
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
```
|
||||
|
||||
#### 將環境變量傳遞到 Shell 腳本
|
||||
|
||||
```diff
|
||||
- name: pass environment
|
||||
uses: appleboy/ssh-action@v1
|
||||
+ env:
|
||||
+ FOO: "BAR"
|
||||
+ BAR: "FOO"
|
||||
+ SHA: ${{ github.sha }}
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
+ envs: FOO,BAR,SHA
|
||||
script: |
|
||||
echo "I am $FOO"
|
||||
echo "I am $BAR"
|
||||
echo "sha: $SHA"
|
||||
```
|
||||
|
||||
_在 `env` 對象中,您需要將每個環境變量作為字符串傳遞,傳遞 `Integer` 數據類型或任何其他類型可能會產生意外結果。_
|
||||
|
||||
#### 如何使用 `ProxyCommand` 連接遠程服務器?
|
||||
|
||||
```bash
|
||||
+--------+ +----------+ +-----------+
|
||||
| Laptop | <--> | Jumphost | <--> | FooServer |
|
||||
+--------+ +----------+ +-----------+
|
||||
```
|
||||
|
||||
在您的 `~/.ssh/config` 文件中,您會看到以下內容。
|
||||
|
||||
```bash
|
||||
Host Jumphost
|
||||
HostName Jumphost
|
||||
User ubuntu
|
||||
Port 22
|
||||
IdentityFile ~/.ssh/keys/jump_host.pem
|
||||
|
||||
Host FooServer
|
||||
HostName FooServer
|
||||
User ubuntu
|
||||
Port 22
|
||||
ProxyCommand ssh -q -W %h:%p Jumphost
|
||||
```
|
||||
|
||||
#### 如何將其轉換為 GitHubActions 的 YAML 格式?
|
||||
|
||||
```diff
|
||||
- name: ssh proxy command
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
+ proxy_host: ${{ secrets.PROXY_HOST }}
|
||||
+ proxy_username: ${{ secrets.PROXY_USERNAME }}
|
||||
+ proxy_key: ${{ secrets.PROXY_KEY }}
|
||||
+ proxy_port: ${{ secrets.PROXY_PORT }}
|
||||
script: |
|
||||
mkdir abc/def
|
||||
ls -al
|
||||
```
|
||||
|
||||
#### 如何保護私鑰?
|
||||
|
||||
密碼短語通常用於加密私鑰。這使得攻擊者無法單獨使用密鑰文件。文件泄露可能來自備份或停用的硬件,黑客通常可以從受攻擊系統中洩露文件。因此,保護私鑰非常重要。
|
||||
|
||||
```diff
|
||||
- name: ssh key passphrase
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
+ passphrase: ${{ secrets.PASSPHRASE }}
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
```
|
||||
|
||||
#### 使用主機指紋驗證
|
||||
|
||||
設置 SSH 主機指紋驗證可以幫助防止中間人攻擊。在設置之前,運行以下命令以獲取 SSH 主機指紋。請記得將 `ed25519` 替換為您的適當金鑰類型(`rsa`、 `dsa`等),而 `example.com` 則替換為您的主機。
|
||||
|
||||
現代 OpenSSH 版本中,需要提取的**默認金鑰**類型是 `rsa`(從版本 5.1 開始)、`ecdsa`(從版本 6.0 開始)和 `ed25519`(從版本 6.7 開始)。
|
||||
|
||||
```sh
|
||||
ssh example.com ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key.pub | cut -d ' ' -f2
|
||||
```
|
||||
|
||||
現在您可以調整您的配置:
|
||||
|
||||
```diff
|
||||
- name: ssh key passphrase
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.HOST }}
|
||||
username: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
port: ${{ secrets.PORT }}
|
||||
+ fingerprint: ${{ secrets.FINGERPRINT }}
|
||||
script: |
|
||||
whoami
|
||||
ls -al
|
||||
```
|
||||
|
||||
## 貢獻
|
||||
|
||||
我們非常希望您為 `appleboy/ssh-action` 做出貢獻,歡迎提交請求!
|
||||
|
||||
## 授權方式
|
||||
|
||||
本項目中的腳本和文檔采用 [MIT](LICENSE) 許可證 發布。
|
153
action.yml
153
action.yml
@ -1,40 +1,145 @@
|
||||
name: 'SSH Remote Commands'
|
||||
description: 'Executing remote ssh commands'
|
||||
author: 'Bo-Yi Wu'
|
||||
name: "SSH Remote Commands"
|
||||
description: "Executing remote ssh commands"
|
||||
author: "Bo-Yi Wu"
|
||||
inputs:
|
||||
host:
|
||||
description: 'ssh remote host'
|
||||
description: "SSH host address or IP to connect to."
|
||||
port:
|
||||
description: 'ssh remote port'
|
||||
default: 22
|
||||
description: "SSH port number for the connection."
|
||||
default: "22"
|
||||
passphrase:
|
||||
description: "Passphrase to decrypt the SSH private key if protected."
|
||||
username:
|
||||
description: 'ssh username'
|
||||
description: "SSH username for authentication on the remote server."
|
||||
password:
|
||||
description: 'ssh password'
|
||||
description: "SSH password for authentication (use secrets for sensitive data)."
|
||||
protocol:
|
||||
description: 'IP protocol version to use. Options: "tcp" (default), "tcp4" (IPv4 only), or "tcp6" (IPv6 only).'
|
||||
default: "tcp"
|
||||
sync:
|
||||
description: "When true, executes commands synchronously across multiple hosts (one after another)."
|
||||
use_insecure_cipher:
|
||||
description: "Enable additional legacy ciphers that might be less secure but more compatible with older systems."
|
||||
cipher:
|
||||
description: "Specify custom cipher algorithms for encryption. Leave empty to use secure defaults."
|
||||
timeout:
|
||||
description: 'timeout for ssh to remote host'
|
||||
description: "Maximum time to wait when establishing the SSH connection, e.g., '30s', '1m'."
|
||||
default: "30s"
|
||||
command_timeout:
|
||||
description: 'timeout for ssh command'
|
||||
default: "1m"
|
||||
description: "Maximum execution time for the remote commands before terminating, e.g., '10m', '1h'."
|
||||
default: "10m"
|
||||
key:
|
||||
description: 'content of ssh private key. ex raw content of ~/.ssh/id_rsa'
|
||||
description: "Raw content of the SSH private key for authentication (use secrets for sensitive data)."
|
||||
key_path:
|
||||
description: 'path of ssh private key'
|
||||
description: "Path to the SSH private key file on the runner."
|
||||
fingerprint:
|
||||
description: "SHA256 fingerprint of the host public key for verification to prevent MITM attacks."
|
||||
proxy_host:
|
||||
description: "Proxy server hostname or IP if connecting through an SSH jump host."
|
||||
proxy_port:
|
||||
description: "SSH port number for the proxy connection."
|
||||
default: "22"
|
||||
proxy_username:
|
||||
description: "Username for authentication on the proxy server."
|
||||
proxy_password:
|
||||
description: "Password for authentication on the proxy server (use secrets for sensitive data)."
|
||||
proxy_protocol:
|
||||
description: 'IP protocol version for proxy. Options: "tcp" (default), "tcp4" (IPv4 only), or "tcp6" (IPv6 only).'
|
||||
default: "tcp"
|
||||
proxy_passphrase:
|
||||
description: "Passphrase to decrypt the proxy SSH private key if protected."
|
||||
proxy_timeout:
|
||||
description: "Maximum time to wait when establishing the proxy SSH connection, e.g., '30s', '1m'."
|
||||
default: "30s"
|
||||
proxy_key:
|
||||
description: "Raw content of the SSH proxy private key for authentication (use secrets for sensitive data)."
|
||||
proxy_key_path:
|
||||
description: "Path to the SSH proxy private key file on the runner."
|
||||
proxy_fingerprint:
|
||||
description: "SHA256 fingerprint of the proxy host public key for verification."
|
||||
proxy_cipher:
|
||||
description: "Specify custom cipher algorithms for proxy connection encryption."
|
||||
proxy_use_insecure_cipher:
|
||||
description: "Enable additional legacy ciphers for proxy connections (less secure but more compatible)."
|
||||
script:
|
||||
description: 'execute commands'
|
||||
script_stop:
|
||||
description: 'stop script after first failure'
|
||||
default: false
|
||||
description: "Commands to execute on the remote server (inline script string)."
|
||||
script_path:
|
||||
description: "Path to a local file containing commands to execute on the remote server."
|
||||
envs:
|
||||
description: 'pass environment variable to shell script'
|
||||
description: "Environment variables to expose to the remote script, format: key=value,key2=value2."
|
||||
envs_format:
|
||||
description: "Format specification for environment variable transfer (for advanced usage)."
|
||||
debug:
|
||||
description: 'enable debug mode'
|
||||
default: false
|
||||
description: "Set to true to enable verbose logging for troubleshooting connection issues."
|
||||
allenvs:
|
||||
description: "When true, passes all GitHub Actions environment variables to the remote script."
|
||||
request_pty:
|
||||
description: "Request a pseudo-terminal from the server (required for interactive commands or sudo)."
|
||||
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-ssh to use.
|
||||
|
||||
outputs:
|
||||
stdout:
|
||||
description: "Standard output of the executed commands when capture_stdout is enabled."
|
||||
value: ${{ steps.entrypoint.outputs.stdout }}
|
||||
|
||||
runs:
|
||||
using: 'docker'
|
||||
image: 'Dockerfile'
|
||||
using: "composite"
|
||||
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_TIMEOUT: ${{ inputs.timeout }}
|
||||
INPUT_PROXY_TIMEOUT: ${{ inputs.proxy_timeout }}
|
||||
INPUT_COMMAND_TIMEOUT: ${{ inputs.command_timeout }}
|
||||
INPUT_SCRIPT: ${{ inputs.script }}
|
||||
INPUT_SCRIPT_FILE: ${{ inputs.script_path }}
|
||||
INPUT_ENVS: ${{ inputs.envs }}
|
||||
INPUT_ENVS_FORMAT: ${{ inputs.envs_format }}
|
||||
INPUT_DEBUG: ${{ inputs.debug }}
|
||||
INPUT_ALL_ENVS: ${{ inputs.allenvs }}
|
||||
INPUT_REQUEST_PTY: ${{ inputs.request_pty }}
|
||||
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_SYNC: ${{ inputs.sync }}
|
||||
INPUT_CAPTURE_STDOUT: ${{ inputs.capture_stdout }}
|
||||
INPUT_CURL_INSECURE: ${{ inputs.curl_insecure }}
|
||||
DRONE_SSH_VERSION: ${{ inputs.version }}
|
||||
|
||||
branding:
|
||||
icon: 'terminal'
|
||||
color: 'gray-dark'
|
||||
icon: "terminal"
|
||||
color: "gray-dark"
|
||||
|
@ -1,7 +1,56 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eu
|
||||
set -euo pipefail
|
||||
|
||||
export GITHUB="true"
|
||||
|
||||
sh -c "/bin/drone-ssh $*"
|
||||
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}"
|
||||
|
||||
function log_error() {
|
||||
echo "$1" >&2
|
||||
exit "$2"
|
||||
}
|
||||
|
||||
function detect_client_info() {
|
||||
CLIENT_PLATFORM="${SSH_CLIENT_OS:-$(uname -s | tr '[:upper:]' '[:lower:]')}"
|
||||
CLIENT_ARCH="${SSH_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_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
|
||||
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
|
||||
|
7
testdata/.ssh/id_ed25519
vendored
Normal file
7
testdata/.ssh/id_ed25519
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||
QyNTUxOQAAACDoi7FltQCqpWporKh61nJUPIeazUYdzdstncoeU5XS2AAAAKBF5e2SReXt
|
||||
kgAAAAtzc2gtZWQyNTUxOQAAACDoi7FltQCqpWporKh61nJUPIeazUYdzdstncoeU5XS2A
|
||||
AAAEBrsLG1vSg08yaQgYM46KQW93Lz2ZikS1tTMH35gfHhpOiLsWW1AKqlamisqHrWclQ8
|
||||
h5rNRh3N2y2dyh5TldLYAAAAFnlvdXJfZW1haWxAZXhhbXBsZS5jb20BAgMEBQYH
|
||||
-----END OPENSSH PRIVATE KEY-----
|
1
testdata/.ssh/id_ed25519.pub
vendored
Normal file
1
testdata/.ssh/id_ed25519.pub
vendored
Normal file
@ -0,0 +1 @@
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOiLsWW1AKqlamisqHrWclQ8h5rNRh3N2y2dyh5TldLY your_email@example.com
|
39
testdata/.ssh/id_passphrase
vendored
Normal file
39
testdata/.ssh/id_passphrase
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
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
|
||||
h55pSap77CEhEhE5FPZKuH9f7/E=
|
||||
-----END OPENSSH PRIVATE KEY-----
|
1
testdata/.ssh/id_passphrase.pub
vendored
Normal file
1
testdata/.ssh/id_passphrase.pub
vendored
Normal file
@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCuWKQh09Vlv3IRu/+oK18ws72VQS7PCXJaIEp1L+7HqC/6+plizaVgd9SjAg0UJSqvp+WfpU5I53hevE0Ip3s71Tsoeu1azWoi2Mbq3ycZ5ysh4htZZklKBkYsyW+2EdITPcmhA8rF+KiDRyuvk7fDo08G3YWgbCScY6VkLA06ReThCehAY54WNvgbx7lyvCWj1qYG0XjM7mTQHr3QN0JHJNdFaG3MCi1rTG2hK/owOlzcesIbzfM1VMIQG5HT4vNg/ULP0BTZ7pGtdvWlvR/660KQwc1tBxLqxI1dYoCgiS/gMyPxhOtNKTvhR/NR7e2sp/StkXURIxTHhj0KjKbnpXTQ2IndnesHAG9kDJ7c31SXastWpbXWhCIdRZk+KQsnmwobZlw3w1vfx2Dm7M2ZCcCgG/ArUPjY44nGOWO5Nz98QHyz3IocsKJXrGVo/3YpNNu72jkw7UGVMqh1dAe3ZMaCAC5pAAa0HKvkid7jdXawL2b//+vsAPSHdnEjP58= mtk10671@NB22040567
|
27
testdata/.ssh/id_rsa
vendored
Normal file
27
testdata/.ssh/id_rsa
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEA4e2D/qPN08pzTac+a8ZmlP1ziJOXk45CynMPtva0rtK/RB26
|
||||
VbfAF0hIJji7ltvnYnqCU9oFfvEM33cTn7T96+od8ib/Vz25YU8ZbstqtIskPuwC
|
||||
bv3K0mAHgsviJyRD7yM+QKTbBQEgbGuW6gtbMKhiYfiIB4Dyj7AdS/fk3v26wDgz
|
||||
7SHI5OBqu9bv1KhxQYdFEnU3PAtAqeccgzNpbH3eYLyGzuUxEIJlhpZ/uU2G9ppj
|
||||
/cSrONVPiI8Ahi4RrlZjmP5l57/sq1ClGulyLpFcMw68kP5FikyqHpHJHRBNgU57
|
||||
1y0Ph33SjBbs0haCIAcmreWEhGe+/OXnJe6VUQIDAQABAoIBAH97emORIm9DaVSD
|
||||
7mD6DqA7c5m5Tmpgd6eszU08YC/Vkz9oVuBPUwDQNIX8tT0m0KVs42VVPIyoj874
|
||||
bgZMJoucC1G8V5Bur9AMxhkShx9g9A7dNXJTmsKilRpk2TOk7wBdLp9jZoKoZBdJ
|
||||
jlp6FfaazQjjKD6zsCsMATwAoRCBpBNsmT6QDN0n0bIgY0tE6YGQaDdka0dAv68G
|
||||
R0VZrcJ9voT6+f+rgJLoojn2DAu6iXaM99Gv8FK91YCymbQlXXgrk6CyS0IHexN7
|
||||
V7a3k767KnRbrkqd3o6JyNun/CrUjQwHs1IQH34tvkWScbseRaFehcAm6mLT93RP
|
||||
muauvMECgYEA9AXGtfDMse0FhvDPZx4mx8x+vcfsLvDHcDLkf/lbyPpu97C27b/z
|
||||
ia07bu5TAXesUZrWZtKA5KeRE5doQSdTOv1N28BEr8ZwzDJwfn0DPUYUOxsN2iIy
|
||||
MheO5A45Ko7bjKJVkZ61Mb1UxtqCTF9mqu9R3PBdJGthWOd+HUvF460CgYEA7QRf
|
||||
Z8+vpGA+eSuu29e0xgRKnRzed5zXYpcI4aERc3JzBgO4Z0er9G8l66OWVGdMfpe6
|
||||
CBajC5ToIiT8zqoYxXwqJgN+glir4gJe3mm8J703QfArZiQrdk0NTi5bY7+vLLG/
|
||||
knTrtpdsKih6r3kjhuPPaAsIwmMxIydFvATKjLUCgYEAh/y4EihRSk5WKC8GxeZt
|
||||
oiZ58vT4z+fqnMIfyJmD5up48JuQNcokw/LADj/ODiFM7GUnWkGxBrvDA3H67WQm
|
||||
49bJjs8E+BfUQFdTjYnJRlpJZ+7Zt1gbNQMf5ENw5CCchTDqEq6pN0DVf8PBnSIF
|
||||
KvkXW9KvdV5J76uCAn15mDkCgYA1y8dHzbjlCz9Cy2pt1aDfTPwOew33gi7U3skS
|
||||
RTerx29aDyAcuQTLfyrROBkX4TZYiWGdEl5Bc7PYhCKpWawzrsH2TNa7CRtCOh2E
|
||||
R+V/84+GNNf04ALJYCXD9/ugQVKmR1XfDRCvKeFQFE38Y/dvV2etCswbKt5tRy2p
|
||||
xkCe/QKBgQCkLqafD4S20YHf6WTp3jp/4H/qEy2X2a8gdVVBi1uKkGDXr0n+AoVU
|
||||
ib4KbP5ovZlrjL++akMQ7V2fHzuQIFWnCkDA5c2ZAqzlM+ZN+HRG7gWur7Bt4XH1
|
||||
7XC9wlRna4b3Ln8ew3q1ZcBjXwD4ppbTlmwAfQIaZTGJUgQbdsO9YA==
|
||||
-----END RSA PRIVATE KEY-----
|
1
testdata/.ssh/id_rsa.pub
vendored
Normal file
1
testdata/.ssh/id_rsa.pub
vendored
Normal file
@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDh7YP+o83TynNNpz5rxmaU/XOIk5eTjkLKcw+29rSu0r9EHbpVt8AXSEgmOLuW2+dieoJT2gV+8QzfdxOftP3r6h3yJv9XPblhTxluy2q0iyQ+7AJu/crSYAeCy+InJEPvIz5ApNsFASBsa5bqC1swqGJh+IgHgPKPsB1L9+Te/brAODPtIcjk4Gq71u/UqHFBh0USdTc8C0Cp5xyDM2lsfd5gvIbO5TEQgmWGln+5TYb2mmP9xKs41U+IjwCGLhGuVmOY/mXnv+yrUKUa6XIukVwzDryQ/kWKTKoekckdEE2BTnvXLQ+HfdKMFuzSFoIgByat5YSEZ7785ecl7pVR drone-scp@localhost
|
50
testdata/.ssh/test
vendored
Normal file
50
testdata/.ssh/test
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
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
|
||||
l4njcaMpg4tpQMHtCBOicGyV0=
|
||||
-----END OPENSSH PRIVATE KEY-----
|
1
testdata/.ssh/test.pub
vendored
Normal file
1
testdata/.ssh/test.pub
vendored
Normal file
@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDz6aZ1jY2onnuj2YNHJ/HhfvIu0B973v/+pFFOavnTUOhEEKEy3TASu+s9CkHrYZAtRc+QYIkNZI31mhHBhotdeP/7GoO2UirkFtrzyQKPNJxEcv0RBoG9ssN8jex0PyK6DHIYYFnIWadVBEEOh/H+rK7j7u2/big3oTzYBuFrCwmYFcz5na99MzFeAUhazF44gVBma+zO+1quGeqF51UDIg1SMGvX8I7LNEqrKEBaIUQJKFQcxlOWlRLQsjJCymrOujsXsRrXHAQWcnxDcNevv2ZMOUl0ybvv9yH0BiGbRBd1Hy8/QPILbAQaqu0oQE7fubN8Q8lqb3Jg0loID4x/5GPhSY8WAXpuLcXTOrb93SnCw1JsAgJDNqpuuRFy3BSZ7wBOr1jfeIoo7xk14OHiUjJ0uXDL9cLMkcw6ElWz81mrD2VCkXUz+qFyjJ+G7aGWRtctZoOzKln4yfNfUmwW8/8ra3QnmrMZ2xW2Ylw3ZhO+tLi7jINHYFb54bAdLVPUU1ctIuJns2qkWnjJCxxMiynIqCif20/OU1n8CTJuOWiURmRdmvKOH4PE3JxC2Qnk/3tV3Cf8hp1CH5VjBZ9AjGj5MDMHXyu34VY2WvYo5QyzfS3ySPoT8kCO0G0xpvjwCMHOK+G2RP4kqb/KKZguiKdgintBXuskTlJmD7kcMQ== deploy@easyssh
|
3
testdata/test.sh
vendored
Normal file
3
testdata/test.sh
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
whoami
|
Loading…
Reference in New Issue
Block a user