使用Jenkins git submodule 实现自动化编译,解决代码安全性问题
扫描二维码
随时随地手机看文章
道哥的第 030 篇原创
一、一个真实的小故事
事情发生在功能机的时代,我们项目组开发一款手机,软件开发成员大概有 20 人左右吧。结果在手机发布的一周后,另一家小厂就推出了软件界面、功能几乎完全一样的手机,除了开机界面。
如果您需要文中提到的软件和代码资源,在文章末尾可以找到下载方式。
- Jenkins 的基本使用方法;
- git submodule 的基本指令用法;
- 通过三个 demo 项目,一步一步操作实现代码的安全管控;
- 利用 Jenkins git submodule 来实现自动化编译;
- git subtree 与 submodule 的区别;
二、Jenkins 的基本使用
1. Jenkins 是什么?
Jenkins是一个开源、由 Java 编写的持续集成工具,也就是说它帮助我们自动构建各类项目。Jenkins 运行在 Servlet 容器中(例如 Apache Tomcat),在 Ubuntu 系统中使用 apt-get 就可以一键安装。
其他的有点我就不吹了,我觉得很好用,如果有机会,你也可以试一下。另外,我测试用的虚拟机是新安装的 Ubuntu16.04-64,按照下面的流程操作,保证可以顺利运行。
- 嵌入在 Web 服务器中,通过浏览器来操作,非常方便;
- 可以执行基于Apache Ant和Apache Maven的项目,以及任意的Shell脚本和Windows批处理命令;
- 可以通过各种手段触发构建。例如提交给版本控制系统时被触发,通过类似Cron的机制调度,在其他的构建已经完成时,还可以通过一个特定的URL进行请求;
- Jenkins强大的插件式,使得Jenkins可以集成很多软件,可能帮助我们持续集成我们的工程项目;
- 给用户很大的权限和灵活性来自动发布、部署等等。
2. 安装 JDK8
(1) 下载,解压
(2) 设置环境变量
我建议你也用这样的环境变量,以后如果升级 JDK 版本,只需要修改JAVA_HOME就可以了。
3. 安装 Jenkins
(1) 导入 Jenkins 存储库的 GPG 密钥
(2) Jenkins存储库添加到系统中
(3) 使用 apt 安装
Jenkins 服务将在安装过程完成后自动启动,可以通过指令systemctl status jenkins进行验证。
文件二:/etc/default/jenkins
如果不幸遇到错误,可以反复使用这两个指令来排除错误。
4. 在浏览器中配置 Jenkins
在浏览器中输入: htpp://localhost:9090,稍等一会,出现界面:
5. 在 Jenkins 中配置一个小项目
(1) 准备一个测试代码 Test1
6. 手动触发编译一次
由于在上面的步骤(6)中,我们没有选择任何触发条件,所以需要我们在项目 Test1 的主界面中,手动单击左侧的 Build Now 按钮来触发。
三、git submodule 基本使用
1. git submodule 是什么?
git submodule 是用于多模块管理的工具,它允许一个项目作为 repository,其他项目作为子模块存在于在父项目中。
添加子模块: git submodule add
更新子模块: git submodule update
初始化子模块: git submodule init 递归的方式克隆整个项目: git clone--recursive
拉取所有子模块: git submodule foreach git pull
2. 利用三个小项目,来测试一下 submodule 的用法
为了便于演示,我们我们创建 3 个项目,把它们都推送到远程仓库中,这里使用 gitee。
为什么要这样设计模块: 安全!
- Test1:编译得到一个动态库:libtest1.so;
- Test2:编译得到一个动态度:libtest2.so;
- Test3:编译得到一个可执行程序,加载、调用上面 2 个动态库中的函数。
项目经理需要把 Test1 和 Test2 作为 sub module,添加到 Test3 中,执行下面的指令:
- 开发人员A:负责 Test1,没有权限拿到其他模块的代码;
- 开发人员B:负责 Test2,没有权限拿到其他模块的代码;
- 项目经理:负责 Test3 和 代码整合,能拿到所有的代码;
1. git submodule add https://gitee.com/[你的账号]/test1.git test1把 Test1 和 Test2 作为子模块添加到 Test3 中之后,看一下文件有什么变化:
2. git submodule add https://gitee.com/[你的账号]/test2.git test2
3. 在一个空目录中来编译、验证一下可行性
我们在另一个空目录中,clone 一下 Test3 这个项目,可以发现:克隆下来的 test1 和 test2 文件夹中是空的,如下所示:
此时,再使用 tree 命令看一下文件变化,可以看到 test1 和 test2 的文件都被拉取下来了。这里有一个问题需要注意:虽然子模块的代码被拉取下来了,但是其 head 并没有指向 master 分支,需要手动处理一下,如图:
四、在 Jenkins 中使用 git module 来编译所有的模块
下面的操作,都是在浏览器的 Jenkins 面板中来操作的。
1. 重新配置项目
因为我们是在 Test3 中,来编译整个项目(Test1 和 Test2 被作为子模块包括进来),因此首先把之前添加的 Test1 项目删除掉,如图:
当然,也可以直接在之前的 Test1 项目基础上进行修改。
- 输入描述信息,选择自由风格项目;
- 输入 git 仓库地址和账户信息,选择 master 分支;
- 触发器不设置;
- 编译环境不设置;
- 编译:选择 Execute shell 执行脚本,输入编译指令:./build.sh。(刚才说了,Jenkins 这是一个自动化构建框架,具体的编译过程由用户决定,所以我们这里的编译过程就是执行 Test3 下的 build.sh 这个脚本。);
- 编译后动作不设置;
此时,重新触发编译一次,一定可以成功的!
五、总结
这篇文章是属于工具型的,一旦部署好之后,每次编译只需要在浏览器中点一下按钮就行,再也不用 ssh 登录到远程电脑中去手动操作了。
1. Jenkins 是如何保持编译历史记录的
在目录 /var/lib/jenkins/jobs/Test3/builds 下面,可以看到很多以数字命名的文件夹,记录了每一次的编译信息。
2. 编译后动作
在我们的编译脚本 build.sh 文件中,仅仅是生成了可执行文件,你还可以继续扩充功能,例如:自动部署。
3. git subtree 功能
它与 git submodule 很类似,但是本质不一样。
- subtree直接把子模块代码拷贝到主模块中,使用命令简单;
- submodule 使用的是“指针”指向子模块,使用命令相对复杂一些,功能也更强大;
4. 继续研究 Jenkins 中的插件功能
六、资源下载
文中用到的资源,放在了网盘中。如果需要的话,请在公众号留言区发送数字:030,即可收到下载地址。