如何实现Jenkins定时任务仅在SVN存在变更时触发执行
Jenkins定时触发场景下SVN变更检测拦截方案
你当前已配置每日19点的cron定时规则,无需修改调度配置,只需要在任务构建流程的最前置环节加入PowerShell检测逻辑,即可实现「SVN无变更时直接跳过后续所有构建步骤」的效果。
前置依赖
- Jenkins运行节点已安装SVN命令行工具,
svn.exe已加入系统环境变量PATH,或在脚本中写死svn.exe的绝对路径 - Jenkins任务的工作目录为对应SVN项目的工作副本根目录,配置的SVN账号拥有仓库读取权限
配置步骤
- 进入目标Jenkins任务的配置页面,找到「构建」配置区
- 在所有现有构建步骤的最上方,新增一个「执行Windows PowerShell」类型的构建步骤
- 将下述脚本粘贴到该步骤的脚本编辑框中,根据自身场景调整参数
- 保存任务配置即可生效
PowerShell检测脚本
# -------------------------- 按需修改配置项 -------------------------- $svnExePath = "svn.exe" # 如果svn没加PATH,这里填绝对路径,比如"C:\Program Files\TortoiseSVN\bin\svn.exe" $svnUsername = "" # SVN用户名,不需要认证就留空 $svnPassword = "" # SVN密码,不需要认证就留空 $projectRoot = $env:WORKSPACE # 默认用Jenkins工作目录作为SVN工作副本根目录,可自定义 # ------------------------------------------------------------------- # 组装svn通用参数 $svnCommonArgs = @() if ($svnUsername) { $svnCommonArgs += "--username", $svnUsername } if ($svnPassword) { $svnCommonArgs += "--password", $svnPassword } $svnCommonArgs += "--non-interactive", "--trust-server-cert" # 切到项目根目录 Set-Location $projectRoot # 获取本地工作副本当前版本号 $localInfo = & $svnExePath info $svnCommonArgs . $localRevision = [regex]::Match($localInfo, "Revision:\s+(\d+)").Groups[1].Value if (-not $localRevision) { Write-Error "获取本地SVN版本失败,请检查工作目录是否为有效SVN副本" exit 1 } # 获取SVN服务器上当前分支的最新版本号 $remoteInfo = & $svnExePath info $svnCommonArgs -r HEAD . $remoteRevision = [regex]::Match($remoteInfo, "Revision:\s+(\d+)").Groups[1].Value if (-not $remoteRevision) { Write-Error "获取SVN服务器最新版本失败,请检查网络和凭证配置" exit 1 } Write-Host "本地SVN版本: $localRevision,服务器最新版本: $remoteRevision" # 版本一致说明无变更,直接退出 if ([int]$localRevision -ge [int]$remoteRevision) { Write-Host "================================" Write-Host "SVN无新增代码变更,本次定时触发跳过后续构建步骤" Write-Host "================================" # 以成功状态退出,Jenkins不会执行后续构建步骤,任务标记为成功 exit 0 } # 有变更则继续执行后续构建步骤 Write-Host "检测到SVN存在代码变更,继续执行后续构建流程"
可选扩展逻辑
如果需要忽略特定文件/目录的变更(比如自动生成的changelog、临时配置文件、CI产物目录),可以在版本号比对通过后,拉取两个版本之间的变更文件列表做二次过滤:
# 拉取本地版本到最新版本之间的所有变更文件 $changeLogs = & $svnExePath log $svnCommonArgs -r "$localRevision`:HEAD" --verbose $changedFiles = [regex]::Matches($changeLogs, "\s+[MAD]\s+(.+)") | ForEach-Object { $_.Groups[1].Value } # 定义需要忽略的路径规则,支持通配符 $ignoreRules = @( "*/docs/*", "*.md", "*/temp/*" ) # 过滤掉忽略路径后,判断是否存在有效变更 $validChanges = $changedFiles | Where-Object { $file = $_ -not ($ignoreRules | Where-Object { $file -like $_ }) } if (-not $validChanges) { Write-Host "所有变更均为忽略范围内的文件,跳过后续构建" exit 0 }
注意:如果脚本用
exit 0退出时Jenkins仍继续执行后续步骤,可以将退出码改为exit 1,同时在该PowerShell步骤的高级配置里勾选「构建失败时标记构建为不稳定,而非直接失败」,避免无变更的触发被标记为失败任务。
内容的提问来源于stack exchange,提问作者G.A
相关产品推荐
相关产品推荐

