git webhooks 实现自动拉取代码

一. 关于 git 钩子

Git 能在特定的重要动作发生时触发自定义脚本。 有两组这样的钩子:客户端的和服务器端的。 客户端钩子由诸如提交和合并这样的操作所调用,而服务器端钩子作用于诸如接收被推送的提交这样的联网操作。 你可以随心所欲地运用这些钩子。

  • 如何使用钩子

钩子都被存储在 Git 目录下的 hooks 子目录中。 也即绝大部分项目中的 .git/hooks 。 当你用 git init 初始化一个新版本库时,Git 默认会在这个目录中放置一些示例脚本。这些脚本除了本身可以被调用外,它们还透露了被触发时所传入的参数。 所有的示例都是 shell 脚本,其中一些还混杂了 Perl 代码,不过,任何正确命名的可执行脚本都可以正常使用 —— 你可以用 Ruby 或 Python,或其它语言编写它们。 这些示例的名字都是以 .sample 结尾,如果你想启用它们,得先移除这个后缀。

把一个正确命名且可执行的文件放入 Git 目录下的 hooks 子目录中,即可激活该钩子脚本。 这样一来,它就能被 Git 调用。 接下来,我们会讲解常用的钩子脚本类型。

具体使用可以参考官方文档:Git Hookes

  • 了解 webhooks

钩子功能(callback),是帮助用户 push 了代码后,自动回调一个你设定的 http 地址。 这是一个通用的解决方案,用户可以自己根据不同的需求,来编写自己的脚本程序(比如发邮件,自动部署等);目前,webhooks 支持多种触发方式,支持复选。

webhooks 的请求方式为POST请求,有两种数据格式可以选择,JSON 和 web 的 form参数,可以自行选择是否使用密码来确定请求。(注意:该密码是明文)

不同托管平台的POST数据格式都不太一样,不过也不会有太大影响,只是解析数据的时候注意就行了,下面是码云的 Push 操作回调的 json 数据:

{
    "before": "fb32ef5812dc132ece716a05c50c7531c6dc1b4d", 
    "after": "ac63b9ba95191a1bf79d60bc262851a66c12cda1", 
    "ref": "refs/heads/master", 
    "user_id": 13,
    "user_name": "123", 
    "user": {
      "name": "123",
      "username": "test123",
      "url": "https://gitee.com/oschina"
    }, 
    "repository": {
        "name": "webhook", 
        "url": "http://git.oschina.net/oschina/webhook", 
        "description": "", 
        "homepage": "https://gitee.com/oschina/webhook"
    }, 
    "commits": [
        {
            "id": "ac63b9ba95191a1bf79d60bc262851a66c12cda1", 
            "message": "1234 bug fix", 
            "timestamp": "2016-12-09T17:28:02 08:00", 
            "url": "https://gitee.com/oschina/webhook/commit/ac63b9ba95191a1bf79d60bc262851a66c12cda1", 
            "author": {
                "name": "123", 
                "email": "[email protected]", 
                "time": "2016-12-09T17:28:02 08:00"
            }
        }
    ], 
    "total_commits_count": 1, 
    "commits_more_than_ten": false, 
    "project": {
        "name": "webhook", 
        "path": "webhook", 
        "url": "https://gitee.com/oschina/webhook", 
        "git_ssh_url": "[email protected]:oschina/webhook.git", 
        "git_http_url": "https://gitee.com/oschina/webhook.git", 
        "git_svn_url": "svn://gitee.com/oschina/webhook", 
        "namespace": "oschina", 
        "name_with_namespace": "oschina/webhook", 
        "path_with_namespace": "oschina/webhook", 
        "default_branch": "master"
    }, 
    "hook_name": "push_hooks", 
    "password": "pwd"
}
以上参考:https://segmentfault.com/a/1190000012643992

二. 服务器环境

  1. centos 7
  2. jdk 1.8
  3. maven 3+
  4. git
  5. nodejs

