Giter VIP home page Giter VIP logo

deploy-kit's Introduction

Deploy-kit

A nice deployment tool supports ftp and sftp. Used directly or with built-in plugins, such as webpack-plugin.

image

yarn add deploy-kit --dev

Basic usage

const client = require('deploy-kit')

client.sftp({
  // sever account, address, port
  server: 'user:[email protected]:22',
  // deploy all files in the directory
  workspace: __dirname + '/dist',
  // ignore the matched files (glob pattern: https://github.com/isaacs/node-glob#glob-primer)
  // support array of glob pattern
  ignore: '**/*.map',
  // where the files are placed on the server
  deployTo: '/data1/htdocs/testapp',
  // you can specify different place for each file
  rules: [
    {
      test: /dist\/(.*)$/,
      // $1, $2... means the parenthesized substring matches
      // [$n] will be replaced with matched string
      dest: 'public/static/[$1]'
    },
    {
      test: /views\/((?:[^/]+\/)*?[^\/]+).html$/,
      dest: 'app/views/[$1].phtml'
    }
  ]
})
.exec()

or use ftp

client.ftp({
  ...
})
.exec()

options:

option type description
server string server info includes username, password, address, and port. e.g. user:[email protected]:22
workspace string deploy all files in the directory
ignore string or array of string ignore the matched files (glob pattern: https://github.com/isaacs/node-glob#glob-primer)
deployTo string where the files are placed.
rules array of rule rule use to speicify different place for each file. each rule has a test and a dest property.

about rule:

{
  test: /dist\/(.*)$/,
  // $1, $2... means the parenthesized substring matches
  // [$n] will be replaced with matched string
  dest: 'public/static/[$1]'
}

test property is a RegExp pattern, use to match specified file with realpath of the file. dest property is the custom filename of matched file. you can extract any part from realpath as a part of dest by parenthesis.

Command Line Interface(CLI)

$ ./bin/deploy-sftp --server user:pwd@server_address:port --ignore **/*.map ./dist /data1/htdocs/testapp
$ ./bin/deploy-ftp ...

cli options:


  Usage: deploy-sftp [options] [workspace] [deployTo]


  Options:

    -V, --version           output the version number
    -c, --config <path>     use configuration from this file
    -s, --server <address>  server account, address. (e.g. user:pwd@address:port)
    -i, --ignore <pattern>  ignore the matched files
    -h, --help              output usage information

  Examples:

    // use configuration from a file
    $ deploy-sftp --config deploy.js
    // deploy files in ./dist to /data1/htdocs/testapp on 10.13.1.2
    $ deploy-sftp -s user:[email protected]:22 --i *.map ./dist /data1/htdocs/testapp

  version: 3.1.0

using config file

You can use configuration file instead of cli args. Just create a deploy.js file in the root directory of your project and exports your configuration like this:

module.exports = {
  server: '',
  workspace: '',
  ignore: '',
  deployTo: '',
  rules: []
}

Runing directly without any arg.

$ ./bin/deploy-sftp

If you prefer to place the configuration file in another place, you can use -c, --config <path> option like this:

$ ./bin/deploy-sftp --config ./config/your_conf.js

Used with plugins

each plugin can called like this:

new DeployPlugin([config])

config is optional. if you omitted the config, Deploy-kit will automatic load the deploy.js from the process.cwd().

  • sftp-webpack-plugin
const DeployPlugin = require('deploy-kit/plugins/sftp-webpack-plugin')

// webpack configuration
moudle.exports = {
  ...
  plugins: [
    new DeployPlugin()
  ]
}

todos:

  • sftp-gulp-plugin
  • ftp-gulp-plugin
  • sftp-fis-plugin

How to write a plugin

todo

deploy-kit's People

Contributors

xiaoyann avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

deploy-kit's Issues

Can't create missing folder on remote server

I think, you should make thees changes

SftpDeploy.prototype.upload = function (file, callback) { this.client.upload(file.filepath, file.dest, callback) }

In your case I have error during upload when folder isn't exists.

Error: handle is not a Buffer

/Users/xiaofeng/working/jinyinwu/official-website/jinyinwu/frontend/node_modules/ssh2-streams/lib/sftp.js:879
throw new Error('handle is not a Buffer');
^

Error: handle is not a Buffer
at SFTPStream.writeData (/Users/xiaofeng/working/jinyinwu/official-website/jinyinwu/frontend/node_modules/ssh2-streams/lib/sftp.js:879:11)
at SFTPWrapper.write (/Users/xiaofeng/working/jinyinwu/official-website/jinyinwu/frontend/node_modules/ssh2/lib/SFTPWrapper.js:48:23)
at /Users/xiaofeng/working/jinyinwu/official-website/jinyinwu/frontend/node_modules/scp2/lib/client.js:195:16
at iterate (/Users/xiaofeng/working/jinyinwu/official-website/jinyinwu/frontend/node_modules/scp2/node_modules/async/lib/async.js:146:13)
at Object.async.eachSeries (/Users/xiaofeng/working/jinyinwu/official-website/jinyinwu/frontend/node_modules/scp2/node_modules/async/lib/async.js:162:9)
at _write (/Users/xiaofeng/working/jinyinwu/official-website/jinyinwu/frontend/node_modules/scp2/lib/client.js:193:15)
at /Users/xiaofeng/working/jinyinwu/official-website/jinyinwu/frontend/node_modules/scp2/lib/client.js:244:11
at SFTPStream._transform (/Users/xiaofeng/working/jinyinwu/official-website/jinyinwu/frontend/node_modules/ssh2-streams/lib/sftp.js:387:17)
at SFTPStream.Transform._read (_stream_transform.js:167:10)
at SFTPStream._read (/Users/xiaofeng/working/jinyinwu/official-website/jinyinwu/frontend/node_modules/ssh2-streams/lib/sftp.js:170:15)
at SFTPStream.Transform._write (_stream_transform.js:155:12)
at doWrite (_stream_writable.js:333:12)
at writeOrBuffer (_stream_writable.js:319:5)
at SFTPStream.Writable.write (_stream_writable.js:246:11)
at Channel.ondata (_stream_readable.js:555:20)
at emitOne (events.js:96:13)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

username: matched[1], TypeError: Cannot read property '1' of null

I tried to use this plugin for webpack only for tests in the first time, however I got this error:

username: matched[1], ^ TypeError: Cannot read property '1' of null

This is my deploy.js:

const client = require("deploy-kit");

client.sftp({
  
  server: 'myuser:[email protected]:222',
  workspace: __dirname,
  ignore: '**/*.map',
  deployTo: './public_html/somefolder',
  rules: [
    {
      test: /dist\/(.*)$/,
      dest: 'public/static/[$1]'
    },
    {
      test: /views\/((?:[^/]+\/)*?[^\/]+).html$/,
      dest: 'app/views/[$1].phtml'
    }
  ]
})
.exec()

