商汇粹外网资源平台

搜索
查看: 1854|回复: 3

如何使用GitLab持续同步GitHub的仓库?

[复制链接]

该用户从未签到

4

主题

4

帖子

38

积分

新手上路

Rank: 1

积分
38
发表于 2022-10-22 09:51:10 | 显示全部楼层 |阅读模式
想用GitLab社区版自己搭一个服务器,然后平时代码还是push到GitHub上的仓库,想让GitLab实现自动备份仓库。GitLab现有的导入仓库的功能只能一次导入仓库,无法实现修改追踪与会持续同步的功能。
回复

使用道具 举报

该用户从未签到

4

主题

13

帖子

49

积分

新手上路

Rank: 1

积分
49
发表于 2022-10-22 10:21:43 | 显示全部楼层
如楼上所说,但是注意,free版本不行,要starter以上才行
回复

使用道具 举报

该用户从未签到

4

主题

31

帖子

93

积分

注册会员

Rank: 2

积分
93
发表于 2022-10-22 10:52:16 | 显示全部楼层
本文以Gitee作为演示,Github实现步骤是一样的,区别在于二者WebHook推送的数据有所区别。
WebHook

1.WebHook是什么

WebHook 功能是帮助用户 push 代码后,自动回调一个您设定的 http 地址。 这是一个通用的解决方案,用户可以自己根据不同的需求,来编写自己的相关程序。
实现过程

1.处理过程


  • 远程仓库接收到Push推送,触发WebHook向接口推送更新的消息;
  • 服务器接口接收到推送的更新消息,提取仓库地址、分支名、仓库名(仓库名用于同步多个仓库时进行区分);
  • 接口将提取的更新信息,投递到后台的异步任务。
  • 异步任务自动执行Git命令,同步指定仓库的代码到对应的目录。
2.功能组成

服务器后台运行一个PHP cli 脚本,脚本运行时启动一个SSH客户端,然后再运行一个Redis客户端,Redis保持订阅,接收来自接口的Redis消息发布。
每当Redis接收到发布的推送消息,触发回调,通过SSH客户端执行Git命令。
PHP SSH 客户端:https://nicen.cn/2430.html
实际代码

1.HTTP接口

HTTP接口接收来自远程仓库的更新推送,然后把数据进行处理后推送给异步任务。
<?php/* 获取推送的数据 */$json = file_get_contents("php://input");$data = json_decode($json, true);/* 判断推送是否来自指定的用户 */if ($data['user_name'] != "friend-nicen") {    exit("非法请求");}/* 处理数据 */$need = [    "clone" => $data['repository']["clone_url"], //远程仓库地址    "path" => $data['repository']["path"], //远程仓库名    "branch" => str_replace("refs/heads/", '', $data['ref'])  //分支];/*通过Redis订阅,进行任务投递*/getRedis()->publish("RECV_GIT", json_encode($need));exit("正在处理本次更新...");
2.PHP Cli脚本

使用前请先按照https://nicen.cn/2430.html,安装PHP拓展,您需要准备:

  • Redis的IP和端口
  • SSH账号和密码
  • 存放所有仓库的根目录
<?phpinclude_once 'vendor/autoload.php';/* 引入SSH客户端 */use phpseclib3\Net\SSH2;/* * 创建redis * */function getRedis():Redis{    $redis = new Redis();    $redis->connect("IP","端口");    $redis->setOption(3, -1);    return $redis;}/*链接ssh*/$ssh = new SSH2('localhost', 22);/*如果登录失败*/if (!$ssh->login('root', '您的SSH密码')) {    return;}/* * SSH读取消息 * */$read = function () use ($ssh) {    /*拼接*/    $raw = "";    /*读取空白次数*/    $blank = 0;    /*     * 循环读取     * */    while (true) {        $msg = $ssh->read('username@username:~$');        if (!empty($msg)) {            $raw .= $msg;        } else {            /*             * 空白10次,终止,返回             * */            if ($blank > 10) {                break;            } else {                $blank++;            }        }    }    return $raw;};/*读取间隔时间*/$ssh->setTimeout(0.1);$redis = getRedis(); //创建redis/* * 打开存放仓库的目录 * */$root = "/home/repos/"; //存放仓库的目录$ssh->write("cd " . $root . "\n");echo $read(); //读取初始化的消息/* * Redis订阅等待消息 * */$redis->subscribe(["RECV_GIT"], function ($redis, $chan, $msg) use ($ssh, $read, $root) {    echo "收到消息:" . $msg . "\n"; //收到消息    /*     * 判断消息内容是否包含分支信息     * */    if (strpos($msg, "branch") === false) return;    try {        $data = json_decode($msg, true); //处理结果        /*         * 判断仓库是否存在         * */        $path = $root . $data['path']; //本地仓库路径        /*         * 仓库目录是否存在         * */        if (!file_exists($path)) {            /*创建*/            mkdir($path);            /*打开仓库目录*/            $ssh->write("cd " . $path . "\n");            /*初始化仓库*/            $ssh->write("git init\n");            echo $read(); //读取后续的消息            /*添加远程仓库*/            $ssh->write("git remote add origin " . $data['clone'] . "\n");            echo $read(); //读取后续的消息        } else {            /*打开仓库目录*/            $ssh->write("cd " . $path . "\n");        }        /*拉取分支*/        $ssh->write("git pull origin " . $data['branch'] . ":" . $data['branch'] . " \n");        echo $read(); //读取后续的消息    } catch (\Throwable $e) {        echo $e->getMessage() . "\n";    }});
3.运行脚本

打开上方Cli脚本所在目录,运行如下命令:
# 前台运行 php 文件名.php    # 后台台运行nohup php 文件名.php  &
每次脚本运行的日志,会自动写入到当前目录的nohup.out文件,作为日志方便观察同步结果 ;
运行之后,每次仓库有更新,脚本都会自动同步这一次的更新;本文只是简单的实现,您完全可以通过这个案例实现更复杂的功能。
回复

使用道具 举报

该用户从未签到

0

主题

6

帖子

26

积分

新手上路

Rank: 1

积分
26
发表于 2022-10-22 11:22:49 | 显示全部楼层
参考 GitLab 文档,Pulling from a remote repository
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表