三.部署

  • 1.安装git

    yum -y install git
  • 2.安装maven

    maven的景象仓库
    http://mirror.bit.edu.cn/apache/maven/maven-3/3.2.5/binaries/
  1. wget http://mirror.bit.edu.cn/apache/maven/maven-3/3.2.5/binaries/apache-maven-3.2.5-bin.tar.gz
  2. tar -zxvf apache-maven-3.2.5-bin.tar.gz
  3. mv apache-maven-3.2.5 /usr/local/maven3
  4. vim /etc/profile
# JAVA
export JAVA_HOME=/usr/jdk/jdk1.8.0_192
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export  PATH=${JAVA_HOME}/bin:$PATH

#maven
export M2_HOME=/usr/local/maven3
export PATH=$PATH:$JAVA_HOME/bin:$M2_HOME/bin
  1. source /etc/profile
  • 3.配置git ssh拉取代码

  • 生成公钥

    此示例是单机部署,所以不需要生成ssh免密登录公钥

  • 用户公钥(用于git clone时认证权限)

ssh-keygen -t rsa -C "[email protected]" # 填自己的邮箱

git webhooks 实现自动拉取代码_第1张图片 默认保存在 /root/.ssh/id_rsa,可以自己修改位置,此处默认

  • git部署公钥

  1. 获取公钥内容
cat /root/.ssh/id_rsa.pub # 查看生成的密钥内容,复制全部
  1. gitee仓库中添加ssh公钥

将公钥的内容粘贴到用户->设置 中的SSH公钥中
git webhooks 实现自动拉取代码_第2张图片

  • git全局设置

 git config --global credential.helper store # 永久保存
 git config --global user.name "name" 
 git config --global user.email "[email protected]" # 邮箱请与码云上一致
  • 拉取代码

    git clone [email protected]:test/test-pull.git #这个是你仓库的ssh地址
    

    如果报错:
    /etc/ssh/ssh_config: line 53: Bad configuration option: permitrootlogin
    /etc/ssh/ssh_config: terminating, 1 bad configuration options
    修改方法为:

    vim /etc/ssh/ssh_config 
    注释掉 permitrootlogin 
    

    配置完成之后可以 clone 或 pull 项目来验证是否配置成功,若多次操作只需输入一次用户名、密码,即配置成功,若每一次操作都有输入用户名密码,则配置不成功,需要重新检查配置。

  • 4、安装nodejs

  • 下载nodejs最新的bin包

wget https://nodejs.org/dist/v10.16.3/node-v10.16.3-linux-x64.tar.xz
  • 解压安装

xz -d node-v10.16.3-linux-x64.tar.xz
tar -xf node-v10.16.3-linux-x64.tar
mv node-v10.16.3-linux-x64 /usr/local/node
  • 配置bin

ln -s /usr/local/node/bin/node /usr/bin/node
ln -s /usr/local/node/bin/npm /usr/bin/npm
  • 验证

node -v
npm

分别输出版本号,标识成功

  • 5.编写自动部署脚本

  • java自动编译、部署脚本

#/bin/bash
#服务路径
SH_PATH='/usr/soft/sh_root'
SOURCE_PATH='/usr/soft/back/game_web'
DEPLOY_PATH='/usr/soft/jar'
JAR_NAME='web-admin.jar'

#单实例逻辑
if [ -f /var/run/${BASH_SOURCE[0]}.pid ];then
    echo "pid文件存在。。需要判断是不是当前正在运行的文件"
	ps -ef|grep -v grep|grep ${BASH_SOURCE[0]}|grep `cat /var/run/${BASH_SOURCE[0]}.pid` >> /dev/null
	if [ $? -eq 0 ];then
		exit 1
	fi
fi
echo "写入临时文件"
echo $$ > /var/run/${BASH_SOURCE[0]}.pid


#停止原本服务
PID=$(jps |grep -v  Jps| awk '{ print $1 }')
echo "原始运行的服务id是:$PID"
if [ -n "$PID" ]
then
  echo "原来服务存在,需要kill"
  kill -9 $PID;
fi

