GitHook+JGit实现最新代码的自动克隆或者项目的自动部署

来源:互联网 发布:劳丽诗的淘宝店咋样 编辑:程序博客网 时间:2024/05/22 05:03

    • 需求
    • 思路
    • 开工
      • 设置webhook
      • 响应webhook的服务器
        • http接口
        • clone和checkout操作
        • 遍历本地仓库
        • IO流读取内容
      • 运行结果

需求

分析师写的sql需要映射到另外一个后台系统报表中,由于要经常进行sql优化,需要经常修改sql,而有时候由于马虎sql也会写错,而此刻以前的sql也忘记了,难以维护,所以决定把sql托管在gitlab上。
需求就是保证后台系统的报表sql是分析师每次push后的最新sql。
通过这种方式也可以实现项目的自动部署,pull最新项目后重启tomcat或者其它服务器就好了。。。

思路

思路一:起初想的是在正式环境中init 一个远程git仓库。每次分析师把sql push到正式环境中。可以使用git的hook功能在push之后做一些操作。测试都成功了,此时发现一个令人伤心的事情就是正式环境中无权限操作。。只能部署项目。唉,只能想别的办法。思路二:在gitlab有一个webhook,相信你看到hook就知道了,钩子,也就是回调函数。通过webhook我们可以在push,merge等操作后可以发送一个http请求,这时候可以通过我们实现的http接口来做我们想做的事情,比如这个需求中。克隆分析师上传的代码。具体实现可以使用JGit,当然也可以编写shell脚本,使用java来调用。在这里我选择的是前者。

开工

设置webhook

具体设置位置如下:
URL:回调的接口。
Trigger:触发器。根据需要勾选下面的事件。
SSL验证是否开启。
这里写图片描述
然后点击Add WebHook即可。
这时候可以点击TestHook测试一下http接口
这里写图片描述

响应webhook的服务器

由于需要相应gitlab发出的http请求。所以我们要提供一个http接口,在这里我使用java实现的。当然可以用php等其它语言实现。
我们需要在服务器上初始化一个git本地仓库,克隆代码到本地仓库,然后对文件进行分析。
所以这里需要另外一个知识:JGit. 通过这个工具我们可以使用java语言操作git,如果想更深入的了解,请自行google哦。在这里我只使用到了clone,checkout和pull。并没有使用add ,commit ,push等操作。

http接口

    @RequestMapping("/toClone")    @ResponseBody    public void setTitle() {        File gitFile = new File("D://temp");        if (cloneRepository(gitFile)) {            System.out.println("clone success");            checkFiles(gitFile);        } else {            System.out.println("clone failure");        }    }

clone和checkout操作

首先判断本地仓库是否已经存在 ,若不存在则clone远程仓库。 若已经存在则拉取相应分支上的代码。

 Git git = null;            if (new File(gitFile.getAbsolutePath() + "/.git").exists()) {                git = Git.open(gitFile);                //检测dev分支是否已经存在 若不存在则新建分支                List<Ref> localBranch = git.branchList().call();                boolean isCreate = true;                for (Ref branch : localBranch) {                    if (branch.getName().endsWith("dev")) {                        isCreate = false;                        break;                    }                }                git.checkout().setCreateBranch(isCreate).setName("dev").setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK).call();                git.pull().call();            } else {                List<String> remoteBranch = new ArrayList<>();                remoteBranch.add("master");                git = Git.cloneRepository().setURI(StaticPro.gitURI).setBranchesToClone(remoteBranch).setDirectory(gitFile).call();                git.checkout().setCreateBranch(true).setName("master").setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK).call();                git.pull().call();            }

遍历本地仓库

然后就是递归遍历本地仓库了

private void checkFiles(File file) {        File files[] = file.listFiles();        if (files != null && files.length > 0) {            for (File file1 : files) {                String fileName = file1.getName();                if (file1.isDirectory() && fileName.endsWith(".git")) continue;                System.out.println(fileName);                System.out.println("内容是:\n" + readFile(file1));                System.out.println("------------------------------------");                checkFiles(file1);            }        }    }

IO流读取内容

private String readFile(File file) {        BufferedReader br = null;        StringBuilder sb = new StringBuilder();        String line = null;        try {            br = new BufferedReader(new FileReader(file));            while ((line = br.readLine()) != null) {                sb.append(line).append("\n");            }            return sb.toString();        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        } finally {            if (br != null) {                try {                    br.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }        return "";    }

运行结果

图片太小的话可以新标签打开图片。
这里写图片描述