Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

svn 和 git webhook的使用 #70

Open
yangweijie opened this Issue Oct 8, 2018 · 2 comments

Comments

Projects
None yet
1 participant
@yangweijie
Copy link
Owner

commented Oct 8, 2018

最近由于想提高代码提交的效率不再git commit && git push 和 svn commit 后每次要去服务器更新代码。
就参考了 分享下使用svn或者git时,测试服务器代码自动更新、线上服务器代码手动更新的配置经验 孟康的文章。没有配置服务器上的文件

svn 用的svn bucket 免费的自带钩子

tim 20181008162318

这个工具比较好的是有钩子请求历史记录。

然后写了项目里的控制器代码:

<?php
namespace app\dev\home;

use think\Controller;

/**
 * Svn钩子
 * @package app\install\controller
 */
class Svn extends Controller
{

    protected function _initialize()
    {
        define('SVN_TOKEN', 'guihzip');
        header("Cache-Control:no-cache,must-revalidate");
    }

    public function commit()
    {
        header("Cache-Control:no-cache,must-revalidate");
        extract($_POST);
        if ($token == SVN_TOKEN) {
            switch ($event) {
                case 'test':
                    return 'ok';
                    break;
                case 'start-commit':
                    return 'ok';
                    break;
                default:
                    // ptrace($log);

                    if(stripos($log, '@commit') !== false){
                        $username   = 'XXXXX';
                        $password   = 'XXXXX';
                        $target_dir = realpath('..');
                        // ptrace($target_dir);
                        ini_set('disable_functions', '');
                        exec("sudo svn up --username {$username} --password {$password} --no-auth-cache {$target_dir} 2>&1", $output, $outresult);
                        ptrace(implode(PHP_EOL, $output).PHP_EOL.$outresult);
                        if ($outresult === 0) {
                            // echo '更新成功!';
                            //echo print_r($output);
                            return 'ok';
                        } else {
                            // echo '更新失败!';
                            // echo print_r($output);
                            return 'failed';
                        }
                    }else{
                        return 'no up';
                    }
                    break;
            }
        } else {
            return 'error token';
        }
    }
}

钩子运行时会报各种没权限,因为我的项目是root clone 出来的。于是查找各种办法,

php利用root权限执行shell脚本(二)

加入了www 用户组后 执行的svn 命令前面一定要带sudo 就可以了。

接下来是git 用的oschina 后来换名为了 gitee 。

在项目里 新增钩子,咱们只管push的钩子

image

对应的代码:

<?php
namespace app\dev\home;

use think\Controller;

/**
 * Git钩子
 * @package app\install\controller
 */
class Git extends Controller
{

    protected function _initialize()
    {
        define('GIT_TOKEN', 'guihzip');
        header("Cache-Control:no-cache,must-revalidate");
    }

    public function push()
    {
        header("Cache-Control:no-cache,must-revalidate");
        // ptrace($_POST);
        $rws_post = file_get_contents('php://input');
        $_POST = json_decode($rws_post, 1);

        // ptrace($_POST);
        extract($_POST);
        $header = $this->request->header();
        // ptrace($header);
        $token = $header['x-gitee-token'];
        $event = $header['x-gitee-event'];
        if ($token == GIT_TOKEN) {
            switch ($event) {
                case 'test':
                    return 'ok';
                    break;
                case 'start-commit':
                    return 'ok';
                    break;
                default:
                    // ptrace($log);
                	$log = $head_commit['message'];
                    if(stripos($log, '@push') !== false){
                        error_reporting ( E_ALL );
			$dir = realpath('..');//该目录为git检出目录
			exec("sudo cd {$dir} && git pull origin master 2>&1", $output, $outresult);
                        ptrace(implode(PHP_EOL, $output).PHP_EOL.$outresult);
                        if ($outresult === 0) {
                            // echo '更新成功!';
                            //echo print_r($output);
                            return 'ok';
                        } else {
                            // echo '更新失败!';
                            // echo print_r($output);
                            return 'failed';
                        }
                    }else{
                        return 'no up';
                    }
                    break;
            }
        } else {
            return 'error token';
        }
    }
}

