New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

deploy-toolkit

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

deploy-toolkit

A toolkit make it easy(with plain config) to manipulate(upload/download/exec command) server via ssh, can be used to deploy stuffs or CI/CD

latest
Source
npmnpm
Version
0.1.1
Version published
Weekly downloads
22
175%
Maintainers
1
Weekly downloads
 
Created
Source

Deploy toolkit

A toolkit make it easy(with plain config) to manipulate(upload/download/exec command) server via `ssh`, can be used to deploy stuffs or CI/CD.
Travis CI code with typescript npm version npm version

All actions are run in sequence, and you can set allow failure for specific action(wont stop the sequence even it failed).

Exmaple

import { deploy, runShellCmd,  findFileRecursive, addGitTag} from 'deploy-toolkit'
import fs from 'fs'
import path from 'path'

const config = {
  // ssh connection config
  ssh: {
    host: 'my.server.com',
    username: 'fancy',
    // // use password if you prefer password
    // password: '123456'
    // or private ssh key file path(or key text content)
    //   use ~ as user homedir
    privateKey: '~/.ssh/my-private-key'
    // set passphrase if private key is encrypted
    passphrase: '3344',
  },
  // whether to show command execution logs
  log: true,
  // commands sequence, will execute by its order
  cmds: [
    {
      // exec command
      type: 'cmd',
      // command arguments list
      args: ['mkdir', '-p', 'saiya/test'],
      // command work directory on remote server
      cwd: '/home/user'
    },
    {
      type: 'cmd',
      args: ['pm2', 'stop', 'my-fancy-app'],
      // if pm2 stop failed, still continue to run the following cmds
      allowFailure: true
    },
    {
      type: 'cmd',
      args: ['ls', 'saiya', '-l'],
      cwd: '/home/user'
    },
    {
      // upload files
      type: 'upload',
      // files' glob pattern, could also be a file/dir path
      src: path.join(__dirname, '../*/*.json'),
      // if upload multi files with glob pattern, srcPrefix is needed to determine to saved path on server
      //  no need if `src` is certain a file/dir path
      srcPrefix: path.join(__dirname, '..'),
      // server directory path to save the files
      dest: '/home/kk/saiya'
    },
    {
      // download file, only support download a single file at a time
      type: 'download',
      // source file path on server
      src: '/home/kk/start.sh',
      // saved path in local
      dest: path.join(__dirname, 'gg.sh')
    }
  ]
}

// run commands
deploy(config).then(() => {
  console.log('all done!')
}).catch((err) => {
  console.warn(err)
})

// run local shell commands
runShellCmd('ls', ['-l']).then((res) => {
  console.log('ls response', res)
})

// find closest package.json file full path, return '' if not found
console.log(findFileRecursive('package.json'))
// found closest .git dir full path from current work dir, return '' if not found
console.log(findFileRecursive('.git', process.cwd(), true))

// add git tag & puth to remote, use `v${package.version}` in package.json as tag name by default
addGitTag().then((tagName) => {
  console.log('done, has added tag', tagName)
})

// sepecify the tag name
addGitTag('v10.0.0-beta').then(() => {
  console.log('done')
})

Install

yarn add deploy-toolkit

or

npm i deploy-toolkit -D

Usage

deploy

Deploy stuffs to remote server with simple json config, you can upload/download/execute-command on remote server.

// import the main function like this
import { deploy } from 'deploy-toolkit'
// // you can import the following types if you are using typescript
// import { IDeployConfig } from 'deploy-toolkit'

function deploy(deployCmd: IDeployConfig): Promise<void>

/** deploy confgi */
interface IDeployConfig {
    /** ssh connection config */
    ssh: ISshConfig
    /** whether to show log when executing cmds */
    log?: boolean
    /** command sequence */
    cmds: ICmds
}

/** SSH Connection config */
interface ISshConfig {
    /** Hostname or IP address of the server. */
    host: string
    /** Port number of the server. */
    port?: number
    /** Username for authentication. */
    username?: string
    /** Password for password-based user authentication. */
    password?: string
    /** file path of the private key, or the private key text content */
    privateKey?: string
    /** For an encrypted private key, this is the passphrase used to decrypt it. */
    passphrase?: string
    /** any other options from ssh2 ConnectConfig */
    [k: string]: any
}
/** commands sequence */
type ICmds = ICmd[]

/** command */
type ICmd = IUploadConfig | IDownloadConfig | IRunConfig | IScriptConfig

