#!/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 sshDeploy = (() => { const rsync = ({ privateKey, port, src, dest, args }) => { console.log(`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) => { if (error) { console.error('⚠️ Rsync error', error.message); process.abort(); } else { console.log("✅ Rsync finished.", stdout); } }); } catch (err) { console.error(`⚠️ An error happened:(.`, err.message, err.stack); process.abort(); } }; const init = ({ src, dest, args, host = 'localhost', username, privateKeyContent, port }) => { validateRsync(() => { 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 = inputs.filter(input => { if (!input) { console.error(`⚠️ ${input} is mandatory`); } return input; }); if (validInputs.length !== inputs.length) { process.abort(); } }; const run = () => { validateInputs([SSH_PRIVATE_KEY, REMOTE_HOST, REMOTE_USER]); sshDeploy.init({ 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, }); }; run();