git 遇到的问题:

1) 没有账号密码
2)git pull 说没有指定分支

第一个问题 通过 设置remote url 为带名称 密码的 地址就行 https://www.jianshu.com/p/8020de245f6a

第二个问题 通过 git branch --set-upstream 本地关联远程分支

孟康文章里的 output 不是一个字符串要自行转换。
gitee 里的post不是传统post 7.2 里 全局变量
$rws_post = $GLOBALS['HTTP_RAW_POST_DATA'];
$mypost = json_decode($rws_post,1);
方式 已经获取不到了 必须 file_get_contents('php://input'); 获取
x-gitee-token 在 gitee 的文章里 其实是大写的, 可能我的nginx环境不同,所以大家要自己调试一下获取header 看看。
ptrace 是自己封装的 钉钉告警函数,大家可以换成发邮件。

@yangweijie

This comment has been minimized.

Copy link
Owner Author

commented Oct 8, 2018

附两张 钉钉成功的信息图:
svn:
image

git:
image

@yangweijie

This comment has been minimized.

Copy link
Owner Author

commented Dec 10, 2018

数据库对比

// 对比测试和线上库
	public function diff_test_and_online_tp_hook($db1 = 'pizhi_bak', $db2 = 'paizhi', $dbName = 'paizhi')
	{
		ini_set('memory_limit', '1024M');
		$now_date = datetime();
		debug('begin');
		$db_conf1 = $this->dbs[$db1];
		$db_conf2 = $this->dbs[$db2];
		$tables1 = Db::connect($db_conf1)->getTables($db1);
		// return json($tables1);
		$tables2 = Db::connect($db_conf2)->getTables($db2);
		if (empty($tables1) && empty($tables2)) {
			return '两个数据库都为空 无需比较';
		}
		$add_tables = $sub_tables = $diff_tables = $same_tables = [];
		if (empty($tables1)) {
			$add_tables = $tables2;
		}
		elseif (empty($tables2)) {
			$sub_tables = $tables1;
		}
		else {
			foreach ($tables1 as $key => $table) {
				if (in_array($table, $tables2)) {
					$table1_fields = Db::connect($db_conf1)->getFields("{$db1}.{$table}");
					$table2_fields = Db::connect($db_conf2)->getFields("{$db2}.{$table}");
					if ($table1_fields == $table2_fields) {
						$same_tables[] = $table;
					}else {
						ptrace("{$db1}.{$table}");
						ptrace($table1_fields);
						ptrace("{$db2}.{$table}");
						ptrace($table2_fields);
						$diff_tables[] = $table;
					}
				}
				else {
					$sub_tables[] = $table;
				}
			}
			foreach ($tables2 as $key => $table2) {
				if(!in_array($table2, $tables1)){
					$add_tables[] = $table2;
				}
			}
		}
		$total = count($same_tables) + count($sub_tables) + count($add_tables) + count($diff_tables);
		debug('end_count_tables');
		$msg = $this->log_cost(sprintf("总共%d 个表,相同的%d个,删除的表%d个,新增的表%d个,不同的表%d个", $total, count($same_tables), count($sub_tables), count($add_tables), count($diff_tables)), 'begin', 'end_count_tables');
		$deleteTables = json_encode($sub_tables, JSON_UNESCAPED_UNICODE);
		$print = '';
		if($diff_tables){
			foreach ($diff_tables as $key => $df_table) {
				$print .= $this->diff_test_and_online("{$db1}.{$df_table}", "{$db2}.{$df_table}", 'sql', 'both').PHP_EOL;
				// $buff->notify2(sprintf("<div><pre>%s</pre></div>",$this->diff_test_and_online("{$dbName}.{$df_table}", "{$dbName}.{$df_table}")));
				// $buff->next();
			}
		}
		debug('end_show_diff');
		$end_msg = $this->log_cost("显示数据库差异结束", 'end_count_tables', 'end_show_diff');
		return json_encode(['print'=>$print, 'total'=>$total, 'same'=>count($same_tables), 'sub'=>count($sub_tables), 'add'=>count($add_tables), 'diff'=>$diff_tables]);
	}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.