To post here I change my user info for dummy text, but it was placed right.

support for hidden files like .htaccess

Hi @xiaoyann , great work - thanks a lot!

It seems as hidden files are not copied, or is this due to my environment?!
Would be great to see hidden files transferred with the sftp client (e.g. .htpasswd, .gitignore, .htaccess, .someSecretFile, etc.)

Cheers,
Johannes

upload error

Hi,

I'm seeing upload failures that don't make sense. It happens only if a file does NOT exists on the remote. Once I manually upload the dist folder and then rerun the build command, everything works as expected.

npm run build
> webpack-babel-react-revisited@ build /Users/bas/Documents/Projects/Digibitious.SchokWebsite
> webpack -p --env.production --env.platform=web --progress


clean-webpack-plugin: /Users/bas/Documents/Projects/Digibitious.SchokWebsite/dist has been removed.
Hash: 68d797da305bdadb1cd8                                                           
Version: webpack 3.10.0
Time: 5767ms
                                             Asset     Size  Chunks                    Chunk Names
  assets/images/afbeelding-1-assets/[email protected]  78.9 kB          [emitted]         
assets/images/8ec7f5aa9e00069455fa0183081740c3.png   131 kB          [emitted]         
                                     assets/app.js   163 kB       0  [emitted]         main
                             assets/css/styles.css  98.6 kB       0  [emitted]         main
                                        index.html  34.9 kB          [emitted]         
                                         over.html  7.29 kB          [emitted]         
  assets/images/afbeelding-1-assets/[email protected]  25.6 kB          [emitted]         
assets/images/d65a8acf3a4236db31b93475e11ff30f.svg   959 kB          [emitted]  [big]  
  assets/images/afbeelding-1-assets/[email protected]  44.7 kB          [emitted]         
  assets/images/afbeelding-1-assets/[email protected]  83.8 kB          [emitted]         
  assets/images/afbeelding-1-assets/[email protected]  90.6 kB          [emitted]         
  assets/images/afbeelding-1-assets/[email protected]   141 kB          [emitted]         
  assets/images/afbeelding-1-assets/[email protected]   238 kB          [emitted]         
  assets/images/afbeelding-1-assets/[email protected]   315 kB          [emitted]  [big]  
                    assets/images/afbeelding-1.psd    11 MB          [emitted]  [big]  
   [2] ./src/js/app.js 515 bytes {0} [built]
   [3] ./src/scss/style.scss 41 bytes {0} [built]
   [4] ./src/images/[email protected] 96 bytes {0} [built]
   [5] ./src/images/face.svg 96 bytes {0} [built]
   [6] (webpack)/buildin/global.js 509 bytes {0} [built]
   [8] ./src/js/bundle.js 5.6 kB {0} [built]
   [9] ./src/js/portfolio.js 790 bytes {0} [built]
  [10] ./src/js/analytics.js 508 bytes {0} [built]
  [11] ./node_modules/css-loader!./node_modules/sass-loader/lib/loader.js?name=assets/css/[name].[ext]!./src/scss/style.scss 98.9 kB [built]
    + 6 hidden modules
Child html-webpack-plugin for "index.html":
     1 asset
       [0] ./node_modules/html-webpack-plugin/lib/loader.js!./src/index.html 35.7 kB {0} [built]
       [2] (webpack)/buildin/global.js 509 bytes {0} [built]
       [3] (webpack)/buildin/module.js 517 bytes {0} [built]
        + 1 hidden module
Child html-webpack-plugin for "over.html":
     1 asset
       [0] ./node_modules/html-webpack-plugin/lib/loader.js!./src/over.html 7.7 kB {0} [built]
       [2] (webpack)/buildin/global.js 509 bytes {0} [built]
       [3] (webpack)/buildin/module.js 517 bytes {0} [built]
        + 1 hidden module
Child extract-text-webpack-plugin node_modules/extract-text-webpack-plugin/dist node_modules/css-loader/index.js!node_modules/sass-loader/lib/loader.js?name=assets/css/[name].[ext]!src/scss/style.scss:
       [0] ./node_modules/css-loader!./node_modules/sass-loader/lib/loader.js?name=assets/css/[name].[ext]!./src/scss/style.scss 98.9 kB {0} [built]
        + 1 hidden module
upload failure : assets/images/8ec7f5aa9e00069455fa0183081740c3.png ===> /demo/assets/images/8ec7f5aa9e00069455fa0183081740c3.png
Times: 0.04s  Files: 15
/Users/bas/Documents/Projects/Digibitious.SchokWebsite/node_modules/deploy-kit/lib/deploy.js:116
    if (err) throw err
             ^

Error: /demo/assets/images/8ec7f5aa9e00069455fa0183081740c3.png: No such file or directory
    at makeError (/Users/bas/Documents/Projects/Digibitious.SchokWebsite/node_modules/ftp/lib/connection.js:1067:13)
    at Parser.<anonymous> (/Users/bas/Documents/Projects/Digibitious.SchokWebsite/node_modules/ftp/lib/connection.js:113:25)
    at Parser.emit (events.js:160:13)
    at Parser._write (/Users/bas/Documents/Projects/Digibitious.SchokWebsite/node_modules/ftp/lib/parser.js:59:10)
    at doWrite (_stream_writable.js:407:12)
    at writeOrBuffer (_stream_writable.js:393:5)
    at Parser.Writable.write (_stream_writable.js:290:11)
    at Socket.ondata (/Users/bas/Documents/Projects/Digibitious.SchokWebsite/node_modules/ftp/lib/connection.js:273:20)
    at Socket.emit (events.js:160:13)
    at addChunk (_stream_readable.js:269:12)
    at readableAddChunk (_stream_readable.js:256:11)
    at Socket.Readable.push (_stream_readable.js:213:10)
    at TCP.onread (net.js:602:20)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! webpack-babel-react-revisited@ build: `webpack -p --env.production --env.platform=web --progress`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the webpack-babel-react-revisited@ build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/bas/.npm/_logs/2018-02-06T09_40_00_362Z-debug.log
// We are using node's native package 'path'
// https://nodejs.org/api/path.html
const path = require('path');
let webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ExtractSass = new ExtractTextPlugin({filename: "assets/css/styles.css"});
const CleanWebpackPlugin = require('clean-webpack-plugin');
const DeployPlugin = require('deploy-kit/plugins/ftp-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { readFileSync } = require('fs');
const ftpCred = readFileSync('.ftp-credentials', 'utf8').trim();

module.exports = (env = {}) => {
  const isProduction = env.production === true;
  const isDevelopment = env.development === true;

  const paths = {
    DIST: path.resolve(__dirname, 'dist'),
    SRC: path.resolve(__dirname, 'src'),
    JS: path.resolve(__dirname, 'src/js'),
    REMOTE: '/demo'
  };

  let conf = {
    entry: path.join(paths.JS, 'app.js'),

    output: {
      path: paths.DIST,
      filename: 'assets/app.js'
    },

    plugins: [
      new HtmlWebpackPlugin({
        filename: 'index.html',
        template: path.join(paths.SRC, 'index.html'),
        chunks: ['main']
      }),
      new HtmlWebpackPlugin({
        filename: 'over.html',
        template: path.join(paths.SRC, 'over.html'),
        chunks: ['main']
      }),
      new webpack.ProvidePlugin({
        $: "jquery",
        jQuery: "jquery",
        Popper: ['popper.js', 'default']
      }),
      ExtractSass,
      new CleanWebpackPlugin(['dist']),
      new CopyWebpackPlugin([{ from: 'src/images/content/', to: 'assets/images/'}])
    ],

    // Loaders configuration
    // We are telling webpack to use "babel-loader" for .js and .jsx files
    module: {
      rules: [
        {
          test: /\.js$/,
          include: path.resolve(__dirname, 'src'),
          use: [{
            loader: 'babel-loader',
            options: {
              presets: [
                ['es2015', {modules: false}]
              ]
            }
          }]
        },
        {
          test: /\.(scss)$/,
          use: ExtractSass.extract({
            fallback: 'style-loader',
            //resolve-url-loader may be chained before sass-loader if necessary
            use: [{
              loader: "css-loader" // translates CSS into CommonJS
            }, {
              loader: "sass-loader?name=assets/css/[name].[ext]" // compiles Sass to CSS
            }]
          })
        },
        {
          test: /\.(png|jpg|gif|svg)$/,
          loaders: [
            'file-loader?hash=sha512&digest=hex&name=assets/images/[hash].[ext]'
          ]
        },
        {
          test: /\.(eot|woff|ttf)$/,
          loaders: [
            'url-loader?name=fonts/images/[name].[ext]'
          ]
        }
      ]
    },
    // Enable importing JS files without specifying their's extenstion
    //
    // So we can write:
    // import MyComponent from './my-component';
    resolve: {
      extensions: ['.js']
    }
  };

  // environment specific
  if (isProduction) {
    conf.plugins.push(new DeployPlugin({
      server: ftpCred,
      workspace: paths.DIST,
      deployTo: paths.REMOTE,
      rules: [
        {
          test: /dist\/(.*)$/,
          // $1, $2... means the parenthesized substring matches
          // [$n] will be replaced with matched string
          dest: '/[$1]'
        },
      ]
    }));
  }

  return conf;
};

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.