一、场景引入:为什么要做Jenkins和SVN的深度集成
很多做开发的朋友都有过这样的经历:自己改完代码提交到SVN仓库,要等半天才能看到测试结果——要么是测试同学还没来得及拉最新代码打包,要么是部署环境出问题耽误事。要是能让代码提交后自动触发打包、测试,还能自动生成这次改了啥的变更日志,整个流程自动走完,是不是能省好多事?这就是我们要做的核心:把Jenkins(自动干活的“流水线管家”)和SVN(存代码的“仓库管理员”)打通,实现从代码提交到交付的全自动化。
先给大家说清楚两个工具的基础定位,怕有刚接触的朋友搞混:Jenkins是专门做自动化流水线的工具,你可以把它当成一个“机器助手”,能按你设定的步骤一步步干活,比如拉代码、打包、测试、部署;SVN是版本控制工具,用来存所有版本的代码,每次提交都会留下提交记录(比如谁改的、改了啥、提交备注是什么)。我们要做的就是让SVN一有新提交,就告诉Jenkins“有新代码啦,快干活”,还要把这次提交的记录提取出来做成变更日志。
二、准备工作:需要提前搞定的4件事
在动手配置之前,得先把基础环境搭好,不然会踩很多坑。这里所有操作都用CentOS 7系统(最常用的服务器系统),所有命令和配置都给大家写清楚,跟着敲就行。
2.1 安装Jenkins
首先要装Java,因为Jenkins是用Java写的,没有Java跑不起来。先装OpenJDK 11(兼容性最好的版本):
# 安装OpenJDK 11
yum install -y java-11-openjdk-devel
# 验证Java是否安装成功,能显示版本号就说明没问题
java -version
然后装Jenkins,用官方的yum源,避免装到旧版本:
# 导入Jenkins的GPG密钥
wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
# 安装Jenkins
yum install -y jenkins
# 启动Jenkins并设置开机自启
systemctl start jenkins
systemctl enable jenkins
# 开放Jenkins的默认端口8080(防火墙要开)
firewall-cmd --zone=public --add-port=8080/tcp --permanent
firewall-cmd --reload
装完之后,打开浏览器输入“服务器IP:8080”,就能看到Jenkins的初始化页面,按提示输入初始密码(密码在/var/lib/jenkins/secrets/initialAdminPassword文件里),然后选“安装推荐的插件”,等插件装完创建管理员账号就可以了。
2.2 安装SVN服务器和客户端
先装SVN服务器,用来存我们的代码仓库:
# 安装SVN服务器
yum install -y subversion subversion-server
# 创建SVN的根目录,所有仓库都存在这里
mkdir -p /svn/repos
# 初始化一个测试仓库,名字叫test-project
svnadmin create /svn/repos/test-project
# 给仓库设置权限,允许Jenkins访问
# 先配置仓库的访问权限文件
vim /svn/repos/test-project/conf/authz
# 在文件最后加一行:[test-project:/],然后下面写:* = rw (所有用户都有读写权限,测试用,生产环境要严格限制)
# 再配置密码文件
vim /svn/repos/test-project/conf/passwd
# 在[users]下面加一行:jenkins = 123456 (Jenkins访问仓库的账号密码)
然后装SVN客户端,Jenkins要靠客户端拉代码:
# 安装SVN客户端
yum install -y subversion
# 验证客户端,能显示版本号就说明没问题
svn --version
2.3 配置Jenkins的插件和账号
Jenkins要和SVN通信,得装专门的插件,还要配置访问SVN的账号。首先装插件:打开Jenkins的“系统管理”→“插件管理”→“可选插件”,搜索并安装两个插件:
- Subversion Plugin:Jenkins和SVN通信的核心插件,没有这个连SVN都连不上
- Build Trigger Plugin:用来配置触发条件的插件,我们要的“提交触发”就靠它
插件装完之后,配置SVN的访问账号:打开“系统管理”→“Manage Credentials”→“全局”→“添加凭证”,类型选“Username with password”,用户名填刚才在SVN里设的jenkins,密码填123456,描述填“SVN测试仓库账号”,保存就行。
2.4 准备一个测试项目
为了方便演示,我们准备一个简单的Java项目(就一个HelloWorld类,打包成Jar包),先把项目提交到SVN仓库。
# 先创建一个本地项目目录
mkdir -p /root/test-project
cd /root/test-project
# 初始化Maven项目(用Maven打包,所以要装Maven)
yum install -y maven
mvn archetype:generate -DgroupId=com.example -DartifactId=test-project -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
# 进入项目目录,修改pom.xml,让它能打包成可执行Jar
vim test-project/pom.xml
# 在<build>标签里加下面的配置,用来指定主类
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<mainClass>com.example.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
# 把项目提交到SVN仓库
svn import /root/test-project file:///svn/repos/test-project -m "初始化项目"
三、核心配置:SVN提交触发Jenkins自动构建
这一步是整个流程的核心,我们要让SVN一有新代码提交,就自动告诉Jenkins“该干活了”。这里分两种触发方式:轮询触发(Jenkins定时去SVN查有没有新提交)和钩子触发(SVN一有提交就主动通知Jenkins),我们两种都讲,重点讲钩子触发(实时性更好)。
3.1 配置轮询触发(入门级,适合新手)
轮询触发的原理很简单:Jenkins每隔一段时间就去SVN仓库查一次,看有没有新的提交,如果有就启动构建。配置步骤如下:
- 打开Jenkins,新建一个任务,类型选“自由风格软件项目”,名字填“test-project-auto-build”,保存
- 进入任务配置页面,找到“源码管理”,选“Subversion”,仓库地址填“file:///svn/repos/test-project”,凭证选刚才配置的jenkins账号,保存
- 找到“构建触发器”,勾选“Poll SCM”,然后在下面的输入框里填“*/5 * * * *”(这个是定时表达式,意思是每5分钟查一次)
- 找到“构建”,点击“增加构建步骤”,选“Invoke top-level Maven targets”,在“Goals”里填“clean package”(意思是先清理旧文件,再打包),保存
现在测试一下:我们修改本地的App.java,然后提交到SVN,等最多5分钟,Jenkins就会自动启动构建,打包出Jar包。轮询触发的优点是配置简单,不用改SVN的配置;缺点是有延迟,最多要等5分钟才能触发,浪费资源。
3.2 配置钩子触发(专业级,实时性好)
钩子触发的原理是:在SVN服务器上配置一个钩子脚本,当有新的提交时,脚本会自动调用Jenkins的API,通知Jenkins启动构建。这种方式是实时的,提交完马上就触发,没有延迟。
首先要配置Jenkins的API访问权限:打开Jenkins的“系统管理”→“全局安全配置”,找到“CSRF Protection”,勾选“Enable security”,然后找到“API Token”,生成一个API Token(每个账号可以生成自己的Token,用来调用API)。
然后配置SVN的钩子脚本:SVN的钩子脚本是放在仓库的hooks目录下的,我们要用到的是post-commit钩子(提交完成后执行的脚本)。
# 进入SVN仓库的hooks目录
cd /svn/repos/test-project/hooks
# 复制默认的钩子模板,改成我们要用的post-commit
cp post-commit.tmpl post-commit
# 给脚本加执行权限
chmod +x post-commit
# 编辑钩子脚本
vim post-commit
把脚本里的内容改成下面的,注意把里面的IP、Token、任务名改成你自己的:
#!/bin/bash
# 这是SVN提交后触发Jenkins构建的钩子脚本
# 配置参数:把下面的内容改成你自己的
JENKINS_URL="http://你的Jenkins服务器IP:8080" # Jenkins的访问地址
JENKINS_USER="你的Jenkins管理员用户名" # Jenkins的管理员账号
JENKINS_TOKEN="你的Jenkins API Token" # 刚才生成的API Token
JOB_NAME="test-project-auto-build" # 刚才创建的Jenkins任务名
# 调用Jenkins的API,触发构建
curl -X POST "$JENKINS_URL/job/$JOB_NAME/build" \
--user "$JENKINS_USER:$JENKINS_TOKEN"
# 可选:把触发结果写到日志里,方便排查问题
echo "SVN提交触发Jenkins构建完成,任务名:$JOB_NAME" >> /svn/repos/test-project/hooks/post-commit.log
现在测试一下:修改本地的App.java,提交到SVN,等个几秒钟,Jenkins就会自动启动构建,比轮询快多了。
四、进阶功能:自动获取SVN提交记录生成变更日志
光自动构建还不够,我们还要自动生成这次构建对应的变更日志,比如这次提交改了啥、谁改的、提交备注是什么。我们可以用SVN的命令行工具来提取提交记录,然后把它加到Jenkins的构建步骤里。
4.1 原理说明:SVN的提交记录怎么提取
SVN有个命令叫svn log,可以提取指定版本范围的提交记录。比如我们要提取上次构建到这次构建之间的提交记录,就可以用这个命令。我们可以在Jenkins的构建步骤里加一个脚本,每次构建前先提取上次构建的版本号,然后用svn log提取这段时间的提交记录,保存成一个文件,再把这个文件加到打包好的Jar包里,或者直接在Jenkins的构建结果里显示。
4.2 配置步骤:把变更日志加到Jenkins构建里
首先要修改Jenkins的任务配置,加一个构建步骤来提取提交记录。进入“test-project-auto-build”任务的配置页面,找到“构建”,在原来的Maven构建步骤前面加一个“执行Shell”步骤,内容如下:
# 配置参数:改成你自己的
SVN_REPO="file:///svn/repos/test-project" # SVN仓库地址
CHANGE_LOG_FILE="change-log.txt" # 变更日志的文件名
# 1. 获取上次构建的版本号(如果是第一次构建,就取第一个版本)
LAST_BUILD_REV=$(svn info --show-item last-changed-revision $SVN_REPO)
if [ -z "$LAST_BUILD_REV" ]; then
LAST_BUILD_REV=1
fi
# 2. 获取当前构建的版本号
CURRENT_REV=$(svn info --show-item last-changed-revision $SVN_REPO)
# 3. 提取两个版本之间的提交记录,生成变更日志
svn log -r $LAST_BUILD_REV:$CURRENT_REV $SVN_REPO > $CHANGE_LOG_FILE
# 4. 把变更日志复制到项目的resources目录,这样打包的时候会被加到Jar包里
cp $CHANGE_LOG_FILE src/main/resources/
# 5. 打印变更日志,方便在Jenkins的构建日志里查看
echo "本次构建的变更日志:"
cat $CHANGE_LOG_FILE
然后把原来的Maven构建步骤里的Goals改成“clean package”,保存。现在测试一下:修改本地的App.java,提交到SVN,Jenkins自动启动构建,构建完成后,你可以在Jenkins的构建日志里看到变更日志,打包好的Jar包里也会有change-log.txt文件。
4.3 优化:把变更日志加到Jenkins的构建结果页面
刚才的变更日志是在构建日志里显示的,我们可以把它加到Jenkins的构建结果页面,更方便查看。需要装一个插件:“Text Finder Plugin”,安装方法和之前的插件一样。
装完之后,进入任务的配置页面,找到“构建后操作”,点击“增加构建后操作步骤”,选“Find text in build log”,然后在“Regular expression to search for”里填“本次构建的变更日志:”,勾选“Display the text in the build result”,保存。现在构建完成后,你可以在构建结果页面看到一个“Text Finder”的链接,点击就能看到变更日志。
五、应用场景、优缺点和注意事项
5.1 应用场景
这套方案适合很多场景,比如:
- 团队开发的日常迭代:每次代码提交后自动构建、测试,不用等人工操作
- 上线前的预发布验证:提交代码后自动打包,生成变更日志,方便测试同学快速了解改了啥
- 开源项目的CI/CD:自动验证提交的代码能不能正常构建,自动生成版本更新日志
5.2 技术优缺点
优点:
- 实时性好:钩子触发的方式提交完马上触发,没有延迟
- 配置灵活:可以根据自己的需求调整构建步骤,比如加测试、部署、发送通知等
- 成本低:Jenkins和SVN都是免费的,不需要额外花钱
- 兼容性好:支持各种语言的项目,比如Java、Python、C++等
缺点:
- 配置复杂:需要熟悉Jenkins和SVN的配置,新手容易踩坑
- 维护成本高:如果服务器出问题,要自己排查解决
- 功能有限:和现在流行的GitLab CI、GitHub Actions比,功能比较少,界面也比较旧
5.3 注意事项
- 安全问题:Jenkins的API Token要保密,不要泄露;SVN的仓库权限要严格控制,不要给所有用户都开读写权限
- 网络问题:如果Jenkins和SVN不在同一台服务器上,要保证网络连通,防火墙要开对应的端口
- 日志问题:要定期清理SVN的钩子日志和Jenkins的构建日志,避免占满服务器空间
- 兼容性问题:要保证Jenkins的版本和插件的版本兼容,不要装太旧的插件
六、文章总结
今天我们从场景引入开始,一步步教大家怎么把Jenkins和SVN打通,实现提交触发的自动构建和变更日志的生成。我们先搭了基础环境,然后配置了两种触发方式(轮询和钩子),最后加了自动生成变更日志的功能。这套方案虽然不是最新的,但非常实用,适合中小团队或者对成本敏感的项目。
其实Jenkins和SVN的集成还有很多进阶功能,比如自动测试、自动部署、发送邮件通知等,大家可以根据自己的需求继续扩展。希望今天的内容能帮大家解决实际问题,提高开发效率。
评论
围绕“全方位详解Jenkins与SVN深度集成实战指南实现基于提交触发的自动构建变更日志获取并集成到持续交付流水线中”参与讨论