Merge pull request #5 from easingthemes/feature/SSH-DEPLOY-refactor
Feature/ssh deploy refactor
This commit is contained in:
		
						commit
						0711330570
					
				
							
								
								
									
										11
									
								
								.editorconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								.editorconfig
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| root = true | ||||
| 
 | ||||
| [*] | ||||
| charset = utf-8 | ||||
| end_of_line = lf | ||||
| indent_size = 2 | ||||
| indent_style = space | ||||
| insert_final_newline = true | ||||
| max_line_length = 120 | ||||
| tab_width = 4 | ||||
| trim_trailing_whitespace = true | ||||
							
								
								
									
										25
									
								
								.eslintrc.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								.eslintrc.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| module.exports = { | ||||
|   env: { | ||||
|     commonjs: true, | ||||
|     es6: true, | ||||
|     node: true | ||||
|   }, | ||||
|   extends: [ | ||||
|     'airbnb-base' | ||||
|   ], | ||||
|   globals: { | ||||
|     Atomics: 'readonly', | ||||
|     SharedArrayBuffer: 'readonly' | ||||
|   }, | ||||
|   parserOptions: { | ||||
|     ecmaVersion: 2018, | ||||
|   }, | ||||
|   rules: { | ||||
|     "comma-dangle": [ | ||||
|       "error", | ||||
|       "never" | ||||
|     ], | ||||
|     "no-console": "off", | ||||
|     "object-curly-newline": "off" | ||||
|   } | ||||
| }; | ||||
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -17,5 +17,5 @@ node_modules/ | ||||
| .env | ||||
| .env.test | ||||
| 
 | ||||
| # jetbrains | ||||
| # IDE | ||||
| .idea | ||||
|  | ||||
							
								
								
									
										10
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								README.md
									
									
									
									
									
								
							| @ -16,9 +16,11 @@ Pass configuration with `env` vars | ||||
| 
 | ||||
| This should be the private key part of an ssh key pair. | ||||
| The public key part should be added to the authorized_keys file on the server that receives the deployment. | ||||
| The keys should be generated using the PEM format. You can us this command | ||||
| 
 | ||||
| The keys should be generated using the PEM format. You can use this command | ||||
| `ssh-keygen -m PEM -t rsa -b 4096` | ||||
| ``` | ||||
| ssh-keygen -m PEM -t rsa -b 4096 | ||||
| ``` | ||||
| 
 | ||||
| 2. `REMOTE_HOST` [required] | ||||
| 
 | ||||
| @ -93,6 +95,4 @@ jobs: | ||||
| 
 | ||||
| ## Disclaimer | ||||
| 
 | ||||
| If you're using GitHub Actions, you'll probably already know that it's still in limited public beta, and GitHub advise against using Actions in production. | ||||
| 
 | ||||
| So, check your keys. Check your deployment paths. And use at your own risk. | ||||
| Check your keys. Check your deployment paths. And use at your own risk. | ||||
|  | ||||
| @ -13,12 +13,15 @@ inputs: | ||||
|     required: true | ||||
|   REMOTE_PORT: | ||||
|     description: "Remote port" | ||||
|     required: false | ||||
|     default: "22" | ||||
|   SOURCE: | ||||
|     description: "Source directory" | ||||
|     required: false | ||||
|     default: "" | ||||
|   TARGET: | ||||
|     description: "Target directory" | ||||
|     required: false | ||||
|     default: "/home/REMOTE_USER/" | ||||
| outputs: | ||||
|   status: | ||||
|  | ||||
							
								
								
									
										294
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										294
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
								
							| @ -49,6 +49,51 @@ module.exports = | ||||
| 
 | ||||
