Compare commits
	
		
			86 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 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 | 
							
								
								
									
										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. | ||||
							
								
								
									
										265
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										265
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,265 +0,0 @@ | ||||
| name: remote ssh command | ||||
| on: [push] | ||||
|  | ||||
| env: | ||||
|   FOO: "BAR" | ||||
|   BAR: "FOO" | ||||
|  | ||||
| jobs: | ||||
|  | ||||
|   testing01: | ||||
|     name: default flag testing | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|     - name: checkout | ||||
|       uses: actions/checkout@v1 | ||||
|  | ||||
|     - name: correct password but wrong key | ||||
|       uses: ./ | ||||
|       with: | ||||
|         host: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         password: ${{ secrets.PASSWORD }} | ||||
|         key: "1234" | ||||
|         port: ${{ secrets.PORT }} | ||||
|         script: whoami | ||||
|  | ||||
|     - name: wrong password but correct key | ||||
|       uses: ./ | ||||
|       with: | ||||
|         host: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         password: "abcdef" | ||||
|         key: ${{ secrets.KEY }} | ||||
|         port: ${{ secrets.PORT }} | ||||
|         script: whoami | ||||
|  | ||||
|     - name: executing remote ssh commands using password | ||||
|       uses: ./ | ||||
|       with: | ||||
|         host: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         password: ${{ secrets.PASSWORD }} | ||||
|         port: ${{ secrets.PORT }} | ||||
|         script: whoami | ||||
|  | ||||
|     - name: executing remote ssh commands using ssh key | ||||
|       uses: ./ | ||||
|       with: | ||||
|         host: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         key: ${{ secrets.KEY }} | ||||
|         port: ${{ secrets.PORT }} | ||||
|         script: whoami | ||||
|  | ||||
|     - name: multiple command | ||||
|       uses: ./ | ||||
|       with: | ||||
|         host: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         key: ${{ secrets.KEY }} | ||||
|         port: ${{ secrets.PORT }} | ||||
|         script: | | ||||
|           whoami | ||||
|           ls -al | ||||
|  | ||||
|     - name: stop script if command error | ||||
|       uses: ./ | ||||
|       continue-on-error: true | ||||
|       with: | ||||
|         host: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         key: ${{ secrets.KEY }} | ||||
|         port: ${{ secrets.PORT }} | ||||
|         script_stop: true | ||||
|         sync: true | ||||
|         debug: true | ||||
|         script: | | ||||
|           mkdir abc/def | ||||
|           ls -al | ||||
|  | ||||
|     - name: ssh key passphrase | ||||
|       uses: ./ | ||||
|       with: | ||||
|         host: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         key: ${{ secrets.SSH2 }} | ||||
|         port: ${{ secrets.PORT }} | ||||
|         passphrase: ${{ secrets.PASSPHRASE }} | ||||
|         script: | | ||||
|           whoami | ||||
|           ls -al | ||||
|  | ||||
|     - name: use insecure cipher | ||||
|       uses: ./ | ||||
|       with: | ||||
|         host: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         password: ${{ secrets.PASSWORD }} | ||||
|         port: ${{ secrets.PORT }} | ||||
|         script: | | ||||
|             ls \ | ||||
|               -lah | ||||
|         use_insecure_cipher: true | ||||
|  | ||||
|     # https://github.com/appleboy/ssh-action/issues/75#issuecomment-668314271 | ||||
|     - name: Multiline SSH commands interpreted as single lines | ||||
|       uses: ./ | ||||
|       with: | ||||
|         host: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         password: ${{ secrets.PASSWORD }} | ||||
|         port: ${{ secrets.PORT }} | ||||
|         script_stop: true | ||||
|         script: | | ||||
|             ls \ | ||||
|               -lah | ||||
|         use_insecure_cipher: true | ||||
|  | ||||
|     # https://github.com/appleboy/ssh-action/issues/85 | ||||
|     - name: Deployment to multiple hosts with different ports | ||||
|       uses: ./ | ||||
|       with: | ||||
|         host: "${{ secrets.HOST }}:${{ secrets.PORT }}" | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         password: ${{ secrets.PASSWORD }} | ||||
|         port: 1024 | ||||
|         script_stop: true | ||||
|         script: | | ||||
|             ls \ | ||||
|               -lah | ||||
|         use_insecure_cipher: true | ||||
|  | ||||
|     # - name: SSH ED25519 Private Key | ||||
|     #   uses: ./ | ||||
|     #   with: | ||||
|     #     host: ${{ secrets.TUNNEL_HOST }} | ||||
|     #     username: ${{ secrets.TUNNEL_USERNAME }} | ||||
|     #     key: ${{ secrets.ID_ED25519 }} | ||||
|     #     port: ${{ secrets.TUNNEL_PORT }} | ||||
|     #     script: whoami | ||||
|  | ||||
|   testing02: | ||||
|     name: testing with envs | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|     - name: checkout | ||||
|       uses: actions/checkout@v1 | ||||
|  | ||||
|     - name: pass environment | ||||
|       uses: ./ | ||||
|       env: | ||||
|         FOO: "BAR" | ||||
|       with: | ||||
|         host: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         key: ${{ secrets.KEY }} | ||||
|         port: ${{ secrets.PORT }} | ||||
|         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: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         key: ${{ secrets.KEY }} | ||||
|         port: ${{ secrets.PORT }} | ||||
|         envs: FOO,BAR,SHA,PORT | ||||
|         script: | | ||||
|           echo "I am $FOO, thanks" | ||||
|           echo "I am $BAR, thanks" | ||||
|           echo "sha: $SHA" | ||||
|           echo "port: $PORT" | ||||
|           sh test.sh | ||||
|  | ||||
|     - name: custom envs format | ||||
|       uses: ./ | ||||
|       env: | ||||
|         FOO: "BAR" | ||||
|         AAA: "BBB" | ||||
|       with: | ||||
|         host: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         key: ${{ secrets.KEY }} | ||||
|         port: ${{ secrets.PORT }} | ||||
|         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: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         key: ${{ secrets.KEY }} | ||||
|         port: ${{ secrets.PORT }} | ||||
|         allenvs: true | ||||
|         script: | | ||||
|           echo "I am $INPUT_FOO, thanks" | ||||
|           echo "I am $INPUT_AAA, thanks" | ||||
|           echo "$GITHUB_BASE_REF" | ||||
|           echo "$GITHUB_REF" | ||||
|  | ||||
|   testing03: | ||||
|     name: git clone and pull | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|     - name: checkout | ||||
|       uses: actions/checkout@v1 | ||||
|  | ||||
|     - name: clone private repository | ||||
|       uses: ./ | ||||
|       with: | ||||
|         host: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         key: ${{ secrets.KEY }} | ||||
|         port: ${{ secrets.PORT }} | ||||
|         script_stop: true | ||||
|         script: | | ||||
|           git clone https://appleboy:${{ secrets.TEST_TOKEN }}@github.com/go-training/self-runner.git test_repository | ||||
|           rm -rf test_repository | ||||
|  | ||||
|   testing04: | ||||
|     name: docker login and pull | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|     - name: checkout | ||||
|       uses: actions/checkout@v1 | ||||
|  | ||||
|     - name: login GitHub Container Registry | ||||
|       uses: ./ | ||||
|       with: | ||||
|         host: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         key: ${{ secrets.KEY }} | ||||
|         port: ${{ secrets.PORT }} | ||||
|         script_stop: true | ||||
|         script: | | ||||
|           echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u github.actor --password-stdin | ||||
|  | ||||
|     - name: login DockerHub Container Registry | ||||
|       uses: ./ | ||||
|       with: | ||||
|         host: ${{ secrets.HOST }} | ||||
|         username: ${{ secrets.USERNAME }} | ||||
|         key: ${{ secrets.KEY }} | ||||
|         port: ${{ secrets.PORT }} | ||||
|         script_stop: true | ||||
|         script: | | ||||
|           echo ${{ secrets.DOCKERHUB_TOKEN }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin | ||||
|  | ||||
							
								
								
									
										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.2.2 | ||||
|         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.2.2 | ||||
|         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.2.2 | ||||
|         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.2.2 | ||||
|         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.2.2 | ||||
|         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.2.2 | ||||
|         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.2.2 | ||||
|         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.2.2 | ||||
|         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.2.2 | ||||
|         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.2.2 | ||||
|         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.2.2 | ||||
|         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.2.2 | ||||
|         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.2.2 | ||||
|         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.2.2 | ||||
|         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.2.2 | ||||
|         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.2.2 | ||||
|         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: 4 | ||||
|     - title: Others | ||||
| @@ -1,5 +0,0 @@ | ||||
| FROM ghcr.io/appleboy/drone-ssh:1.7.0 | ||||
|  | ||||
| COPY entrypoint.sh /entrypoint.sh | ||||
| RUN chmod +x /entrypoint.sh | ||||
| ENTRYPOINT ["/entrypoint.sh"] | ||||
							
								
								
									
										242
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										242
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,75 +1,77 @@ | ||||
| # 🚀 SSH for GitHub Actions | ||||
|  | ||||
| [繁體中文](./README.zh-tw.md) | ||||
| English | [繁體中文](./README.zh-tw.md) | [简体中文](./README.zh-cn.md) | ||||
|  | ||||
| [GitHub Action](https://github.com/features/actions) for executing remote ssh commands. | ||||
| 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) | ||||
|  | ||||
| **Important**: Only support **Linux** [docker](https://www.docker.com/) container. | ||||
|  | ||||
| This thing is built using [Golang](https://go.dev) and [drone-ssh](https://github.com/appleboy/drone-ssh). 🚀 | ||||
| This project is built with [Golang](https://go.dev) and [drone-ssh](https://github.com/appleboy/drone-ssh). 🚀 | ||||
|  | ||||
| ## Input variables | ||||
|  | ||||
| See [action.yml](./action.yml) for more detailed information. | ||||
| 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                                                    |               | | ||||
| | sync                    | Enable synchronous execution if multiple hosts                  | false         | | ||||
| | use_insecure_cipher     | Include more ciphers with use_insecure_cipher                    | false         | | ||||
| | cipher                  | Allowed cipher algorithms. If unspecified, a sensible default   |               | | ||||
| | 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_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_stop             | Stop script after first failure                                  | false         | | ||||
| | envs                    | Pass environment variables to shell script                      |               | | ||||
| | envs_format             | Flexible configuration of environment value transfer            |               | | ||||
| | debug                   | Enable debug mode                                               | false         | | ||||
| | allenvs                 | Pass all environment variables to shell script                  | false         | | ||||
| | 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         | | ||||
|  | ||||
| **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@v0.2.0 | ||||
|       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.2.2 | ||||
|         with: | ||||
|           host: ${{ secrets.HOST }} | ||||
|           username: linuxserver.io | ||||
|           password: ${{ secrets.PASSWORD }} | ||||
|           port: ${{ secrets.PORT }} | ||||
|           script: whoami | ||||
| ``` | ||||
|  | ||||
| output: | ||||
| @@ -78,17 +80,17 @@ output: | ||||
| ======CMD====== | ||||
| whoami | ||||
| ======END====== | ||||
| out: *** | ||||
| ============================================== | ||||
| ✅ Successfully executed commands to all host. | ||||
| ============================================== | ||||
| linuxserver.io | ||||
| =============================================== | ||||
| ✅ Successfully executed commands to all hosts. | ||||
| =============================================== | ||||
| ``` | ||||
|  | ||||
| ### Setting up a SSH Key | ||||
|  | ||||
| Make sure to follow the below steps while creating SSH Keys and using them. | ||||
| The best practice is create the SSH Keys on local machine not remote machine. | ||||
| Login with username specified in Github Secrets. Generate a RSA Key-Pair: | ||||
| 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: | ||||
|  | ||||
| ### Generate rsa key | ||||
|  | ||||
| @@ -102,7 +104,7 @@ ssh-keygen -t rsa -b 4096 -C "your_email@example.com" | ||||
| ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" | ||||
| ``` | ||||
|  | ||||
| Add newly generated key into Authorized keys. Read more about authorized keys [here](https://www.ssh.com/ssh/authorized_keys/). | ||||
| 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 | ||||
|  | ||||
| @@ -116,27 +118,44 @@ cat .ssh/id_rsa.pub | ssh b@B 'cat >> .ssh/authorized_keys' | ||||
| cat .ssh/id_ed25519.pub | ssh b@B 'cat >> .ssh/authorized_keys' | ||||
| ``` | ||||
|  | ||||
| Copy Private Key content and paste in Github Secrets. | ||||
| 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 | ||||
| clip < ~/.ssh/id_rsa | ||||
| # 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 | ||||
| clip < ~/.ssh/id_ed25519 | ||||
| # macOS | ||||
| pbcopy < ~/.ssh/id_ed25519 | ||||
| # Ubuntu | ||||
| xclip < ~/.ssh/id_ed25519 | ||||
| ``` | ||||
|  | ||||
| See the detail information about [SSH login without password](http://www.linuxproblem.org/art_9.html). | ||||
| See detailed information about [SSH login without a password](http://www.linuxproblem.org/art_9.html). | ||||
|  | ||||
| **A note** from one of our readers: Depending on your version of SSH you might also have to do the following changes: | ||||
| **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 | ||||
| - 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 | ||||
|  | ||||
| @@ -146,13 +165,13 @@ If you are currently using OpenSSH and are getting the following error: | ||||
| ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey] | ||||
| ``` | ||||
|  | ||||
| Make sure that your key algorithm of choice 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 (which is either `/etc/ssh/sshd_config` or a drop-in file under `/etc/ssh/sshd_config.d/`): | ||||
| 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 could use this instead of rsa if needed: | ||||
| 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" | ||||
| @@ -164,7 +183,7 @@ ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" | ||||
|  | ||||
| ```yaml | ||||
| - name: executing remote ssh commands using password | ||||
|   uses: appleboy/ssh-action@v0.2.0 | ||||
|   uses: appleboy/ssh-action@v1.2.2 | ||||
|   with: | ||||
|     host: ${{ secrets.HOST }} | ||||
|     username: ${{ secrets.USERNAME }} | ||||
| @@ -177,7 +196,7 @@ ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" | ||||
|  | ||||
| ```yaml | ||||
| - name: executing remote ssh commands using ssh key | ||||
|   uses: appleboy/ssh-action@v0.2.0 | ||||
|   uses: appleboy/ssh-action@v1.2.2 | ||||
|   with: | ||||
|     host: ${{ secrets.HOST }} | ||||
|     username: ${{ secrets.USERNAME }} | ||||
| @@ -190,7 +209,7 @@ ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" | ||||
|  | ||||
| ```yaml | ||||
| - name: multiple command | ||||
|   uses: appleboy/ssh-action@v0.2.0 | ||||
|   uses: appleboy/ssh-action@v1.2.2 | ||||
|   with: | ||||
|     host: ${{ secrets.HOST }} | ||||
|     username: ${{ secrets.USERNAME }} | ||||
| @@ -203,11 +222,24 @@ ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" | ||||
|  | ||||
|  | ||||
|  | ||||
| #### Commands from a file | ||||
|  | ||||
| ```yaml | ||||
| - name: file commands | ||||
|   uses: appleboy/ssh-action@v1.2.2 | ||||
|   with: | ||||
|     host: ${{ secrets.HOST }} | ||||
|     username: ${{ secrets.USERNAME }} | ||||
|     key: ${{ secrets.KEY }} | ||||
|     port: ${{ secrets.PORT }} | ||||
|     script_path: scripts/script.sh | ||||
| ``` | ||||
|  | ||||
| #### Multiple Hosts | ||||
|  | ||||
| ```diff | ||||
|   - name: multiple host | ||||
|     uses: appleboy/ssh-action@v0.2.0 | ||||
|     uses: appleboy/ssh-action@v1.2.2 | ||||
|     with: | ||||
| -     host: "foo.com" | ||||
| +     host: "foo.com,bar.com" | ||||
| @@ -219,11 +251,13 @@ ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" | ||||
|         ls -al | ||||
| ``` | ||||
|  | ||||
| The default value of `port` is `22`. | ||||
|  | ||||
| #### Multiple hosts with different port | ||||
|  | ||||
| ```diff | ||||
|   - name: multiple host | ||||
|     uses: appleboy/ssh-action@v0.2.0 | ||||
|     uses: appleboy/ssh-action@v1.2.2 | ||||
|     with: | ||||
| -     host: "foo.com" | ||||
| +     host: "foo.com:1234,bar.com:5678" | ||||
| @@ -238,7 +272,7 @@ ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" | ||||
|  | ||||
| ```diff | ||||
|   - name: multiple host | ||||
|     uses: appleboy/ssh-action@v0.2.0 | ||||
|     uses: appleboy/ssh-action@v1.2.2 | ||||
|     with: | ||||
|       host: "foo.com,bar.com" | ||||
| +     sync: true | ||||
| @@ -254,7 +288,7 @@ ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" | ||||
|  | ||||
| ```diff | ||||
|   - name: pass environment | ||||
|     uses: appleboy/ssh-action@v0.2.0 | ||||
|     uses: appleboy/ssh-action@v1.2.2 | ||||
| +   env: | ||||
| +     FOO: "BAR" | ||||
| +     BAR: "FOO" | ||||
| @@ -273,37 +307,6 @@ ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" | ||||
|  | ||||
| _Inside `env` object, you need to pass every environment variable as a string, passing `Integer` data type or any other may output unexpected results._ | ||||
|  | ||||
| #### Stop script after first failure | ||||
|  | ||||
| > ex: missing `abc` folder | ||||
|  | ||||
| ```diff | ||||
|   - name: stop script if command error | ||||
|     uses: appleboy/ssh-action@v0.2.0 | ||||
|     with: | ||||
|       host: ${{ secrets.HOST }} | ||||
|       username: ${{ secrets.USERNAME }} | ||||
|       key: ${{ secrets.KEY }} | ||||
|       port: ${{ secrets.PORT }} | ||||
| +     script_stop: true | ||||
|       script: | | ||||
|         mkdir abc/def | ||||
|         ls -al | ||||
| ``` | ||||
|  | ||||
| output: | ||||
|  | ||||
| ```sh | ||||
| ======CMD====== | ||||
| mkdir abc/def | ||||
| ls -al | ||||
|  | ||||
| ======END====== | ||||
| 2019/11/21 01:16:21 Process exited with status 1 | ||||
| err: mkdir: cannot create directory ‘abc/def’: No such file or directory | ||||
| ##[error]Docker run failed with exit code 1 | ||||
| ``` | ||||
|  | ||||
| #### How to connect remote server using `ProxyCommand`? | ||||
|  | ||||
| ```bash | ||||
| @@ -332,7 +335,7 @@ Host FooServer | ||||
|  | ||||
| ```diff | ||||
|   - name: ssh proxy command | ||||
|     uses: appleboy/ssh-action@v0.2.0 | ||||
|     uses: appleboy/ssh-action@v1.2.2 | ||||
|     with: | ||||
|       host: ${{ secrets.HOST }} | ||||
|       username: ${{ secrets.USERNAME }} | ||||
| @@ -355,7 +358,7 @@ It is not uncommon for files to leak from backups or decommissioned hardware, an | ||||
|  | ||||
| ```diff | ||||
|   - name: ssh key passphrase | ||||
|     uses: appleboy/ssh-action@v0.2.0 | ||||
|     uses: appleboy/ssh-action@v1.2.2 | ||||
|     with: | ||||
|       host: ${{ secrets.HOST }} | ||||
|       username: ${{ secrets.USERNAME }} | ||||
| @@ -381,7 +384,7 @@ Now you can adjust you config: | ||||
|  | ||||
| ```diff | ||||
|   - name: ssh key passphrase | ||||
|     uses: appleboy/ssh-action@v0.2.0 | ||||
|     uses: appleboy/ssh-action@v1.2.2 | ||||
|     with: | ||||
|       host: ${{ secrets.HOST }} | ||||
|       username: ${{ secrets.USERNAME }} | ||||
| @@ -393,6 +396,29 @@ Now you can adjust you config: | ||||
|         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! | ||||
|   | ||||
							
								
								
									
										403
									
								
								README.zh-cn.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										403
									
								
								README.zh-cn.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,403 @@ | ||||
| # 🚀 用于 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  | | ||||
|  | ||||
| **注意:** 用户可以在他们的 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.2.2 | ||||
|         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.2.2 | ||||
|   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.2.2 | ||||
|   with: | ||||
|     host: ${{ secrets.HOST }} | ||||
|     username: ${{ secrets.USERNAME }} | ||||
|     key: ${{ secrets.KEY }} | ||||
|     port: ${{ secrets.PORT }} | ||||
|     script: whoami | ||||
| ``` | ||||
|  | ||||
| #### 多个命令 | ||||
|  | ||||
| ```yaml | ||||
| - name: multiple command | ||||
|   uses: appleboy/ssh-action@v1.2.2 | ||||
|   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.2.2 | ||||
|   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.2.2 | ||||
|     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.2.2 | ||||
|     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.2.2 | ||||
|     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.2.2 | ||||
| +   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.2.2 | ||||
|     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.2.2 | ||||
|     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.2.2 | ||||
|     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) 发布。 | ||||
							
								
								
									
										200
									
								
								README.zh-tw.md
									
									
									
									
									
								
							
							
						
						
									
										200
									
								
								README.zh-tw.md
									
									
									
									
									
								
							| @@ -1,50 +1,58 @@ | ||||
| # 🚀 用於 GitHub Actions 的 SSH | ||||
| # 🚀 GitHub Actions 的 SSH | ||||
|  | ||||
| [GitHub Action](https://github.com/features/actions) for executing remote ssh commands. | ||||
| [English](./README.md) | 繁體中文 | [简体中文](./README.zh-cn.md) | ||||
|  | ||||
| [GitHub Action](https://github.com/features/actions) 用於執行遠端 SSH 命令。 | ||||
|  | ||||
|  | ||||
|  | ||||
| [](https://github.com/appleboy/ssh-action/actions) | ||||
| [](https://github.com/appleboy/ssh-action/actions/workflows/main.yml) | ||||
|  | ||||
| **注意**: 只支援在 **Linux** [docker](https://www.docker.com/) 容器上執行。 | ||||
| 此專案使用 [Golang](https://go.dev) 和 [drone-ssh](https://github.com/appleboy/drone-ssh) 建立。🚀 | ||||
|  | ||||
| ## 輸入變數 | ||||
|  | ||||
| 更詳細的資訊,請參閱 [action.yml](./action.yml)。 | ||||
| 請參閱 [action.yml](./action.yml) 以獲取更詳細的信息。 | ||||
|  | ||||
| * `host` - SSH 主機 | ||||
| * `port` - SSH 連接埠,預設為 `22` | ||||
| * `username` - SSH 使用者名稱 | ||||
| * `password` - SSH 密碼 | ||||
| * `passphrase` - 通常用於加密私鑰的 passphrase | ||||
| * `sync` - 同步執行多個主機上的命令,預設為 false | ||||
| * `timeout` - SSH 連接到遠端主機的超時時間,預設為 `30s` | ||||
| * `command_timeout` - SSH 命令超時時間,預設為 10m | ||||
| * `key` - SSH 私鑰的內容,例如 ~/.ssh/id_rsa 的原始內容,請記得包含 BEGIN 和 END 行 | ||||
| * `key_path` - SSH 私鑰的路徑 | ||||
| * `fingerprint` - 主機公鑰的 SHA256 指紋,預設為略過驗證 | ||||
| * `script` - 執行命令 | ||||
| * `script_stop` - 當出現第一個錯誤時停止執行命令 | ||||
| * `envs` - 傳遞環境變數到 shell script | ||||
| * `debug` - 啟用偵錯模式 | ||||
| * `use_insecure_cipher` - 使用不安全的密碼(ciphers)進行加密,參見 [#56](https://github.com/appleboy/ssh-action/issues/56) | ||||
| * `cipher` - 允許使用的密碼(ciphers)演算法。如果未指定,則使用適當的演算法 | ||||
| | 輸入參數                  | 描述                                                  | 預設值 | | ||||
| | ------------------------- | ----------------------------------------------------- | ------ | | ||||
| | 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  | | ||||
|  | ||||
| SSH 代理設置: | ||||
| **注意:** 用戶可以在他們的 shell 腳本中添加 `set -e` 以實現類似於已刪除的 `script_stop` 選項的功能。 | ||||
|  | ||||
| * `proxy_host` - 代理主機 | ||||
| * `proxy_port` - 代理端口,預設為 `22` | ||||
| * `proxy_username` - 代理使用者名稱 | ||||
| * `proxy_password` - 代理密碼 | ||||
| * `proxy_passphrase` - 密碼通常用於加密私有金鑰 | ||||
| * `proxy_timeout` - SSH 連線至代理主機的逾時時間,預設為 `30s` | ||||
| * `proxy_key` - SSH 代理私有金鑰內容 | ||||
| * `proxy_key_path` - SSH 代理私有金鑰路徑 | ||||
| * `proxy_fingerprint` - 代理主機公鑰的 SHA256 指紋,預設為跳過驗證 | ||||
| * `proxy_use_insecure_cipher` - 使用不安全的加密方式,請參閱 [#56](https://github.com/appleboy/ssh-action/issues/56) | ||||
| * `proxy_cipher` - 允許的加密算法。如果未指定,則使用合理的算法 | ||||
|  | ||||
| ## 使用方式 | ||||
| ## 用法 | ||||
|  | ||||
| 執行遠端 SSH 命令 | ||||
|  | ||||
| @@ -52,19 +60,18 @@ SSH 代理設置: | ||||
| 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@v0.1.10 | ||||
|       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.2.2 | ||||
|         with: | ||||
|           host: ${{ secrets.HOST }} | ||||
|           username: linuxserver.io | ||||
|           password: ${{ secrets.PASSWORD }} | ||||
|           port: ${{ secrets.PORT }} | ||||
|           script: whoami | ||||
| ``` | ||||
|  | ||||
| 畫面輸出 | ||||
| @@ -73,10 +80,10 @@ jobs: | ||||
| ======CMD====== | ||||
| whoami | ||||
| ======END====== | ||||
| out: *** | ||||
| ============================================== | ||||
| ✅ Successfully executed commands to all host. | ||||
| ============================================== | ||||
| linuxserver.io | ||||
| =============================================== | ||||
| ✅ Successfully executed commands to all hosts. | ||||
| =============================================== | ||||
| ``` | ||||
|  | ||||
| ### 設置 SSH 金鑰 | ||||
| @@ -113,23 +120,40 @@ cat .ssh/id_ed25519.pub | ssh b@B 'cat >> .ssh/authorized_keys' | ||||
|  | ||||
| ### 複製 rsa 私鑰內容 | ||||
|  | ||||
| 在複製私鑰之前,請按照以下說明安裝 `clip` 命令: | ||||
|  | ||||
| ```bash | ||||
| clip < ~/.ssh/id_rsa | ||||
| # 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 | ||||
| clip < ~/.ssh/id_ed25519 | ||||
| # macOS | ||||
| pbcopy < ~/.ssh/id_ed25519 | ||||
| # Ubuntu | ||||
| xclip < ~/.ssh/id_ed25519 | ||||
| ``` | ||||
|  | ||||
| 有關無需密碼登錄 SSH 的詳細信息,請[參見該網站](http://www.linuxproblem.org/art_9.html)。 | ||||
|  | ||||
| **來自讀者的注意事項**: 根據您的 SSH 版本,您可能還需要進行以下更改: | ||||
| **注意**:根據您的 SSH 版本,您可能還需要進行以下更改: | ||||
|  | ||||
| * 將公鑰放在 `.ssh/authorized_keys2` 中 | ||||
| * 將 `.ssh` 的權限更改為700 | ||||
| * 將 `.ssh/authorized_keys2` 的權限更改為640 | ||||
| - 將公鑰放在 `.ssh/authorized_keys2` 中 | ||||
| - 將 `.ssh` 的權限更改為 700 | ||||
| - 將 `.ssh/authorized_keys2` 的權限更改為 640 | ||||
|  | ||||
| ### 如果你使用的是 OpenSSH | ||||
|  | ||||
| @@ -157,7 +181,7 @@ ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" | ||||
|  | ||||
| ```yaml | ||||
| - name: executing remote ssh commands using password | ||||
|   uses: appleboy/ssh-action@v0.1.10 | ||||
|   uses: appleboy/ssh-action@v1.2.2 | ||||
|   with: | ||||
|     host: ${{ secrets.HOST }} | ||||
|     username: ${{ secrets.USERNAME }} | ||||
| @@ -170,7 +194,7 @@ ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" | ||||
|  | ||||
| ```yaml | ||||
| - name: executing remote ssh commands using ssh key | ||||
|   uses: appleboy/ssh-action@v0.1.10 | ||||
|   uses: appleboy/ssh-action@v1.2.2 | ||||
|   with: | ||||
|     host: ${{ secrets.HOST }} | ||||
|     username: ${{ secrets.USERNAME }} | ||||
| @@ -183,7 +207,7 @@ ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" | ||||
|  | ||||
| ```yaml | ||||
| - name: multiple command | ||||
|   uses: appleboy/ssh-action@v0.1.10 | ||||
|   uses: appleboy/ssh-action@v1.2.2 | ||||
|   with: | ||||
|     host: ${{ secrets.HOST }} | ||||
|     username: ${{ secrets.USERNAME }} | ||||
| @@ -196,11 +220,24 @@ ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" | ||||
|  | ||||
|  | ||||
|  | ||||
| #### 從文件中執行命令 | ||||
|  | ||||
| ```yaml | ||||
| - name: file commands | ||||
|   uses: appleboy/ssh-action@v1.2.2 | ||||
|   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@v0.1.10 | ||||
|     uses: appleboy/ssh-action@v1.2.2 | ||||
|     with: | ||||
| -     host: "foo.com" | ||||
| +     host: "foo.com,bar.com" | ||||
| @@ -216,7 +253,7 @@ ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" | ||||
|  | ||||
| ```diff | ||||
|   - name: multiple host | ||||
|     uses: appleboy/ssh-action@v0.1.10 | ||||
|     uses: appleboy/ssh-action@v1.2.2 | ||||
|     with: | ||||
| -     host: "foo.com" | ||||
| +     host: "foo.com:1234,bar.com:5678" | ||||
| @@ -231,7 +268,7 @@ ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" | ||||
|  | ||||
| ```diff | ||||
|   - name: multiple host | ||||
|     uses: appleboy/ssh-action@v0.1.10 | ||||
|     uses: appleboy/ssh-action@v1.2.2 | ||||
|     with: | ||||
|       host: "foo.com,bar.com" | ||||
| +     sync: true | ||||
| @@ -247,7 +284,7 @@ ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" | ||||
|  | ||||
| ```diff | ||||
|   - name: pass environment | ||||
|     uses: appleboy/ssh-action@v0.1.10 | ||||
|     uses: appleboy/ssh-action@v1.2.2 | ||||
| +   env: | ||||
| +     FOO: "BAR" | ||||
| +     BAR: "FOO" | ||||
| @@ -266,37 +303,6 @@ ssh-keygen -t ed25519 -a 200 -C "your_email@example.com" | ||||
|  | ||||
| _在 `env` 對象中,您需要將每個環境變量作為字符串傳遞,傳遞 `Integer` 數據類型或任何其他類型可能會產生意外結果。_ | ||||
|  | ||||
| #### 在第一次失敗後停止腳本 | ||||
|  | ||||
| > ex: missing `abc` folder | ||||
|  | ||||
| ```diff | ||||
|   - name: stop script if command error | ||||
|     uses: appleboy/ssh-action@v0.1.10 | ||||
|     with: | ||||
|       host: ${{ secrets.HOST }} | ||||
|       username: ${{ secrets.USERNAME }} | ||||
|       key: ${{ secrets.KEY }} | ||||
|       port: ${{ secrets.PORT }} | ||||
| +     script_stop: true | ||||
|       script: | | ||||
|         mkdir abc/def | ||||
|         ls -al | ||||
| ``` | ||||
|  | ||||
| 畫面輸出: | ||||
|  | ||||
| ```sh | ||||
| ======CMD====== | ||||
| mkdir abc/def | ||||
| ls -al | ||||
|  | ||||
| ======END====== | ||||
| 2019/11/21 01:16:21 Process exited with status 1 | ||||
| err: mkdir: cannot create directory ‘abc/def’: No such file or directory | ||||
| ##[error]Docker run failed with exit code 1 | ||||
| ``` | ||||
|  | ||||
| #### 如何使用 `ProxyCommand` 連接遠程服務器? | ||||
|  | ||||
| ```bash | ||||
| @@ -325,7 +331,7 @@ Host FooServer | ||||
|  | ||||
| ```diff | ||||
|   - name: ssh proxy command | ||||
|     uses: appleboy/ssh-action@v0.1.10 | ||||
|     uses: appleboy/ssh-action@v1.2.2 | ||||
|     with: | ||||
|       host: ${{ secrets.HOST }} | ||||
|       username: ${{ secrets.USERNAME }} | ||||
| @@ -346,7 +352,7 @@ Host FooServer | ||||
|  | ||||
| ```diff | ||||
|   - name: ssh key passphrase | ||||
|     uses: appleboy/ssh-action@v0.1.10 | ||||
|     uses: appleboy/ssh-action@v1.2.2 | ||||
|     with: | ||||
|       host: ${{ secrets.HOST }} | ||||
|       username: ${{ secrets.USERNAME }} | ||||
| @@ -362,7 +368,7 @@ Host FooServer | ||||
|  | ||||
| 設置 SSH 主機指紋驗證可以幫助防止中間人攻擊。在設置之前,運行以下命令以獲取 SSH 主機指紋。請記得將 `ed25519` 替換為您的適當金鑰類型(`rsa`、 `dsa`等),而 `example.com` 則替換為您的主機。 | ||||
|  | ||||
| 現代 OpenSSH 版本中,需要提取的_默認金鑰_類型是 `rsa`(從版本 5.1 開始)、`ecdsa`(從版本 6.0 開始)和 `ed25519`(從版本 6.7 開始)。 | ||||
| 現代 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 | ||||
| @@ -372,7 +378,7 @@ ssh example.com ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key.pub | cut -d ' ' | ||||
|  | ||||
| ```diff | ||||
|   - name: ssh key passphrase | ||||
|     uses: appleboy/ssh-action@v0.1.10 | ||||
|     uses: appleboy/ssh-action@v1.2.2 | ||||
|     with: | ||||
|       host: ${{ secrets.HOST }} | ||||
|       username: ${{ secrets.USERNAME }} | ||||
|   | ||||
							
								
								
									
										137
									
								
								action.yml
									
									
									
									
									
								
							
							
						
						
									
										137
									
								
								action.yml
									
									
									
									
									
								
							| @@ -1,76 +1,137 @@ | ||||
| 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 host address.' | ||||
|     description: "SSH host address or IP to connect to." | ||||
|   port: | ||||
|     description: 'SSH port number.' | ||||
|     description: "SSH port number for the connection." | ||||
|     default: "22" | ||||
|   passphrase: | ||||
|     description: 'Passphrase for the SSH key.' | ||||
|     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: 'Enable synchronous execution if multiple hosts are involved.' | ||||
|     description: "When true, executes commands synchronously across multiple hosts (one after another)." | ||||
|   use_insecure_cipher: | ||||
|     description: 'Include more ciphers by using insecure ciphers.' | ||||
|     description: "Enable additional legacy ciphers that might be less secure but more compatible with older systems." | ||||
|   cipher: | ||||
|     description: 'Allowed cipher algorithms. If unspecified, a sensible default is used.' | ||||
|     description: "Specify custom cipher algorithms for encryption. Leave empty to use secure defaults." | ||||
|   timeout: | ||||
|     description: 'Timeout duration for establishing SSH connection to the host.' | ||||
|     description: "Maximum time to wait when establishing the SSH connection, e.g., '30s', '1m'." | ||||
|     default: "30s" | ||||
|   command_timeout: | ||||
|     description: 'Timeout duration for SSH commands execution.' | ||||
|     description: "Maximum execution time for the remote commands before terminating, e.g., '10m', '1h'." | ||||
|     default: "10m" | ||||
|   key: | ||||
|     description: 'Content of the SSH private key. For example, the 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 to the SSH private key file.' | ||||
|     description: "Path to the SSH private key file on the runner." | ||||
|   fingerprint: | ||||
|     description: 'SHA256 fingerprint of the host public key.' | ||||
|     description: "SHA256 fingerprint of the host public key for verification to prevent MITM attacks." | ||||
|   proxy_host: | ||||
|     description: 'SSH proxy host address.' | ||||
|     description: "Proxy server hostname or IP if connecting through an SSH jump host." | ||||
|   proxy_port: | ||||
|     description: 'SSH proxy port number.' | ||||
|     description: "SSH port number for the proxy connection." | ||||
|     default: "22" | ||||
|   proxy_username: | ||||
|     description: 'SSH proxy username.' | ||||
|     description: "Username for authentication on the proxy server." | ||||
|   proxy_password: | ||||
|     description: 'SSH 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: 'SSH proxy key passphrase.' | ||||
|     description: "Passphrase to decrypt the proxy SSH private key if protected." | ||||
|   proxy_timeout: | ||||
|     description: 'Timeout duration for establishing SSH connection to the proxy host.' | ||||
|     description: "Maximum time to wait when establishing the proxy SSH connection, e.g., '30s', '1m'." | ||||
|     default: "30s" | ||||
|   proxy_key: | ||||
|     description: 'Content of the SSH proxy private key. For example, the raw content of ~/.ssh/id_rsa.' | ||||
|     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.' | ||||
|     description: "Path to the SSH proxy private key file on the runner." | ||||
|   proxy_fingerprint: | ||||
|     description: 'SHA256 fingerprint of the proxy host public key.' | ||||
|     description: "SHA256 fingerprint of the proxy host public key for verification." | ||||
|   proxy_cipher: | ||||
|     description: 'Allowed cipher algorithms for the proxy. If unspecified, a sensible default is used.' | ||||
|     description: "Specify custom cipher algorithms for proxy connection encryption." | ||||
|   proxy_use_insecure_cipher: | ||||
|     description: 'Include more ciphers for the proxy by using insecure ciphers.' | ||||
|     description: "Enable additional legacy ciphers for proxy connections (less secure but more compatible)." | ||||
|   script: | ||||
|     description: 'Commands to be executed.' | ||||
|   script_stop: | ||||
|     description: 'Stop the script after the first failure.' | ||||
|     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: 'Environment variables to be passed to the shell script.' | ||||
|     description: "Environment variables to expose to the remote script, format: key=value,key2=value2." | ||||
|   envs_format: | ||||
|     description: 'Flexible configuration for environment value transfer.' | ||||
|     description: "Format specification for environment variable transfer (for advanced usage)." | ||||
|   debug: | ||||
|     description: 'Enable debug mode.' | ||||
|     description: "Set to true to enable verbose logging for troubleshooting connection issues." | ||||
|   allenvs: | ||||
|     description: 'pass all environment variable to shell script.' | ||||
|     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)." | ||||
|   capture_stdout: | ||||
|     description: "When true, captures and returns standard output from the commands as action output." | ||||
|     default: "false" | ||||
|  | ||||
| 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 }} | ||||
|  | ||||
| branding: | ||||
|   icon: 'terminal' | ||||
|   color: 'gray-dark' | ||||
|   icon: "terminal" | ||||
|   color: "gray-dark" | ||||
|   | ||||
| @@ -1,7 +1,77 @@ | ||||
| #!/bin/sh | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| set -eu | ||||
| set -o errexit | ||||
| set -o nounset | ||||
| set -o 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 detect_client_info() { | ||||
|   if [ -n "${SSH_CLIENT_OS-}" ]; then | ||||
|     CLIENT_PLATFORM="${SSH_CLIENT_OS}" | ||||
|   else | ||||
|     local kernel | ||||
|     kernel="$(uname -s)" | ||||
|     case "${kernel}" in | ||||
|     Darwin) | ||||
|       CLIENT_PLATFORM="darwin" | ||||
|       ;; | ||||
|     Linux) | ||||
|       CLIENT_PLATFORM="linux" | ||||
|       ;; | ||||
|     Windows) | ||||
|       CLIENT_PLATFORM="windows" | ||||
|       ;; | ||||
|     *) | ||||
|       echo "Unknown, unsupported platform: ${kernel}." >&2 | ||||
|       echo "Supported platforms: Linux, Darwin and Windows." >&2 | ||||
|       echo "Bailing out." >&2 | ||||
|       exit 2 | ||||
|       ;; | ||||
|     esac | ||||
|   fi | ||||
|  | ||||
|   if [ -n "${SSH_CLIENT_ARCH-}" ]; then | ||||
|     CLIENT_ARCH="${SSH_CLIENT_ARCH}" | ||||
|   else | ||||
|     local machine | ||||
|     machine="$(uname -m)" | ||||
|     case "${machine}" in | ||||
|     x86_64* | i?86_64* | amd64*) | ||||
|       CLIENT_ARCH="amd64" | ||||
|       ;; | ||||
|     aarch64* | arm64*) | ||||
|       CLIENT_ARCH="arm64" | ||||
|       ;; | ||||
|     *) | ||||
|       echo "Unknown, unsupported architecture (${machine})." >&2 | ||||
|       echo "Supported architectures x86_64, i686, arm64." >&2 | ||||
|       echo "Bailing out." >&2 | ||||
|       exit 3 | ||||
|       ;; | ||||
|     esac | ||||
|   fi | ||||
| } | ||||
|  | ||||
| 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 "Will download ${CLIENT_BINARY} from ${DOWNLOAD_URL_PREFIX}" | ||||
| curl -fsSL --retry 5 --keepalive-time 2 "${DOWNLOAD_URL_PREFIX}/${CLIENT_BINARY}" -o ${TARGET} | ||||
| chmod +x ${TARGET} | ||||
|  | ||||
| echo "======= CLI Version =======" | ||||
| sh -c "${TARGET} --version" # print version | ||||
| echo "===========================" | ||||
| if [[ "$INPUT_CAPTURE_STDOUT" == 'true' ]]; then | ||||
|   echo 'stdout<<EOF' >>$GITHUB_OUTPUT          # use heredoc for multiline output | ||||
|   sh -c "${TARGET} $*" | tee -a $GITHUB_OUTPUT # run the command | ||||
|   echo 'EOF' >>$GITHUB_OUTPUT | ||||
| else | ||||
|   sh -c "${TARGET} $*" # run the command | ||||
| 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 | ||||
		Reference in New Issue
	
	Block a user