社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Git

Gitee Webhook 实现自动拉取代码并编译代码

hejingtao • 7 年前 • 449 次点击  

Gitee Webhook 实现自动拉取代码并编译代码

一、Webhook 介绍与作用简介

Webhook,顾名思义就是钩子,简而言之,可以在特定情况下触发特定的操作。例如在远程git仓库中进行了push、tag等操作时,自动在远程server端自动拉取、编译代码。 以下是一个push代码到远程仓库后,自动拉取代码进行编译后,将生成的Webassembly相关的文件(.js,.wasm)和版本号push到远程仓库中的demo。

二、demo实现

1. 仓库设置(以gitee为例)

首先,需要拥有项目的管理者权限,点击项目首页上方的管理,然后点击左侧菜单下方的WebHooks,进入到以下截图的设置页面。

WebHooks设置界面
]

在上面的的界面中,我已经添加了一个Webhook,触发类型为push,同时还有一个密码。 当你push代码到远程仓库时,会往这里设置的URL发送一个携带着设置好密码的POST请求。当然你也可以勾选其他的操作类型。

Webhook添加界面.png

2. PHP代码实现

  • hooks.php
 <?php

// 本地仓库路径
$local = '/data/wwwroot/default/hooks/laserbox';

// 安全验证字符串,为空则不验证
$token = '123456';

//  payload为字符串,需要经过解析
$payload = file_get_contents('php://input');
if (!$payload) {
    header('HTTP/1.1 400 Bad Request');
    die('HTTP HEADER or POST is missing.');
}
$content = json_decode($payload, true);

// 如果启用验证,并且验证失败,返回错误
if ($token && $content['password'] != $token) {
    header('HTTP/1.1 403 Permission Denied');
    die('Permission denied.');
}

//最后会执行一个脚本编译代码,然后再push代码到远程
//所以会重复触发WebHooks,因此此处判断是否是本地的推送
if($content['commits'][0]['author']['name'] == 'handsomeTaoTao'){
        header('HTTP/1.1 403 Permission Denied');
        die('self push.');
}

/*
 * 这里有几点需要注意:
 *
 * 1.确保PHP正常执行系统命令。写一个PHP文件,内容:
 * `<?php echo shell_exec('ls -la')`
 * 在通过浏览器访问这个文件,能够输出目录结构说明PHP可以运行系统命令。
 *
 * 2、PHP一般使用www-data或者nginx用户运行,PHP通过脚本执行系统命令也是用这个用户,
 * 在通过浏览器访问这个文件,能够输出目录结构说明PHP可以运行系统命令。
 *
 * 2、PHP一般使用www-data或者nginx用户运行,PHP通过脚本执行系统命令也是用这个用户,
 * 所以必须确保在该用户家目录(一般是/home/www-data或/home/nginx)下有.ssh目录和
 * 一些授权文件,以及git配置文件,如下:
 * ```
 * + .ssh
 *   - authorized_keys
 *   - config
 *   - id_rsa
 *   - id_rsa.pub
 *   - known_hosts
 * - .gitconfig
 * ```
 *
 * 3.在执行的命令后面加上2>&1可以输出详细信息,确定错误位置
 *
 * 4.git目录权限问题。比如:
 * `fatal: Unable to create '/data/www/html/awaimai/.git/index.lock': Permission denied`
 * 那就是PHP用户没有写权限,需要给目录授予权限:
 * ``
 * sudo chown -R :www-data /data/www/html/awaimai`
 * sudo chmod -R g+w /data/www/html/awaimai
 * ```
 *
 * 5.SSH认证问题。如果是通过SSH认证,有可能提示错误:
 * `Could not create directory '/.ssh'.`
 * 或者
 * `Host key verification failed.`
 *
 */

// shell_exec函数默认是禁止的,无法使用的话需要进php.ini修改相关配置
//执行shell时,没有sudo仿佛会执行不成功,只执行一小段,加了sudo之后执行成功,可以为运行php的用户添加sudo权限,参考资料有相关问题
echo shell_exec("cd {$local} && sudo  sh ./autoCompiled.sh");
die("done " . date('Y-m-d H:i:s', time()));

  • autoCompiled.sh
#!/bin/sh
source /data/git/emsdk/emsdk_env.sh  // 载入命令,否则在命令行中无法使用emcc等编译用的命令
cd  /data/git/Webassembly-Lib/Demo/  // 进入到执行命令的目录中
git pull
rm -f src/version.h
git rev-list HEAD | sort > config.git-hash
LOCALVER=`wc -l config.git-hash | awk '{print $1}'`
if [ $LOCALVER \> 1 ] ; then
    VER=`git rev-list origin/master | sort | join config.git-hash - | wc -l | awk '{print $1}'`
    if [ $VER != $LOCALVER ] ; then
        VER="$VER+$(($LOCALVER-$VER))"
    fi
    if git status | grep -q "modified:" ; then


    

        VER="${VER}M"
    fi
    VER="$VER $(git rev-list HEAD -n 1 | cut -c 1-7)"
    GIT_VERSION=r$VER
else
    GIT_VERSION=
    VER="x"
fi
rm -f config.git-hash

cat version.h.template | sed "s/\$FULL_VERSION/$GIT_VERSION/g" > src/version.h


# 编译和提交代码
make
git add .
git commit -m 'Auto Compiled By handsomeTaoTao' 
git push

三、结束语

目前这个demo还只是实现了比较简单的功能,可以进一步优化功能,例如在浏览器访问该地址时显示上一次编译是否成功的信息,失败的话则显示错误信息,这样子可以方便调试。


参考资料
stackoverflow: php-sudo-in-shell-exec
Gitee 配置文档
Github、GitLab、Gitee使用Webhooks实现代码自动部署


今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/eI9lK9QFsr
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/12444