| module.exports = require("child_process"); | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 197: | ||||
| /***/ (function(module, __unusedexports, __webpack_require__) { | ||||
| 
 | ||||
| const { existsSync, mkdirSync, writeFileSync } = __webpack_require__(747); | ||||
| 
 | ||||
| const { | ||||
|   GITHUB_WORKSPACE | ||||
| } = process.env; | ||||
| 
 | ||||
| const validateDir = (dir) => { | ||||
|   if (!existsSync(dir)) { | ||||
|     console.log(`[SSH] Creating ${dir} dir in `, GITHUB_WORKSPACE); | ||||
|     mkdirSync(dir); | ||||
|     console.log('✅ [SSH] dir created.'); | ||||
|   } else { | ||||
|     console.log(`[SSH] ${dir} dir exist`); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| const validateFile = (filePath) => { | ||||
|   if (!existsSync(filePath)) { | ||||
|     console.log(`[SSH] Creating ${filePath} file in `, GITHUB_WORKSPACE); | ||||
|     try { | ||||
|       writeFileSync(filePath, '', { | ||||
|         encoding: 'utf8', | ||||
|         mode: 0o600 | ||||
|       }); | ||||
|       console.log('✅ [SSH] file created.'); | ||||
|     } catch (e) { | ||||
|       console.error('⚠️ [SSH] writeFileSync error', filePath, e.message); | ||||
|       process.abort(); | ||||
|     } | ||||
|   } else { | ||||
|     console.log(`[SSH] ${filePath} file exist`); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| module.exports = { | ||||
|   validateDir, | ||||
|   validateFile | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 243: | ||||
| @ -455,6 +500,50 @@ function getString(command,callback){ | ||||
| module.exports=commandline; | ||||
| 
 | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 613: | ||||
| /***/ (function(module, __unusedexports, __webpack_require__) { | ||||
| 
 | ||||
| const { writeFileSync } = __webpack_require__(747); | ||||
| const { join } = __webpack_require__(622); | ||||
| 
 | ||||
| const { | ||||
|   validateDir, | ||||
|   validateFile | ||||
| } = __webpack_require__(197); | ||||
| 
 | ||||
| const { | ||||
|   HOME | ||||
| } = process.env; | ||||
| 
 | ||||
| const addSshKey = (key, name) => { | ||||
|   const sshDir = join(HOME || __dirname, '.ssh'); | ||||
|   const filePath = join(sshDir, name); | ||||
| 
 | ||||
|   validateDir(sshDir); | ||||
|   validateFile(`${sshDir}/known_hosts`); | ||||
| 
 | ||||
|   try { | ||||
|     writeFileSync(filePath, key, { | ||||
|       encoding: 'utf8', | ||||
|       mode: 0o600 | ||||
|     }); | ||||
|   } catch (e) { | ||||
|     console.error('⚠️ writeFileSync error', filePath, e.message); | ||||
|     process.abort(); | ||||
|   } | ||||
| 
 | ||||
|   console.log('✅ Ssh key added to `.ssh` dir ', filePath); | ||||
| 
 | ||||
|   return filePath; | ||||
| }; | ||||
| 
 | ||||
| module.exports = { | ||||
|   addSshKey | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 622: | ||||
| @ -474,164 +563,82 @@ module.exports = require("util"); | ||||
| /***/ 676: | ||||
| /***/ (function(__unusedmodule, __unusedexports, __webpack_require__) { | ||||
| 
 | ||||
| const fs = __webpack_require__(747); | ||||
| const path = __webpack_require__(622); | ||||
| const commandExists = __webpack_require__(677); | ||||
| const nodeCmd = __webpack_require__(428); | ||||
| const nodeRsync = __webpack_require__(250); | ||||
| 
 | ||||
| const { REMOTE_HOST, REMOTE_USER, REMOTE_PORT, SSH_PRIVATE_KEY, DEPLOY_KEY_NAME, SOURCE, TARGET, ARGS, GITHUB_WORKSPACE, HOME } = process.env; | ||||
| console.log('GITHUB_WORKSPACE', GITHUB_WORKSPACE); | ||||
| const { validateRsync, validateInputs } = __webpack_require__(735); | ||||
| const { addSshKey } = __webpack_require__(613); | ||||
| 
 | ||||
| const { | ||||
|   REMOTE_HOST, REMOTE_USER, | ||||
|   REMOTE_PORT, SSH_PRIVATE_KEY, DEPLOY_KEY_NAME, | ||||
|   SOURCE, TARGET, ARGS, | ||||
|   GITHUB_WORKSPACE | ||||
| } = process.env; | ||||
| 
 | ||||
| const defaultOptions = { | ||||
|   ssh: true, | ||||
|   sshCmdArgs: ['-o StrictHostKeyChecking=no'], | ||||
|   recursive: true | ||||
| }; | ||||
| 
 | ||||
| console.log('[general] GITHUB_WORKSPACE: ', GITHUB_WORKSPACE); | ||||
| 
 | ||||
| const sshDeploy = (() => { | ||||
|   const rsync = ({ privateKey, port, src, dest, args }) => { | ||||
|         console.log(`Starting Rsync Action: ${src} to ${dest}`); | ||||
|     console.log(`[Rsync] Starting Rsync Action: ${src} to ${dest}`); | ||||
| 
 | ||||
|     try { | ||||
|       // RSYNC COMMAND
 | ||||
|             nodeRsync({ src, dest, args, privateKey, ssh: true, port, sshCmdArgs: ['-o StrictHostKeyChecking=no'], recursive: true }, (error, stdout, stderr, cmd) => { | ||||
|       nodeRsync({ | ||||
|         src, dest, args, privateKey, port, ...defaultOptions | ||||
|       }, (error, stdout, stderr, cmd) => { | ||||
|         if (error) { | ||||
|                     console.error('⚠️ Rsync error', error.message); | ||||
|                     console.log('stderr: ', stderr); | ||||
|                     console.log('stdout: ', stdout); | ||||
|                     console.log('cmd: ', cmd); | ||||
|           console.error('⚠️ [Rsync] error: ', error.message); | ||||
|           console.log('⚠️ [Rsync] stderr: ', stderr); | ||||
|           console.log('⚠️ [Rsync] stdout: ', stdout); | ||||
|           console.log('⚠️ [Rsync] cmd: ', cmd); | ||||
|           process.abort(); | ||||
|         } else { | ||||
|                     console.log("✅ Rsync finished.", stdout); | ||||
|           console.log('✅ [Rsync] finished.', stdout); | ||||
|         } | ||||
|       }); | ||||
|     } catch (err) { | ||||
|             console.error(`⚠️ An error happened:(.`, err.message, err.stack); | ||||
|       console.error('⚠️ [Rsync] command error: ', err.message, err.stack); | ||||
|       process.abort(); | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|     const init = ({ | ||||
|         src, | ||||
|         dest, | ||||
|         args, | ||||
|         host = 'localhost', | ||||
|         username, | ||||
|         privateKeyContent, | ||||
|         port | ||||
|     }) => { | ||||
|   const init = ({ src, dest, args, host = 'localhost', port, username, privateKeyContent }) => { | ||||
|     validateRsync(() => { | ||||
|             const privateKey = addSshKey(privateKeyContent, DEPLOY_KEY_NAME ||'deploy_key'); | ||||
| 
 | ||||
|             const remoteDest = username + '@' + host + ':' + dest; | ||||
|       const privateKey = addSshKey(privateKeyContent, DEPLOY_KEY_NAME || 'deploy_key'); | ||||
|       const remoteDest = `${username}@${host}:${dest}`; | ||||
| 
 | ||||
|       rsync({ privateKey, port, src, dest: remoteDest, args }); | ||||
|     }); | ||||
|   }; | ||||
| 
 | ||||
|     const validateDir = (dir) => { | ||||
|         if (!fs.existsSync(dir)){ | ||||
|             console.log(`Creating ${dir} dir in `, GITHUB_WORKSPACE); | ||||
|             fs.mkdirSync(dir); | ||||
|         } else { | ||||
|             console.log(`${dir} dir exist`); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     const validateFile = (filePath) => { | ||||
|         if (!fs.existsSync(filePath)){ | ||||
|             console.log(`Creating ${filePath} file in `, GITHUB_WORKSPACE); | ||||
|             try { | ||||
|                 fs.writeFileSync(filePath, '', { | ||||
|                     encoding: 'utf8', | ||||
|                     mode: 0o600 | ||||
|                 }); | ||||
|             } catch (e) { | ||||
|                 console.error('⚠️ writeFileSync error', filePath, e.message); | ||||
|                 process.abort(); | ||||
|             } | ||||
|         } else { | ||||
|             console.log(`${filePath} file exist`); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     const addSshKey = (key, name) => { | ||||
|         const sshDir = path.join(HOME || __dirname, '.ssh'); | ||||
|         const filePath = path.join(sshDir, name); | ||||
| 
 | ||||
|         validateDir(sshDir); | ||||
|         validateFile(sshDir + '/known_hosts'); | ||||
| 
 | ||||
|         try { | ||||
|             fs.writeFileSync(filePath, key, { | ||||
|                 encoding: 'utf8', | ||||
|                 mode: 0o600 | ||||
|             }); | ||||
|         } catch (e) { | ||||
|             console.error('⚠️ writeFileSync error', filePath, e.message); | ||||
|             process.abort(); | ||||
|         } | ||||
| 
 | ||||
|         console.log('✅ Ssh key added to `.ssh` dir ', filePath); | ||||
| 
 | ||||
|         return filePath; | ||||
|     }; | ||||
| 
 | ||||
|     const validateRsync = (callback = () => {}) => { | ||||
|         const rsyncCli = commandExists.sync('rsync'); | ||||
| 
 | ||||
|         if (!rsyncCli) { | ||||
|             nodeCmd.get( | ||||
|                 'sudo apt-get --no-install-recommends install rsync', | ||||
|                 function(err, data, stderr){ | ||||
|                     if (err) { | ||||
|                         console.log('⚠️ Rsync installation failed ', err.message); | ||||
|                         process.abort(); | ||||
|                     } else { | ||||
|                         console.log('✅ Rsync installed. \n', data, stderr); | ||||
|                         callback(); | ||||
|                     } | ||||
|                 } | ||||
|             ); | ||||
|         } else { | ||||
|             callback(); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|   return { | ||||
|     init | ||||
|     } | ||||
|   }; | ||||
| })(); | ||||
| 
 | ||||
| const validateInputs = (inputs) => { | ||||
|     const validInputs = Object.keys(inputs).filter((key) => { | ||||
|         const input = inputs[key]; | ||||
|         if (!input) { | ||||
|             console.error(`⚠️ ${key} is mandatory`); | ||||
|         } | ||||
| 
 | ||||
|         return input; | ||||
|     }); | ||||
| 
 | ||||
|     if (validInputs.length !== Object.keys(inputs).length) { | ||||
|         process.abort(); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| const run = () => { | ||||
|     validateInputs({SSH_PRIVATE_KEY, REMOTE_HOST, REMOTE_USER}); | ||||
|   validateInputs({ SSH_PRIVATE_KEY, REMOTE_HOST, REMOTE_USER }); | ||||
| 
 | ||||
|   sshDeploy.init({ | ||||
|         src: GITHUB_WORKSPACE + '/' + SOURCE || '', | ||||
|         dest: TARGET || '/home/' + REMOTE_USER + '/', | ||||
|     src: `${GITHUB_WORKSPACE}/${SOURCE}` || '', | ||||
|     dest: TARGET || `/home/${REMOTE_USER}/`, | ||||
|     args: ARGS ? [ARGS] : ['-rltgoDzvO'], | ||||
|     host: REMOTE_HOST, | ||||
|     port: REMOTE_PORT || '22', | ||||
|     username: REMOTE_USER, | ||||
|         privateKeyContent: SSH_PRIVATE_KEY, | ||||
|     privateKeyContent: SSH_PRIVATE_KEY | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| run(); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 677: | ||||
| @ -640,6 +647,59 @@ run(); | ||||
| module.exports = __webpack_require__(243); | ||||
| 
 | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 735: | ||||
| /***/ (function(module, __unusedexports, __webpack_require__) { | ||||
| 
 | ||||
| const { sync: commandExists } = __webpack_require__(677); | ||||
| const { get: nodeCmd } = __webpack_require__(428); | ||||
| 
 | ||||
| const validateRsync = (callback = () => {}) => { | ||||
|   const rsyncCli = commandExists.sync('rsync'); | ||||
| 
 | ||||
|   if (!rsyncCli) { | ||||
|     nodeCmd( | ||||
|       'sudo apt-get --no-install-recommends install rsync', | ||||
|       (err, data, stderr) => { | ||||
|         if (err) { | ||||
|           console.log('⚠️ [CLI] Rsync installation failed. Aborting ... ', err.message); | ||||
|           process.abort(); | ||||
|         } else { | ||||
|           console.log('✅ [CLI] Rsync installed. \n', data, stderr); | ||||
|           callback(); | ||||
|         } | ||||
|       } | ||||
|     ); | ||||
|   } else { | ||||
|     callback(); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| const validateInputs = (inputs) => { | ||||
|   const inputKeys = Object.keys(inputs); | ||||
|   const validInputs = inputKeys.filter((inputKey) => { | ||||
|     const inputValue = inputs[inputKey]; | ||||
| 
 | ||||
|     if (!inputValue) { | ||||
|       console.error(`⚠️ [INPUTS] ${inputKey} is mandatory`); | ||||
|     } | ||||
| 
 | ||||
|     return inputValue; | ||||
|   }); | ||||
| 
 | ||||
|   if (validInputs.length !== inputKeys.length) { | ||||
|     console.error(`⚠️ [INPUTS] Inputs not valid, aborting ...`); | ||||
|     process.abort(); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| module.exports = { | ||||
|   validateRsync, | ||||
|   validateInputs | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 747: | ||||
|  | ||||
							
								
								
									
										1658
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1658
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -9,10 +9,15 @@ | ||||
|     "rsyncwrapper": "3.0.1" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@zeit/ncc": "^0.20.5" | ||||
|     "@zeit/ncc": "^0.20.5", | ||||
|     "eslint": "^6.8.0", | ||||
|     "eslint-config-airbnb-base": "^14.1.0", | ||||
|     "eslint-plugin-import": "^2.20.2" | ||||
|   }, | ||||
|   "scripts": { | ||||
|     "build": "ncc build ./src/index.js -o dist" | ||||
|     "build": "npm run lint && ncc build ./src/index.js -o dist", | ||||
|     "lint": "eslint ./src/index.js", | ||||
|     "lint:fix": "eslint ./src/index.js --fix" | ||||
|   }, | ||||
|   "repository": { | ||||
|     "type": "git", | ||||
|  | ||||
							
								
								
									
										38
									
								
								src/helpers.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/helpers.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| const { existsSync, mkdirSync, writeFileSync } = require('fs'); | ||||
| 
 | ||||
| const { | ||||
|   GITHUB_WORKSPACE | ||||
| } = process.env; | ||||
| 
 | ||||
| const validateDir = (dir) => { | ||||
|   if (!existsSync(dir)) { | ||||
|     console.log(`[SSH] Creating ${dir} dir in `, GITHUB_WORKSPACE); | ||||
|     mkdirSync(dir); | ||||
|     console.log('✅ [SSH] dir created.'); | ||||
|   } else { | ||||
|     console.log(`[SSH] ${dir} dir exist`); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| const validateFile = (filePath) => { | ||||
|   if (!existsSync(filePath)) { | ||||
|     console.log(`[SSH] Creating ${filePath} file in `, GITHUB_WORKSPACE); | ||||
|     try { | ||||
|       writeFileSync(filePath, '', { | ||||
|         encoding: 'utf8', | ||||
|         mode: 0o600 | ||||
|       }); | ||||
|       console.log('✅ [SSH] file created.'); | ||||
|     } catch (e) { | ||||
|       console.error('⚠️ [SSH] writeFileSync error', filePath, e.message); | ||||
|       process.abort(); | ||||
|     } | ||||
|   } else { | ||||
|     console.log(`[SSH] ${filePath} file exist`); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| module.exports = { | ||||
|   validateDir, | ||||
|   validateFile | ||||
| }; | ||||
							
								
								
									
										152
									
								
								src/index.js
									
									
									
									
									
								
							
							
						
						
									
										152
									
								
								src/index.js
									
									
									
									
									
								
							| @ -1,157 +1,75 @@ | ||||
| #!/usr/bin/env node
 | ||||
| const fs = require('fs'); | ||||
| const path = require('path'); | ||||
| const commandExists = require('command-exists'); | ||||
| const nodeCmd = require('node-cmd'); | ||||
| const nodeRsync = require('rsyncwrapper'); | ||||
| 
 | ||||
| const { REMOTE_HOST, REMOTE_USER, REMOTE_PORT, SSH_PRIVATE_KEY, DEPLOY_KEY_NAME, SOURCE, TARGET, ARGS, GITHUB_WORKSPACE, HOME } = process.env; | ||||
| console.log('GITHUB_WORKSPACE', GITHUB_WORKSPACE); | ||||
| const { validateRsync, validateInputs } = require('./rsyncCli'); | ||||
| const { addSshKey } = require('./sshKey'); | ||||
| 
 | ||||
| const { | ||||
|   REMOTE_HOST, REMOTE_USER, | ||||
|   REMOTE_PORT, SSH_PRIVATE_KEY, DEPLOY_KEY_NAME, | ||||
|   SOURCE, TARGET, ARGS, | ||||
|   GITHUB_WORKSPACE | ||||
| } = process.env; | ||||
| 
 | ||||
| const defaultOptions = { | ||||
|   ssh: true, | ||||
|   sshCmdArgs: ['-o StrictHostKeyChecking=no'], | ||||
|   recursive: true | ||||
| }; | ||||
| 
 | ||||
| console.log('[general] GITHUB_WORKSPACE: ', GITHUB_WORKSPACE); | ||||
| 
 | ||||
| const sshDeploy = (() => { | ||||
|   const rsync = ({ privateKey, port, src, dest, args }) => { | ||||
|         console.log(`Starting Rsync Action: ${src} to ${dest}`); | ||||
|     console.log(`[Rsync] Starting Rsync Action: ${src} to ${dest}`); | ||||
| 
 | ||||
|     try { | ||||
|       // RSYNC COMMAND
 | ||||
|             nodeRsync({ src, dest, args, privateKey, ssh: true, port, sshCmdArgs: ['-o StrictHostKeyChecking=no'], recursive: true }, (error, stdout, stderr, cmd) => { | ||||
|       nodeRsync({ | ||||
|         src, dest, args, privateKey, port, ...defaultOptions | ||||
|       }, (error, stdout, stderr, cmd) => { | ||||
|         if (error) { | ||||
|                     console.error('⚠️ Rsync error', error.message); | ||||
|                     console.log('stderr: ', stderr); | ||||
|                     console.log('stdout: ', stdout); | ||||
|                     console.log('cmd: ', cmd); | ||||
|           console.error('⚠️ [Rsync] error: ', error.message); | ||||
|           console.log('⚠️ [Rsync] stderr: ', stderr); | ||||
|           console.log('⚠️ [Rsync] stdout: ', stdout); | ||||
|           console.log('⚠️ [Rsync] cmd: ', cmd); | ||||
|           process.abort(); | ||||
|         } else { | ||||
|                     console.log("✅ Rsync finished.", stdout); | ||||
|           console.log('✅ [Rsync] finished.', stdout); | ||||
|         } | ||||
|       }); | ||||
|     } catch (err) { | ||||
|             console.error(`⚠️ An error happened:(.`, err.message, err.stack); | ||||
|       console.error('⚠️ [Rsync] command error: ', err.message, err.stack); | ||||
|       process.abort(); | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|     const init = ({ | ||||
|         src, | ||||
|         dest, | ||||
|         args, | ||||
|         host = 'localhost', | ||||
|         username, | ||||
|         privateKeyContent, | ||||
|         port | ||||
|     }) => { | ||||
|   const init = ({ src, dest, args, host = 'localhost', port, username, privateKeyContent }) => { | ||||
|     validateRsync(() => { | ||||
|             const privateKey = addSshKey(privateKeyContent, DEPLOY_KEY_NAME ||'deploy_key'); | ||||
| 
 | ||||
|             const remoteDest = username + '@' + host + ':' + dest; | ||||
|       const privateKey = addSshKey(privateKeyContent, DEPLOY_KEY_NAME || 'deploy_key'); | ||||
|       const remoteDest = `${username}@${host}:${dest}`; | ||||
| 
 | ||||
|       rsync({ privateKey, port, src, dest: remoteDest, args }); | ||||
|     }); | ||||
|   }; | ||||
| 
 | ||||
|     const validateDir = (dir) => { | ||||
|         if (!fs.existsSync(dir)){ | ||||
|             console.log(`Creating ${dir} dir in `, GITHUB_WORKSPACE); | ||||
|             fs.mkdirSync(dir); | ||||
|         } else { | ||||
|             console.log(`${dir} dir exist`); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     const validateFile = (filePath) => { | ||||
|         if (!fs.existsSync(filePath)){ | ||||
|             console.log(`Creating ${filePath} file in `, GITHUB_WORKSPACE); | ||||
|             try { | ||||
|                 fs.writeFileSync(filePath, '', { | ||||
|                     encoding: 'utf8', | ||||
|                     mode: 0o600 | ||||
|                 }); | ||||
|             } catch (e) { | ||||
|                 console.error('⚠️ writeFileSync error', filePath, e.message); | ||||
|                 process.abort(); | ||||
|             } | ||||
|         } else { | ||||
|             console.log(`${filePath} file exist`); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     const addSshKey = (key, name) => { | ||||
|         const sshDir = path.join(HOME || __dirname, '.ssh'); | ||||
|         const filePath = path.join(sshDir, name); | ||||
| 
 | ||||
|         validateDir(sshDir); | ||||
|         validateFile(sshDir + '/known_hosts'); | ||||
| 
 | ||||
|         try { | ||||
|             fs.writeFileSync(filePath, key, { | ||||
|                 encoding: 'utf8', | ||||
|                 mode: 0o600 | ||||
|             }); | ||||
|         } catch (e) { | ||||
|             console.error('⚠️ writeFileSync error', filePath, e.message); | ||||
|             process.abort(); | ||||
|         } | ||||
| 
 | ||||
|         console.log('✅ Ssh key added to `.ssh` dir ', filePath); | ||||
| 
 | ||||
|         return filePath; | ||||
|     }; | ||||
| 
 | ||||
|     const validateRsync = (callback = () => {}) => { | ||||
|         const rsyncCli = commandExists.sync('rsync'); | ||||
| 
 | ||||
|         if (!rsyncCli) { | ||||
|             nodeCmd.get( | ||||
|                 'sudo apt-get --no-install-recommends install rsync', | ||||
|                 function(err, data, stderr){ | ||||
|                     if (err) { | ||||
|                         console.log('⚠️ Rsync installation failed ', err.message); | ||||
|                         process.abort(); | ||||
|                     } else { | ||||
|                         console.log('✅ Rsync installed. \n', data, stderr); | ||||
|                         callback(); | ||||
|                     } | ||||
|                 } | ||||
|             ); | ||||
|         } else { | ||||
|             callback(); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|   return { | ||||
|     init | ||||
|     } | ||||
|   }; | ||||
| })(); | ||||
| 
 | ||||
| const validateInputs = (inputs) => { | ||||
|     const validInputs = Object.keys(inputs).filter((key) => { | ||||
|         const input = inputs[key]; | ||||
|         if (!input) { | ||||
|             console.error(`⚠️ ${key} is mandatory`); | ||||
|         } | ||||
| 
 | ||||
|         return input; | ||||
|     }); | ||||
| 
 | ||||
|     if (validInputs.length !== Object.keys(inputs).length) { | ||||
|         process.abort(); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| const run = () => { | ||||
|     validateInputs({SSH_PRIVATE_KEY, REMOTE_HOST, REMOTE_USER}); | ||||
|   validateInputs({ SSH_PRIVATE_KEY, REMOTE_HOST, REMOTE_USER }); | ||||
| 
 | ||||
|   sshDeploy.init({ | ||||
|         src: GITHUB_WORKSPACE + '/' + SOURCE || '', | ||||
|         dest: TARGET || '/home/' + REMOTE_USER + '/', | ||||
|     src: `${GITHUB_WORKSPACE}/${SOURCE}` || '', | ||||
|     dest: TARGET || `/home/${REMOTE_USER}/`, | ||||
|     args: ARGS ? [ARGS] : ['-rltgoDzvO'], | ||||
|     host: REMOTE_HOST, | ||||
|     port: REMOTE_PORT || '22', | ||||
|     username: REMOTE_USER, | ||||
|         privateKeyContent: SSH_PRIVATE_KEY, | ||||
|     privateKeyContent: SSH_PRIVATE_KEY | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| run(); | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										46
									
								
								src/rsyncCli.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/rsyncCli.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | ||||
| const { sync: commandExists } = require('command-exists'); | ||||
| const { get: nodeCmd } = require('node-cmd'); | ||||
| 
 | ||||
| const validateRsync = (callback = () => {}) => { | ||||
|   const rsyncCli = commandExists.sync('rsync'); | ||||
| 
 | ||||
|   if (!rsyncCli) { | ||||
|     nodeCmd( | ||||
|       'sudo apt-get --no-install-recommends install rsync', | ||||
|       (err, data, stderr) => { | ||||
|         if (err) { | ||||
|           console.log('⚠️ [CLI] Rsync installation failed. Aborting ... ', err.message); | ||||
|           process.abort(); | ||||
|         } else { | ||||
|           console.log('✅ [CLI] Rsync installed. \n', data, stderr); | ||||
|           callback(); | ||||
|         } | ||||
|       } | ||||
|     ); | ||||
|   } else { | ||||
|     callback(); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| const validateInputs = (inputs) => { | ||||
|   const inputKeys = Object.keys(inputs); | ||||
|   const validInputs = inputKeys.filter((inputKey) => { | ||||
|     const inputValue = inputs[inputKey]; | ||||
| 
 | ||||
|     if (!inputValue) { | ||||
|       console.error(`⚠️ [INPUTS] ${inputKey} is mandatory`); | ||||
|     } | ||||
| 
 | ||||
|     return inputValue; | ||||
|   }); | ||||
| 
 | ||||
|   if (validInputs.length !== inputKeys.length) { | ||||
|     console.error(`⚠️ [INPUTS] Inputs not valid, aborting ...`); | ||||
|     process.abort(); | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| module.exports = { | ||||
|   validateRsync, | ||||
|   validateInputs | ||||
| } | ||||
							
								
								
									
										37
									
								
								src/sshKey.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/sshKey.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | ||||
| const { writeFileSync } = require('fs'); | ||||
| const { join } = require('path'); | ||||
| 
 | ||||
| const { | ||||
|   validateDir, | ||||
|   validateFile | ||||
| } = require('./helpers'); | ||||
| 
 | ||||
| const { | ||||
|   HOME | ||||
| } = process.env; | ||||
| 
 | ||||
| const addSshKey = (key, name) => { | ||||
|   const sshDir = join(HOME || __dirname, '.ssh'); | ||||
|   const filePath = join(sshDir, name); | ||||
| 
 | ||||
|   validateDir(sshDir); | ||||
|   validateFile(`${sshDir}/known_hosts`); | ||||
| 
 | ||||
|   try { | ||||
|     writeFileSync(filePath, key, { | ||||
|       encoding: 'utf8', | ||||
|       mode: 0o600 | ||||
|     }); | ||||
|   } catch (e) { | ||||
|     console.error('⚠️ writeFileSync error', filePath, e.message); | ||||
|     process.abort(); | ||||
|   } | ||||
| 
 | ||||
|   console.log('✅ Ssh key added to `.ssh` dir ', filePath); | ||||
| 
 | ||||
|   return filePath; | ||||
| }; | ||||
| 
 | ||||
| module.exports = { | ||||
|   addSshKey | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user