cd $DEPLOY_PATH
rm -rf *
echo "删除原部署目录文件。。。"
#拉取最新代码部署
cd $SOURCE_PATH
git reset --hard origin/master
git clean -f
git pull
git checkout master
echo "拉取代码完成。。。。。"
#也可以 
#rm -rf *
#git clone [email protected]:srxxfd/game_web.git
mvn clean -U install -P prod -Dmaven.test.skip=true
echo "编译完成。。。。"
if [ $? -ne 0 ]
then
  echo "构建失败,请查看代码问题!"
  exit 1;
fi

mv target/web-admin-1.0.0.jar $DEPLOY_PATH/$JAR_NAME
cd $DEPLOY_PATH
echo "进入到部署目录。。。"
#如果不行 就使用 setsid
#nohup java -jar $JAR_NAME &
source $SH_PATH/start_jar.sh "$DEPLOY_PATH" "$JAR_NAME"
echo "编译完成。。。。"
if [ $? -ne 0 ]
then
  echo "启动失败。。。"
  exit 1;
fi
echo "启动完成。。。。"
rm -f /var/run/${BASH_SOURCE[0]}.pid
exit 0;

start_jar.sh

   #!/bin/bash
  #获取参数
  DEPLOY_PATH=$1
  JAR_FILE_NAME=$2
  echo "DEPLOY_PATH 是:$DEPLOY_PATH"
  echo "JAR_FILE_NAME 是:$JAR_FILE_NAME"
  cd $DEPLOY_PATH
  echo "进去到jar目录"
  nohup java -jar $JAR_FILE_NAME > nohup.log 2>&1 &
 exit 0

在执行上面shell脚本之前我们必须第一次手动git clone项目进去

  • 6.监听web-hooks服务

  • 引用 gitee-webhook-handler

mkdir /usr/soft/web_hooks #创建目录
cd /usr/soft/web_hooks
npm init 
npm install  gitee-webhook-handler --save 
  • 创建js

vim webhook.js


var http = require('http')
var createHandler = require('gitee-webhook-handler')
var handler = createHandler({ path: '/webhooks_push', secret: '654321'}) //post 所需要用到的秘钥
function run_cmd(cmd, args, callback) {
  var spawn = require('child_process').spawn;
  var child = spawn(cmd, args);
  var resp = "";
  child.stdout.on('data', function(buffer) { resp += buffer.toString(); });
  child.stdout.on('end', function() { callback (resp) });
}
handler.on('error', function (err) {
  console.error('Error:', err.message)
})
handler.on('Push Hook', function (event) {
 // 这个地方就是GitHub 和 Gitee 不一样的地方,需要注意
  console.log('Received a push event for %s to %s',
    event.payload.repository.name,
    event.payload.ref);
    run_cmd('sh', ['/usr/soft/sh_root/deploy.sh'], function(text){ console.log(text) });// 需要执行的脚本位置
})
try {
  http.createServer(function (req, res) {
    handler(req, res, function (err) {
      res.statusCode = 404
      res.end('no such location')
    })
  }).listen(6666) // 服务监听的端口,可以自行修改
}catch(err){
  console.error('Error:', err.message)
}

  • 启动服务

npm install -g forever #解决node服务自动停掉
ln -s /usr/local/node/lib/node_modules/forever/bin/forever /usr/bin/forever 
forever start -l forever.log -o out.log -e err.log webhook.js
forever start -a  -l /usr/soft/web_hooks/forever.log -o /usr/soft/web_hooks/forever_out.log -e /usr/soft/web_hooks/forever_err.log webhook.js
  • gitee配置

git webhooks 实现自动拉取代码_第3张图片

  • nginx反向代理

location ^~ /webhooks_push {
            proxy_set_header Host $host;
            proxy_set_header X-Real-Ip $remote_addr;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_pass http://127.0.0.1:6666;
        }

保存后,如果服务启动没有问题,会返回 {“ok”:true}

至此配置完成,push完代码之后,可以看到调用到了服务器上

参考内容

  1. https://aotu.io/notes/2016/01/07/auto-deploy-website-by-webhooks-of-github/index.html
  2. https://segmentfault.com/a/1190000003908244

你可能感兴趣的:(java相关)