git hook and automatic deployment

Keywords: Programming github npm ssh git

Tencent cloud 11.11 is the first purchase of 1-core 2G cloud server of 88 yuan, and receives 9888 yuan voucher free of charge. Once 100 cloud products are folded

Then the last article goes on to say [git hook and Automated Deployment (I)] (https://segmentfault.com/a/11900021044092)

webhook

Definition

Webhooks allow you to build or set up integrations, such as GitHub Apps , which subscribe to certain events on GitHub.com. When one of those events is triggered, we'll send a HTTP POST payload to the webhook's configured URL. Webhooks can be used to update an external issue tracker, trigger CI builds, update a backup mirror, or even deploy to your production server. You're only limited by your imagination.

Pay attention to the key statements. When we trigger an event (such as git push), github will send a post request to my configured url and take some parameters

Automated deployment process

Let's play more regularly this time

Goal: npm run dp, a local command, can automatically package, upload and deploy projects

Process:
1. Local command triggers local shell script, automatic packaging and git add commit push
2.git push will make github send a post request to the target service
3. When the service is triggered, execute the relevant script
4. The script must make the target display directory pull files from github
5. After pulling, the automatic deployment is completed

webhook configuration

Set github

Enter github to create a new project helloworld, and add webhooks in the webhooks in the setting of the project

We can also configure passwords, trigger events, and so on

Here we choose application/json for content type

palyload

Let's take a look at the payload form

POST /payload HTTP/1.1
Host: localhost:4567
X-GitHub-Delivery: 72d3162e-cc78-11e3-81ab-4c9367dc0958
X-Hub-Signature: sha1=7d38cdd689735b008b3c702edd92eea23791c5f6
User-Agent: GitHub-Hookshot/044aadd
Content-Type: application/json
Content-Length: 6615
X-GitHub-Event: issues
{
  "action": "opened",
  "issue": {
    "url": "https://api.github.com/repos/octocat/Hello-World/issues/1347",
    "number": 1347,
    ...
  },
  "repository" : {
    "id": 1296269,
    "full_name": "octocat/Hello-World",
    "owner": {
      "login": "octocat",
      "id": 1,
      ...
    },
    ...
  },
  "sender": {
    "login": "octocat",
    "id": 1,
    ...
  }
}

This post request will have a unique request header, a repository related parameter, a sender related to the submitter, which will be used later when sending emails

Local script configuration

Technological process

  • Vue cli initialization project
  • Add remote library as the Hello World source in github
  • Configuration in npm sript
"dp": "npm run build && sh dp.sh"

-Script dp.sh

#!/bin/sh
echo 'Add to'
git add .
echo 'commit'
git commit -m 'dp'
echo 'Push in..'
git push origin master

In this case, we can implement npm run dp to complete automatic packing and uploading

npm scipt

When it comes to npm script, plug in. In fact, this is a shell script
The principle of npm script is very simple. Whenever npm run is executed, a new Shell will be created automatically, in which the specified script command will be executed. Therefore, as long as the Shell (generally Bash) can run the command, it can be written in the npm script.

In particular, npm run's new Shell will add the node_modules/.bin subdirectory of the current directory to the PATH variable. After the execution, the PATH variable will be restored as it is.

This means that all scripts in the node_modules/.bin subdirectory of the current directory can be called directly with the script name without adding the path. For example, mocha is included in the current project's dependency. Just write mocha test directly.

"test": "mocha test"

Instead of writing it like this.

"test": "./node_modules/.bin/mocha test"

Because the only requirement of npm script is that it can be executed in Shell, it is not necessarily a Node script, and any executable file can be written in it.

The exit code of npm script also complies with Shell script rules. If the exit code is not 0, npm will consider that the execution of this script fails.

Server script configuration

webhook.js

First, install node and pm2 on the server. Manage webhook.js service with pm2
Write webhook.js service to make corresponding post request of github
webhook.js

let http = require('http');
var spawn = require('child_process').spawn;
let sendMail = require('./sendMail.js');
let server = http.createServer(function(req,res){
    console.log(req.method,req.url);
    if(req.url == '/webhook' && req.method =='POST'){
        let buffers = [];
        req.on('data',function(data){
            buffers.push(data);
        });
        req.on('end',function(){
            //Get the payload of the webhook request, as well
            let payload = JSON.parse(Buffer.concat(buffers));
            console.log(payload.pusher,payload.head_commit)
            let event = req.headers['x-github-event'];
                        console.log(payload.repository)
            res.setHeader('Content-Type','application/json');
            res.end(JSON.stringify({"ok":true}));
            if(event === 'push'){
                //Execute the corresponding shell
                let child = spawn('sh', [`${payload.repository.name}`]);
                let buffers = [];
                child.stdout.on('data', function (buffer) { buffers.push(buffer)});
                child.stdout.on('end', function () {
                    //Get subprocess log information
                    let logs = Buffer.concat(buffers).toString();
                    //Send emails
                    sendMail(`
            <h1>Deployment date: ${new Date()}</h1>
            <h2>Deployer: ${payload.pusher.name}</h2>
            <h2>Deploy mailbox: ${payload.pusher.email}</h2>
            <h2>Submission of information: ${payload.head_commit.message}</h2>
            <h2>Deployment log:<br/> ${logs.replace(/\\n/,'<br/>')}</h2>
        
        `);
                });
            }
        });
    }else{
        res.end('Now Found!!!!');
    }
});
server.listen(4000,()=>{
    console.log('Service starting on port 4000!');
});

sendmail.js

const nodemailer = require('nodemailer');
let transporter = nodemailer.createTransport({
    // host: 'smtp.ethereal.email',
    service: 'qq', // Use built-in transport to send email to view support list: https://nodemailer.com/smtp/well-known/
    port: 465, // SMTP port
    secureConnection: true, // SSL used
    auth: {
        user: '250351xxxx@qq.com',
        // The password here is not the qq password, but the smtp authorization code you set
        pass: 'Your authorization code',
    }
});


function sendMail(message){
    let mailOptions = {
        from: '"250351xxxx" <250351xxxx@qq.com>', // Sending address
        to: '250351xxxx@qq.com', // Recipient
        subject: 'Deployment notification', // theme
        html:message // Content subject
    };
    // send mail with defined transport object
    transporter.sendMail(mailOptions, (error, info) => {
        if (error) {
            return console.log(error);
        }
        console.log('Message sent: %s', info.messageId);
    });
}
module.exports = sendMail;

helloworld.sh

Write the helloworld.sh script. Note that the name is not randomly chosen. It's the name of your github warehouse, because I execute the script in webhook.js

 let child = spawn('sh', [`${payload.repository.name}`]); //Although I touch helloworld.sh, it seems that there is no extension when ls is executed, so there is no write when ls is executed

It's written in helloworld.sh

#!/bin/sh
echo 'Start execution webhook hook'
unset GIT_DIR 
DIR_ONE=/home/user/www/  #This directory is the server page display directory 
cd $DIR_ONE
echo 'Eliminate git cache'
git clean -df
echo 'Pull remote code'
git pull origin master
echo 'Deployment completed'

At this time, there will be www folder, hellowrold executable file, webhook.js service file under / home/user

Practical operation

  1. Add remote github library helloworld locally
  2. Remote server / home/user/www / add remote github library helloworld
  3. Script each part
  4. pm2 starts webhook.js
  5. Local npm run dp completes the first upload
  6. Open the browser, at this time, the page can be normally displayed as the first content
  7. Change the content of components, and re npm run dp
  8. Open the browser, at this time, the page can be displayed as the second content normally, and the deployment is successful

Matters needing attention

1. As for the problem of server permissions, I suggest that it is better for individuals to have their own servers, root permissions, and adjust as you like. If you use the company's server, there may be problems with cross directory access and ssh configuration.
Tencent cloud is highly recommended here. Recently, it has been doing activities for 88 years. It's safe and patient
0.1 discount server link . If you buy something that you can't play, you can chat with me in private. Three accompany policy, including teaching and meeting...

2. How to match SSH

First log in to the remote server, input ssh keygen on the command line, and generate ssh public key and private key

Second, check whether there is a ~ /. ssh directory locally. If not, perform the above operations

Then scp ~/.ssh/id_rsa.pub [remote host name]: ~ /. ssh/authorized_keys

Add a config file to the local ~ /. ssh, which says

Host           qq
HostName      Your qq The server ip
Port          22
User              root
IdentityFile    ~/.ssh/id_rsa

When you enter ssh qq in the console, the qq server will automatically appear

  1. ssh connection between local project and github

~/. ssh/id_rsa.pub put it in github public key

summary

This paper introduces the hook of webhook and an example of using it to deploy simply and automatically. It also explains the problems that may be encountered. I hope I can bring you some help.

Recently, my boss asked me to research and combine this set of deployment and eslint with Jenkins to form a fixed process. It's a big pressure mountain. Let's talk about it when we find out

As an aside, it's really hard to write an article. After so long writing, there is no reward. Is there any elder brother who can give me a reward, let me open meat, support me

Posted by tim_perrett on Mon, 18 Nov 2019 02:26:08 -0800