gitlab之前一直是在项目根目录做一个脚本然后ssh连到服务器手动运行脚本
跟输入命令没啥差别...
之前公司搞了gitlab的自动部署
大致流程是:
开发们都使用dev分支,每次提交到dev分支时就触发一个webhook
webhook其实就往指定的url发送一个请求
服务器写一个php文件接收请求并在php中通过exec()执行脚本
当然 以上都是在测试服务器上进行的
然后每当合并到master分支时 也会触发一个webhook 这个是请求到生产环境拉代码的php文件的
合并分支是由组长等管理者确认测试没问题后进行

回到正题

gitlab设置

TIM截图20180627140407.png
在gitlab项目页面左下角点击设置->Intergrations

微信截图_20180629163532.png
填写好url,token和确保push event勾选上就点击Add webhook即可
需要注意:
1.请求url最好换一个端口;
2.后面可以带get参数,方面日后判断事件和要更新的项目;
3.这里的token在webhook请求的时候,服务端可以通过$_SERVER['HTTP_X_GITLAB_TOKEN']获取。

服务器部署

目前我在测试服务器里某目录里有index.php与laravel_pull.sh,tp5_pull.sh
然后nginx已经把相应域名指向该目录

index.php:

//请求过来的token
$gitlab_token = isset($_SERVER['HTTP_X_GITLAB_TOKEN'])?$_SERVER['HTTP_X_GITLAB_TOKEN']:null;
//自己做验证的token
$my_token = 'my_token';
//因为可能有多个项目 所以判断下是哪个
$project = isset($_GET['project'])?$_GET['project']:null;
//也做一下ip限制
$ips = [
    '0.0.0.0',
    '0.0.0.0',
    '0.0.0.0',
];
//如果有问题就报错
if(!$gitlab_token || $gitlab_token != $my_token || !$project || !in_array($_SERVER['REMOTE_ADDR'],$ips))
{
    echo "ERR";
    exit();
}

echo '<pre>';
//匹配下是哪个项目 之后还可能加上$event 如把comment放在某些地方展示作为更新日志,
switch($project)
{
    case 'laravel':
        exec('sudo ./laravel_pull.sh',$str);
        //这里可以用日志记录的形式
        print_r($str);
        exit();
        break;

    case 'tp5':
        exec('sudo ./tp5_pull.sh',$str);
        //这里可以用日志记录的形式
        print_r($str);
        exit();

        break;

    //报错
    default:
        echo "ERR2";
}

laravel_pull.sh和tp5_pull.sh

#!/bin/env bash
cd /你的项目目录
git checkout .
git checkout dev
git pull

运行&遇到的问题

此时我通过git提交到dev,测试环境应该也会相应拉取代码,但是发现并没有效果。
到刚新建的目录尝试直接运行index.php

php index.php

输出结果

[root@ cmd]# php index.php 
Already on 'dev'
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 8 (delta 4), reused 0 (delta 0)
Unpacking objects: 100% (8/8), done.
From gitlab.****.com:root/course
   6cedc94..47d6e15  master     -> origin/dev
<pre>array(4) {
  [0]=>
  string(25) "Updating 6cedc94..47d6e15"
  [1]=>
  string(12) "Fast-forward"
  [2]=>
  string(63) " **/**/**/**/HomeController.php | 2 +-"
  [3]=>
  string(46) " 1 file changed, 1 insertion(+), 1 deletion(-)"
}

然后直接通过浏览器访问webhook的url输出是一个空数组
结论:php文件在cli下是可以正常运行的
百度了一番是权限问题
参考资料https://stackoverflow.com/questions/3173201/sudo-in-php-exec

建议先看下当前web是用哪个用户,更改index.php并直接访问webhook url:

<?php 
  exec('whoami',$str);
  print_f($str);

很神奇的发现尽管我没装apache,但现在用的用户是apache
这个问题之后再处理 先实现功能
知道用户后需要修改/etc/sudoers
让其 run script from root level without root privileges
在最后加上一行代码:

用户名 ALL = NOPASSWD: 脚本路径

举个例子

apache  ALL = NOPASSWD: /var/www/cmd/laravel_pull.sh
apache  ALL = NOPASSWD: /var/www/cmd/tp5_pull.sh

如果你vim或vi这个/etc/sudoers会发现是readonly的
然后千万别做傻事,用visudo命令打开即可

visudo

啥都不同加 直接visudo就会直接打开/etc/sudoers文件进行编辑了
在最后加上代码后:wq即可

再运行

再往dev分支提交并推送一个更新,测试环境马上更新了,大功告成!

标签: gitlab, webhook

添加新评论