mirror of
https://github.com/appleboy/ssh-action.git
synced 2026-09-02 09:39:32 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c4f70287fc | |||
| 6f15e4fabc | |||
| 7e02feefeb | |||
| ca58dd0ce3 | |||
| b838bc2f27 | |||
| 068c0c7a4e | |||
| 1530429296 | |||
| 81fc8ccc33 | |||
| 90162d1e43 | |||
| 8743aa11bf | |||
| 0ff4204d59 | |||
| 8e460a28f2 | |||
| 23bd972bfc |
@@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this action
|
||||||
|
title: ""
|
||||||
|
labels: enhancement
|
||||||
|
assignees: appleboy
|
||||||
|
---
|
||||||
|
|
||||||
|
## Is your feature request related to a problem?
|
||||||
|
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
## Describe the solution you'd like
|
||||||
|
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
## Example Yaml Config
|
||||||
|
|
||||||
|
If applicable, show how you would expect to use the new feature:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: executing remote ssh commands
|
||||||
|
uses: appleboy/ssh-action@v1
|
||||||
|
with:
|
||||||
|
host: ${{ secrets.HOST }}
|
||||||
|
username: ${{ secrets.USERNAME }}
|
||||||
|
key: ${{ secrets.KEY }}
|
||||||
|
script: whoami
|
||||||
|
```
|
||||||
|
|
||||||
|
## Additional context
|
||||||
|
|
||||||
|
Add any other context about the feature request here. Note that SSH connection
|
||||||
|
behavior (ciphers, timeouts, proxy, etc.) is implemented in
|
||||||
|
[drone-ssh](https://github.com/appleboy/drone-ssh) - feature requests for
|
||||||
|
connection behavior may belong there.
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
## Description
|
||||||
|
|
||||||
|
Please describe what this PR changes and why.
|
||||||
|
|
||||||
|
## Related Issues
|
||||||
|
|
||||||
|
Fixes #
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
- [ ] Tests pass (`.github/workflows/main.yml` scenarios cover this change)
|
||||||
|
- [ ] `action.yml` input descriptions updated (if adding/changing parameters)
|
||||||
|
- [ ] README.md parameter tables updated (if adding/changing parameters)
|
||||||
|
- [ ] Chinese translations updated (README.zh-cn.md, README.zh-tw.md)
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
labels:
|
||||||
|
- "dependencies"
|
||||||
|
commit-message:
|
||||||
|
prefix: "chore(ci)"
|
||||||
@@ -13,17 +13,17 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Setup go
|
- name: Setup go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v7
|
||||||
with:
|
with:
|
||||||
go-version: "^1"
|
go-version: "^1"
|
||||||
|
|
||||||
- name: Run GoReleaser
|
- name: Run GoReleaser
|
||||||
uses: goreleaser/goreleaser-action@v6
|
uses: goreleaser/goreleaser-action@v7
|
||||||
with:
|
with:
|
||||||
# either 'goreleaser' (default) or 'goreleaser-pro'
|
# either 'goreleaser' (default) or 'goreleaser-pro'
|
||||||
distribution: goreleaser
|
distribution: goreleaser
|
||||||
|
|||||||
+122
-12
@@ -7,7 +7,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: create new ssh server
|
- name: create new ssh server
|
||||||
run: |
|
run: |
|
||||||
@@ -70,7 +70,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: add public key to env
|
- name: add public key to env
|
||||||
run: |
|
run: |
|
||||||
@@ -142,7 +142,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: add public key to env
|
- name: add public key to env
|
||||||
run: |
|
run: |
|
||||||
@@ -223,7 +223,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: add public key to env
|
- name: add public key to env
|
||||||
run: |
|
run: |
|
||||||
@@ -297,7 +297,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: add public key to env
|
- name: add public key to env
|
||||||
run: |
|
run: |
|
||||||
@@ -351,7 +351,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: add public key to env
|
- name: add public key to env
|
||||||
run: |
|
run: |
|
||||||
@@ -496,10 +496,10 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Set up WARP
|
- name: Set up WARP
|
||||||
uses: fscarmen/warp-on-actions@v1.1
|
uses: fscarmen/warp-on-actions@v1.4
|
||||||
with:
|
with:
|
||||||
stack: dual
|
stack: dual
|
||||||
|
|
||||||
@@ -525,7 +525,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Set Environment Variables
|
- name: Set Environment Variables
|
||||||
run: |
|
run: |
|
||||||
@@ -569,7 +569,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: create new ssh server
|
- name: create new ssh server
|
||||||
run: |
|
run: |
|
||||||
@@ -609,12 +609,108 @@ jobs:
|
|||||||
- name: check stdout
|
- name: check stdout
|
||||||
run: |
|
run: |
|
||||||
echo "stdout: ${{ steps.stdout.outputs.stdout }}"
|
echo "stdout: ${{ steps.stdout.outputs.stdout }}"
|
||||||
|
if [ -z "${{ steps.stdout.outputs.stdout }}" ]; then
|
||||||
|
echo "Error: stdout is empty"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- id: stdout-multiline
|
||||||
|
name: capture multiline output
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
host: ${{ env.REMOTE_HOST }}
|
||||||
|
username: linuxserver.io
|
||||||
|
password: password
|
||||||
|
port: 2222
|
||||||
|
capture_stdout: true
|
||||||
|
script: |
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
echo "Line 1"
|
||||||
|
echo "Line 2"
|
||||||
|
echo "Line 3"
|
||||||
|
whoami
|
||||||
|
pwd
|
||||||
|
|
||||||
|
- name: check multiline output
|
||||||
|
run: |
|
||||||
|
echo "stdout: ${{ steps.stdout-multiline.outputs.stdout }}"
|
||||||
|
# Check if all lines are present
|
||||||
|
if ! echo "${{ steps.stdout-multiline.outputs.stdout }}" | grep -q "Line 1"; then
|
||||||
|
echo "Error: 'Line 1' not found in output"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! echo "${{ steps.stdout-multiline.outputs.stdout }}" | grep -q "Line 2"; then
|
||||||
|
echo "Error: 'Line 2' not found in output"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! echo "${{ steps.stdout-multiline.outputs.stdout }}" | grep -q "Line 3"; then
|
||||||
|
echo "Error: 'Line 3' not found in output"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! echo "${{ steps.stdout-multiline.outputs.stdout }}" | grep -q "linuxserver.io"; then
|
||||||
|
echo "Error: username not found in output"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for duplicates - each unique line should appear exactly once
|
||||||
|
OUTPUT="${{ steps.stdout-multiline.outputs.stdout }}"
|
||||||
|
LINE1_COUNT=$(echo "$OUTPUT" | grep -c "^Line 1$" || true)
|
||||||
|
LINE2_COUNT=$(echo "$OUTPUT" | grep -c "^Line 2$" || true)
|
||||||
|
LINE3_COUNT=$(echo "$OUTPUT" | grep -c "^Line 3$" || true)
|
||||||
|
|
||||||
|
echo "Line 1 count: $LINE1_COUNT"
|
||||||
|
echo "Line 2 count: $LINE2_COUNT"
|
||||||
|
echo "Line 3 count: $LINE3_COUNT"
|
||||||
|
|
||||||
|
if [ "$LINE1_COUNT" -ne 1 ]; then
|
||||||
|
echo "Error: 'Line 1' appears $LINE1_COUNT times (expected 1)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ "$LINE2_COUNT" -ne 1 ]; then
|
||||||
|
echo "Error: 'Line 2' appears $LINE2_COUNT times (expected 1)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ "$LINE3_COUNT" -ne 1 ]; then
|
||||||
|
echo "Error: 'Line 3' appears $LINE3_COUNT times (expected 1)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✓ No duplicate lines detected"
|
||||||
|
|
||||||
|
- id: stdout-with-special-chars
|
||||||
|
name: capture output with special characters
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
host: ${{ env.REMOTE_HOST }}
|
||||||
|
username: linuxserver.io
|
||||||
|
password: password
|
||||||
|
port: 2222
|
||||||
|
capture_stdout: true
|
||||||
|
script: |
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
echo "Test with special chars: @#$%^&*()"
|
||||||
|
echo "Path: /home/user/test"
|
||||||
|
echo "JSON: {\"key\": \"value\"}"
|
||||||
|
|
||||||
|
- name: check special characters output
|
||||||
|
run: |
|
||||||
|
echo "stdout: ${{ steps.stdout-with-special-chars.outputs.stdout }}"
|
||||||
|
if ! echo "${{ steps.stdout-with-special-chars.outputs.stdout }}" | grep -q "special chars"; then
|
||||||
|
echo "Error: special characters test failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! echo "${{ steps.stdout-with-special-chars.outputs.stdout }}" | grep -q "/home/user/test"; then
|
||||||
|
echo "Error: path not found in output"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
testing-script-stop:
|
testing-script-stop:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: create new ssh server
|
- name: create new ssh server
|
||||||
run: |
|
run: |
|
||||||
@@ -697,11 +793,25 @@ jobs:
|
|||||||
echo "Output contains 'True'"
|
echo "Output contains 'True'"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
windows-binary-download:
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
|
- name: test binary download and checksum verification
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
export GITHUB_ACTION_PATH="$PWD"
|
||||||
|
export INPUT_CURL_INSECURE=false
|
||||||
|
export INPUT_CAPTURE_STDOUT=false
|
||||||
|
./entrypoint.sh --help
|
||||||
|
|
||||||
testing-script-error:
|
testing-script-error:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: create new ssh server
|
- name: create new ssh server
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: create new ssh server
|
- name: create new ssh server
|
||||||
run: |
|
run: |
|
||||||
@@ -55,7 +55,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: add public key to env
|
- name: add public key to env
|
||||||
run: |
|
run: |
|
||||||
@@ -127,7 +127,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: add public key to env
|
- name: add public key to env
|
||||||
run: |
|
run: |
|
||||||
@@ -208,7 +208,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: add public key to env
|
- name: add public key to env
|
||||||
run: |
|
run: |
|
||||||
@@ -282,7 +282,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: add public key to env
|
- name: add public key to env
|
||||||
run: |
|
run: |
|
||||||
@@ -336,7 +336,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: add public key to env
|
- name: add public key to env
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v7
|
||||||
|
|
||||||
- name: Run Trivy vulnerability scanner in repo mode
|
- name: Run Trivy vulnerability scanner in repo mode
|
||||||
uses: aquasecurity/trivy-action@0.33.1
|
uses: aquasecurity/trivy-action@v0.36.0
|
||||||
with:
|
with:
|
||||||
scan-type: 'fs'
|
scan-type: 'fs'
|
||||||
scan-ref: '.'
|
scan-ref: '.'
|
||||||
@@ -33,19 +33,10 @@ jobs:
|
|||||||
format: 'sarif'
|
format: 'sarif'
|
||||||
output: 'trivy-results.sarif'
|
output: 'trivy-results.sarif'
|
||||||
severity: 'CRITICAL,HIGH,MEDIUM'
|
severity: 'CRITICAL,HIGH,MEDIUM'
|
||||||
|
exit-code: '1'
|
||||||
|
|
||||||
- name: Upload Trivy results to GitHub Security tab
|
- name: Upload Trivy results to GitHub Security tab
|
||||||
uses: github/codeql-action/upload-sarif@v3
|
uses: github/codeql-action/upload-sarif@v4
|
||||||
if: always()
|
if: always()
|
||||||
with:
|
with:
|
||||||
sarif_file: 'trivy-results.sarif'
|
sarif_file: 'trivy-results.sarif'
|
||||||
|
|
||||||
- name: Run Trivy vulnerability scanner (table format)
|
|
||||||
uses: aquasecurity/trivy-action@0.33.1
|
|
||||||
with:
|
|
||||||
scan-type: 'fs'
|
|
||||||
scan-ref: '.'
|
|
||||||
scanners: 'vuln,secret,misconfig'
|
|
||||||
format: 'table'
|
|
||||||
severity: 'CRITICAL,HIGH,MEDIUM'
|
|
||||||
exit-code: '1'
|
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# macOS
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# drone-ssh binaries downloaded by entrypoint.sh during local testing
|
||||||
|
drone-ssh-*
|
||||||
|
checksums.txt
|
||||||
@@ -162,7 +162,7 @@ Or use ED25519 keys instead (preferred).
|
|||||||
|
|
||||||
The action pins to specific drone-ssh versions via:
|
The action pins to specific drone-ssh versions via:
|
||||||
|
|
||||||
- Default: `DRONE_SSH_VERSION="1.8.2"` in `entrypoint.sh`
|
- Default: `DRONE_SSH_VERSION="1.8.4"` in `entrypoint.sh`
|
||||||
- Override: Users can specify `version` input parameter
|
- Override: Users can specify `version` input parameter
|
||||||
|
|
||||||
Update the default version when new drone-ssh releases are available.
|
Update the default version when new drone-ssh releases are available.
|
||||||
|
|||||||
@@ -45,11 +45,13 @@ English | [繁體中文](./README.zh-tw.md) | [简体中文](./README.zh-cn.md)
|
|||||||
**SSH for GitHub Actions** is a powerful [GitHub Action](https://github.com/features/actions) for executing remote SSH commands easily and securely in your CI/CD workflows.
|
**SSH for GitHub Actions** is a powerful [GitHub Action](https://github.com/features/actions) for executing remote SSH commands easily and securely in your CI/CD workflows.
|
||||||
Built with [Golang](https://go.dev) and [drone-ssh](https://github.com/appleboy/drone-ssh), it supports a wide range of SSH scenarios, including multi-host, proxy, and advanced authentication.
|
Built with [Golang](https://go.dev) and [drone-ssh](https://github.com/appleboy/drone-ssh), it supports a wide range of SSH scenarios, including multi-host, proxy, and advanced authentication.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
[](https://github.com/appleboy/ssh-action/actions/workflows/main.yml)
|
[](https://github.com/appleboy/ssh-action/actions/workflows/main.yml)
|
||||||
[](https://github.com/appleboy/ssh-action/actions/workflows/trivy-scan.yml)
|
[](https://github.com/appleboy/ssh-action/actions/workflows/trivy-scan.yml)
|
||||||
|
|
||||||
|
**Slides:** [SSH for GitHub Actions](https://speakerdeck.com/appleboy/ssh-for-github-actions)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🧩 Core Concepts & Input Parameters
|
## 🧩 Core Concepts & Input Parameters
|
||||||
@@ -127,8 +129,8 @@ These parameters control the use of a proxy (jump host) for connecting to your t
|
|||||||
|
|
||||||
This action provides the following outputs that you can use in subsequent steps:
|
This action provides the following outputs that you can use in subsequent steps:
|
||||||
|
|
||||||
| Output | Description |
|
| Output | Description |
|
||||||
| ------ | ----------------------------------------------------------------- |
|
| ------ | -------------------------------------------------------------------------- |
|
||||||
| stdout | Standard output of the executed commands (requires `capture_stdout: true`) |
|
| stdout | Standard output of the executed commands (requires `capture_stdout: true`) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
+3
-1
@@ -45,11 +45,13 @@
|
|||||||
**SSH for GitHub Actions** 是一个强大的 [GitHub Action](https://github.com/features/actions),可让你在 CI/CD 工作流中轻松且安全地执行远程 SSH 命令。
|
**SSH for GitHub Actions** 是一个强大的 [GitHub Action](https://github.com/features/actions),可让你在 CI/CD 工作流中轻松且安全地执行远程 SSH 命令。
|
||||||
本项目基于 [Golang](https://go.dev) 和 [drone-ssh](https://github.com/appleboy/drone-ssh) 构建,支持多主机、代理、高级认证等多种 SSH 场景。
|
本项目基于 [Golang](https://go.dev) 和 [drone-ssh](https://github.com/appleboy/drone-ssh) 构建,支持多主机、代理、高级认证等多种 SSH 场景。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
[](https://github.com/appleboy/ssh-action/actions/workflows/main.yml)
|
[](https://github.com/appleboy/ssh-action/actions/workflows/main.yml)
|
||||||
[](https://github.com/appleboy/ssh-action/actions/workflows/trivy-scan.yml)
|
[](https://github.com/appleboy/ssh-action/actions/workflows/trivy-scan.yml)
|
||||||
|
|
||||||
|
**幻灯片:** [SSH for GitHub Actions](https://speakerdeck.com/appleboy/ssh-for-github-actions)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🧩 核心概念与输入参数
|
## 🧩 核心概念与输入参数
|
||||||
|
|||||||
+3
-1
@@ -45,11 +45,13 @@
|
|||||||
**SSH for GitHub Actions** 是一個強大的 [GitHub Action](https://github.com/features/actions),可讓你在 CI/CD 工作流程中輕鬆且安全地執行遠端 SSH 指令。
|
**SSH for GitHub Actions** 是一個強大的 [GitHub Action](https://github.com/features/actions),可讓你在 CI/CD 工作流程中輕鬆且安全地執行遠端 SSH 指令。
|
||||||
本專案以 [Golang](https://go.dev) 和 [drone-ssh](https://github.com/appleboy/drone-ssh) 建立,支援多主機、代理、進階認證等多種 SSH 場景。
|
本專案以 [Golang](https://go.dev) 和 [drone-ssh](https://github.com/appleboy/drone-ssh) 建立,支援多主機、代理、進階認證等多種 SSH 場景。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
[](https://github.com/appleboy/ssh-action/actions/workflows/main.yml)
|
[](https://github.com/appleboy/ssh-action/actions/workflows/main.yml)
|
||||||
[](https://github.com/appleboy/ssh-action/actions/workflows/trivy-scan.yml)
|
[](https://github.com/appleboy/ssh-action/actions/workflows/trivy-scan.yml)
|
||||||
|
|
||||||
|
**簡報:** [SSH for GitHub Actions](https://speakerdeck.com/appleboy/ssh-for-github-actions)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🧩 核心概念與輸入參數
|
## 🧩 核心概念與輸入參數
|
||||||
|
|||||||
+41
-6
@@ -6,7 +6,7 @@ export GITHUB="true"
|
|||||||
|
|
||||||
GITHUB_ACTION_PATH="${GITHUB_ACTION_PATH%/}"
|
GITHUB_ACTION_PATH="${GITHUB_ACTION_PATH%/}"
|
||||||
DRONE_SSH_RELEASE_URL="${DRONE_SSH_RELEASE_URL:-https://github.com/appleboy/drone-ssh/releases/download}"
|
DRONE_SSH_RELEASE_URL="${DRONE_SSH_RELEASE_URL:-https://github.com/appleboy/drone-ssh/releases/download}"
|
||||||
DRONE_SSH_VERSION="${DRONE_SSH_VERSION:-1.8.2}"
|
DRONE_SSH_VERSION="${DRONE_SSH_VERSION:-1.8.4}"
|
||||||
|
|
||||||
# Error codes
|
# Error codes
|
||||||
readonly ERR_UNKNOWN_PLATFORM=2
|
readonly ERR_UNKNOWN_PLATFORM=2
|
||||||
@@ -26,6 +26,8 @@ function detect_client_info() {
|
|||||||
|
|
||||||
case "${CLIENT_PLATFORM}" in
|
case "${CLIENT_PLATFORM}" in
|
||||||
darwin | linux | windows) ;;
|
darwin | linux | windows) ;;
|
||||||
|
# Git Bash / MSYS2 / Cygwin on Windows runners report e.g. MINGW64_NT-10.0
|
||||||
|
mingw* | msys* | cygwin*) CLIENT_PLATFORM="windows" ;;
|
||||||
*) log_error "Unknown or unsupported platform: ${CLIENT_PLATFORM}. Supported platforms are Linux, Darwin, and Windows." "${ERR_UNKNOWN_PLATFORM}" ;;
|
*) log_error "Unknown or unsupported platform: ${CLIENT_PLATFORM}. Supported platforms are Linux, Darwin, and Windows." "${ERR_UNKNOWN_PLATFORM}" ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@@ -39,6 +41,10 @@ function detect_client_info() {
|
|||||||
detect_client_info
|
detect_client_info
|
||||||
DOWNLOAD_URL_PREFIX="${DRONE_SSH_RELEASE_URL}/v${DRONE_SSH_VERSION}"
|
DOWNLOAD_URL_PREFIX="${DRONE_SSH_RELEASE_URL}/v${DRONE_SSH_VERSION}"
|
||||||
CLIENT_BINARY="drone-ssh-${DRONE_SSH_VERSION}-${CLIENT_PLATFORM}-${CLIENT_ARCH}"
|
CLIENT_BINARY="drone-ssh-${DRONE_SSH_VERSION}-${CLIENT_PLATFORM}-${CLIENT_ARCH}"
|
||||||
|
# Windows release assets are published with an .exe suffix
|
||||||
|
if [[ "${CLIENT_PLATFORM}" == "windows" ]]; then
|
||||||
|
CLIENT_BINARY="${CLIENT_BINARY}.exe"
|
||||||
|
fi
|
||||||
TARGET="${GITHUB_ACTION_PATH}/${CLIENT_BINARY}"
|
TARGET="${GITHUB_ACTION_PATH}/${CLIENT_BINARY}"
|
||||||
|
|
||||||
# Check if binary already exists and is executable (caching)
|
# Check if binary already exists and is executable (caching)
|
||||||
@@ -62,6 +68,37 @@ else
|
|||||||
log_error "Downloaded file is missing or empty: ${TARGET}" "${ERR_INVALID_BINARY}"
|
log_error "Downloaded file is missing or empty: ${TARGET}" "${ERR_INVALID_BINARY}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Verify checksum; container jobs may lack shasum (Perl) or sha256sum, so
|
||||||
|
# detect an available tool and skip verification with a warning if none exists
|
||||||
|
SHA256_CMD=""
|
||||||
|
if command -v shasum >/dev/null 2>&1; then
|
||||||
|
SHA256_CMD="shasum -a 256"
|
||||||
|
elif command -v sha256sum >/dev/null 2>&1; then
|
||||||
|
SHA256_CMD="sha256sum"
|
||||||
|
else
|
||||||
|
echo "Warning: neither shasum nor sha256sum is available, skipping checksum verification" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "${SHA256_CMD}" ]]; then
|
||||||
|
CHECKSUMS_FILE="${GITHUB_ACTION_PATH}/checksums.txt"
|
||||||
|
if ! curl -fsSL --retry 5 --keepalive-time 2 --location ${INSECURE_OPTION} \
|
||||||
|
"${DOWNLOAD_URL_PREFIX}/checksums.txt" -o "${CHECKSUMS_FILE}"; then
|
||||||
|
log_error "Failed to download checksums.txt from ${DOWNLOAD_URL_PREFIX}." "${ERR_DOWNLOAD_FAILED}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
EXPECTED_CHECKSUM=$(awk -v bin="${CLIENT_BINARY}" '$2 == bin {print $1}' "${CHECKSUMS_FILE}")
|
||||||
|
if [[ -z "${EXPECTED_CHECKSUM}" ]]; then
|
||||||
|
log_error "No checksum entry found for ${CLIENT_BINARY} in checksums.txt." "${ERR_INVALID_BINARY}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
ACTUAL_CHECKSUM=$(${SHA256_CMD} "${TARGET}" | awk '{print $1}')
|
||||||
|
if [[ "${ACTUAL_CHECKSUM}" != "${EXPECTED_CHECKSUM}" ]]; then
|
||||||
|
log_error "Checksum verification failed for ${CLIENT_BINARY}: expected ${EXPECTED_CHECKSUM}, got ${ACTUAL_CHECKSUM}." "${ERR_INVALID_BINARY}"
|
||||||
|
fi
|
||||||
|
echo "Checksum verification passed for ${CLIENT_BINARY}"
|
||||||
|
rm -f "${CHECKSUMS_FILE}"
|
||||||
|
fi
|
||||||
|
|
||||||
chmod +x "${TARGET}"
|
chmod +x "${TARGET}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -71,11 +108,9 @@ if ! "${TARGET}" --version; then
|
|||||||
fi
|
fi
|
||||||
echo "======================================="
|
echo "======================================="
|
||||||
if [[ "${INPUT_CAPTURE_STDOUT}" == 'true' ]]; then
|
if [[ "${INPUT_CAPTURE_STDOUT}" == 'true' ]]; then
|
||||||
{
|
echo 'stdout<<EOF' >> "${GITHUB_OUTPUT}"
|
||||||
echo 'stdout<<EOF'
|
"${TARGET}" "$@" | tee -a "${GITHUB_OUTPUT}"
|
||||||
"${TARGET}" "$@" | tee -a "${GITHUB_OUTPUT}"
|
echo 'EOF' >> "${GITHUB_OUTPUT}"
|
||||||
echo 'EOF'
|
|
||||||
} >>"${GITHUB_OUTPUT}"
|
|
||||||
else
|
else
|
||||||
"${TARGET}" "$@"
|
"${TARGET}" "$@"
|
||||||
fi
|
fi
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 652 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 70 KiB |
Reference in New Issue
Block a user