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
- Add remote github library helloworld locally
- Remote server / home/user/www / add remote github library helloworld
- Script each part
- pm2 starts webhook.js
- Local npm run dp completes the first upload
- Open the browser, at this time, the page can be normally displayed as the first content
- Change the content of components, and re npm run dp
- 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
- 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