/** upload config */
interface IUploadConfig {
    type: 'upload'
    /** source file(in local), could be a specified file/directory path or a glob pattern */
    src: string
    /** if src is a glob pattern, then srcPrefix is need, to determine the path save on server. omit it if src is a spicifed file/directory path */
    srcPrefix?: string
    /** destination path(on server), should be a file path if src is a specified file, or a directory for other situations */
    dest: string
    /** allow failure, so the command sequence will continue to run even this failed */
    allowFailure?: boolean
}

/** download config */
interface IDownloadConfig {
    type: 'download'
    /** source file path(on server) */
    src: string
    /** dest save path(in local) */
    dest: string
    /** allow failure, so the command sequence will continue to run even this failed */
    allowFailure?: boolean
}

/** custom command */
interface IRunConfig {
    type: 'cmd'
    /** cmd arguments */
    args: string[]
    /** cmd work directory */
    cwd?: string
    /** options */
    options?: {
        /** another way to set work directory, will be rewrite if set outside */
        cwd?: string
        /** extra options for ssh2.exec */
        options?: Object
        /** input for the command */
        stdin?: string
        /** output */
        stream?: 'stdout' | 'stderr' | 'both'
        /** stdout event */
        onStdout?: ((chunk: Buffer) => void)
        /** stderror event */
        onStderr?: ((chunk: Buffer) => void)
    }
    /** allow failure, so the command sequence will continue to run even this failed */
    allowFailure?: boolean
}


/**
 * custom script
 */ 
interface IScriptConfig {
  type: 'script'
  /* custom shebang, default #!/usr/bin/env bash */
  shebang?: string
  /* shell name, default bash. if shebang specified, then shell will be used */
  shell?: string
  /* script content, you can use DOWNLOAD/UPLOAD keywords to download or upload file */
  script: string
  /* initial work dir */
  cwd?: string
  /** allow failure, so the command sequence will continue to run even this failed */
  allowFailure?: boolean
}

Example

import { deploy, IDeployConfig, runShellCmd, findFileRecursive } from '../src/'
import path from 'path'

const config: IDeployConfig = {
  ssh: {
    host: '10.213.85.1',
    username: 'deploy',
    password: 'passw0rp!'
  },
  log: true,
  cmds: [
    {
      type: 'cmd',
      args: ['mkdir', '-p', 'saiya/test'],
      cwd: '~/Documents'
    },
    {
      type: 'download',
      src: '/home/deploy/start.sh',
      dest: path.join(__dirname, 'start.sh')
    },
    {
      type: 'upload',
      src: '/home/user1/Documents/Hobby/project1/dist',
      dest: '/home/deploy/Documents/project1'
    },
    {
      type: 'script',
      script: `
      cd ~
      rm -rf Document/project1
      UPLOAD /home/user1/Documents/Hobby/project1/dist > /home/deploy/Documents/project1
      cd Document/project1
      npm start
      DOWNLOAD  /home/deploy/Documents/project1/logs/latest.log > /home/user1/Documents/Hobby/logs/latest.log
      echo "done"
      `
    }
  ]
}


deploy(config).then(() => {
  console.log('all done')
})

runShellCmd

run shell command on local machine, a promise wrapper of node child_process.spawn, by default run the command in cwd process.cwd()

import { runShellCmd } from 'deploy-toolkit'
// return promise with execution result
function runShellCmd(cmd: string, options?: SpawnOptions): Promise<string>
function runShellCmd(
    cmd: string,
    args?: string[],
    options?: SpawnOptions
): Promise<string>

// check nodejs doc http://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options for detail explains
interface SpawnOptions {
    cwd?: string // default is process.cwd()
    env?: any
    stdio?: any
    detached?: boolean
    uid?: number
    gid?: number
    shell?: boolean | string
    windowsVerbatimArguments?: boolean
    windowsHide?: boolean
}

findFileRecursive

find a file/dir recursively from specified dir to the root until found, return '' if not found.

import { findFileRecursive } from 'deploy-toolkit'
/**
 * find a file(dir) recursive( aka try to find package.json, node_modules, etc.)
 * @param fileName file name(s)(or dir name(s) if isDir is true), if an array, return the first matched one
 * @param dir the initial dir path to find, use `process.cwd()` by default
 * @param isDir whether to find a dir, default false
 */
function findFileRecursive(
    fileName: string | string[],
    dir?: string,
    isDir?: boolean
): string

// e.g. find babel config file path

const babelRcPath = findFileRecursive([
    '.babelrc',
    '.babelrc.js',
    'babel.config.js'
])

addGitTag

add git tag and push it to remote, you can use it on postbuild or postpublish.
use v${package.version} in package.json as tag name by default, return the tagName after tag push

function addGitTag(tagName?: string): Promise<string>

Keywords

deploy

FAQs

Package last updated on 09 Apr 2019

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts