Written in the beginning

Why write this article

Recently, I delivered a small multi-terminal project, the deployment of which was as minimal as possible. There was no need to build a CI pipeline for it, so I embarked on the road of investigation of automatic deployment scheme. Most of the nuggets were Jenkins + Docker, and two feasible schemes were obtained through investigation using pure NodeJS. Write it down as a learning record.

Why is it called simple Practice

Obviously, because it is easy to operate, especially for small agile development projects, the front end does not need to understand the traditional CI tools, such as Jenkins Circle CI, and do not need to pay attention to the continuous integration environment, as long as a Node environment can complete automatic deployment.

Train of thought

Assuming that we are now ready to publish our code to a sandbox environment, we can:

  • Soil method
    • Login SSH
    • CD Go to the corresponding resource directory
    • Drag the packaged resource files to this directory
  • First Upgrade
    • Write a script file and submit the file to the server through FTP
    • You can run it manuallynpm run deployRun the JS script
    • You can usehuskyRun the JS script before committing the code
  • Second Upgrade
    • usinggittheweb hookEach push triggers the hook, sending a request to the server, and the rest of the deployment is done on the server

First, earthwork is probably the least expensive, but the least efficient way to do it, especially in the Bugfix phase where you have to commit code all the time, package it manually every time, and deploy it manually. The first upgrade is through FTP, package the code locally, run the script manually, connect to the server and then submit to the resource folder of the server. This solution is actually good, but connecting to SSH requires exposing the server account password to the code, which is not recommended. The third upgrade, the ultimate solution, is all packaged and deployed to the server. So, there are two deployment options available. If you’re not familiar with FTP or Web hooks, don’t worry

Code implementation (pseudocode)

case1: ftp

const path = require('path');
const gulp = require('gulp');
const sftp = require('gulp-sftp-up4');

const config = {
    remotePath: 'Static resource path on server'.host: 'Server IP'.password: 'password'
};

gulp.src(path.resolve(__dirname, '.. /dist/**')).pipe(sftp(config));
Copy the code

The realization is very simple, that is, the content in dist is directly pushed from the local machine to the server XX directory, gulp as the carrier, and the push logic is implemented by gulp-SftP-UP4

case2: web hook

web hookThe principle is that at a node (push commit pull…) A request is submitted, with the repository information in the request body of the request

First you need to find it on Gitweb hook settings, our company uses GOgs as the code warehouseFill in the push address, select hook trigger event as each code push, so that each push code will request the above address, here I usepm2Here’s an easy onenode server

const childProcess = require('child_process');
const Koa = require('koa');
const Router = require('koa-router');
var bodyParser = require('koa-bodyparser');
const app = new Koa();
const router = new Router();

app.use(bodyParser());

router.post('/web-hook'.async (ctx, next) => {
    childProcess.exec('sh deploy.sh', { maxBuffer: 1024 * 1024 * 1024 }, (error, stdout, stderr) = > {});
    awaitnext(); }); . . . app.use(router.routes()).use(router.allowedMethods()); app.listen(8082.() = > {
    console.log('server is starting on port 8082! ');
});
Copy the code

The server receives the request, does the only thing and executes deploy.sh with shell script pseudocode below

#! /bin/bash
set -e

SOURCE_PATH='Project source directory'
DEPLOY_PATH='Directory of packaged files'
TAR="output.tar"

cd $SOURCE_PATH
git pull
git checkout master

echo 'git pull finished'

echo "Node version:"
node -v
echo "npm version:"
npm -v
echo "yarn version:"
yarn --version

yarn

if [ $? -ne 0 ]; then
    echo "yarn install failed!"
    exit 1
fi

rm -rf output
mkdir output

yarn build

if [ $? -ne 0 ]; then
    echo "build failed!"
    exit 1
fi

# compression
cd build
tar cvf $TAR. / *cd $DEPLOY_PATH
rm -rf *
mkdir dir
cd dir

mv $SOURCE_PATH/output/$TAR $DEPLOY_PATH/dir

# decompression
cd $DEPLOY_PATH/dir
tar xvf $TAR
rm -rf $TAR
echo 'Deployment complete'
Copy the code

The above completed each submission of the code, the server side will update the code, packaging, deployment, do not feel the developer, successfully free hands! The implementation is simple enough to pass the path to the script via environment variables if it is a multi-project deployment. Unfortunately, the error message of the child process will not be fed back to the client. If you want to make an error message, you can only open a scheduled task to capture logs, but it does not affect the normal operation of core functions.

conclusion

Regardless of the deployment of FTPORWeb Hook, they are not the final solution, but only a shadow of automatic deployment. The advantage is that it can more or less improve work efficiency. I will also record some engineering research results in Nuggets in the future