我该如何告诉Jenkins/Hudson只针对我Git树中特定项目的更改触发构建?
stages {
stage('Nginx') {
when { changeset "nginx/*"}
steps {
sh "make build-nginx"
sh "make start-nginx"
}
}
}
您可以使用anyOf
或allOf
关键字将多个条件组合起来,以实现OR或AND的行为:
when {
anyOf {
changeset "nginx/**"
changeset "fluent-bit/**"
}
}
steps {
sh "make build-nginx"
sh "make start-nginx"
}
Git插件有一个选项(排除区域),可以使用正则表达式来确定是否根据提交的文件是否匹配被排除的区域正则表达式跳过构建。
不幸的是,目前(1.15)stock Git插件没有“包含区域”功能。然而,有人在GitHub上发布了补丁,适用于Jenkins和Hudson,实现了你想要的功能。
这需要一些工作来构建,但它像广告一样有效,并且对我来说非常有用,因为我的Git树有多个独立的项目。
https://github.com/jenkinsci/git-plugin/pull/49
更新:Git插件(1.16)现在具有“包含”区域功能。
忽略提交c6e2b1dca0d1885:没有匹配包含区域白名单的路径
。有什么线索吗?更多细节请参见:https://dev59.com/OKbja4cB1Zd3GeqPovo3 - FranAguiar基本上,你需要两个任务。一个是检查文件是否更改,另一个是执行实际的构建:
任务 #1
此任务应在 Git 存储库中发生更改时触发。然后它会测试您指定的路径(这里是“src”)是否有更改,然后使用 Jenkins CLI 触发第二个任务。
export JENKINS_CLI="java -jar /var/run/jenkins/war/WEB-INF/jenkins-cli.jar"
export JENKINS_URL=http://localhost:8080/
export GIT_REVISION=`git rev-parse HEAD`
export STATUSFILE=$WORKSPACE/status_$BUILD_ID.txt
# Figure out, whether "src" has changed in the last commit
git diff-tree --name-only HEAD | grep src
# Exit with success if it didn't
$? || exit 0
# Trigger second job
$JENKINS_CLI build job2 -p GIT_REVISION=$GIT_REVISION -s
工作 #2
配置此工作以接受名为GIT_REVISION的参数,以确保您正在构建第一个工作选择要构建的确切修订版本。
$? || exit 0
中似乎缺少了一些东西... test $? -eq 0 || exit 0
可能是正确的吗? - antakjenkins-cli.jar
被禁用了。那么,在 jenkins 的 源代码管理 部分,如何指定 仓库 URL 上的 GIT-REVISION
?对于 SVN,我们可以在 URL 后缀中添加类似于 @${repo_rev}
的内容。 - Heinz.when{}
块中,以使其具有条件性,对吗? - undefined虽然这并不影响单个作业,但是如果最新的提交没有包含任何更改,您可以使用此脚本忽略某些步骤:
/*
* Check a folder if changed in the latest commit.
* Returns true if changed, or false if no changes.
*/
def checkFolderForDiffs(path) {
try {
// git diff will return 1 for changes (failure) which is caught in catch, or
// 0 meaning no changes
sh "git diff --quiet --exit-code HEAD~1..HEAD ${path}"
return false
} catch (err) {
return true
}
}
if ( checkFolderForDiffs('api/') ) {
//API folder changed, run steps here
}
api/
文件夹,它不会重试此提交。如果您能解决这个问题,我很乐意接受您的建议! - Blueimport jenkins.*;
import jenkins.model.*;
// CONFIGURATION
// Links between changed file patterns and job names to build
def jobsByPattern = [
"/my-project/": "my-project-job",
"my-super-project/":"super-job",
]
// Listing changes files since last build
def changeLogSets = build.changeSets
def changedFiles = []
for (int i = 0; i < changeLogSets.size(); i++) {
def entries = changeLogSets[i].items
for (int j = 0; j < entries.length; j++) {
def entry = entries[j]
def files = new ArrayList(entry.affectedFiles)
for (int k = 0; k < files.size(); k++) {
def file = files[k]
changedFiles.add(file.path)
}
}
}
// Listing ad hoc jobs to build
jobsToBuild = [:] // declare an empty map
for(entry in jobsByPattern ) {
def pattern = entry.key
println "Check pattern: $pattern"
for (int i = 0; i < changedFiles.size(); i++) {
def file = changedFiles[i]
println "Check file: $file"
if( file.contains( pattern ) ) {
def jobName = entry.value
jobsToBuild[ jobName ] = true
break
}
}
}
// Building appropriate jobs
jobsToBuild.each{
def jobName = it.key
println "$jobName must be built!"
def job = Jenkins.instance.getJob(jobName)
def cause = new hudson.model.Cause.UpstreamCause(build)
def causeAction = new hudson.model.CauseAction(cause)
Jenkins.instance.queue.schedule(job, 0, causeAction)
}
#!/bin/bash
set -e -o pipefail -u
paths=()
while [ "$1" != "--" ]; do
paths+=( "$1" ); shift
done
shift
if git diff --quiet --exit-code "${BASE_BRANCH:-origin/master}"..HEAD ${paths[@]}; then
echo "No changes in ${paths[@]}, skipping $@..." 1>&2
exit 0
fi
echo "Changes found in ${paths[@]}, running $@..." 1>&2
exec "$@"
changed_files
这样的变量和表达式$.commits [*]. ['modified','added','removed'] [*]
。$changed_files
和过滤正则表达式"folder/subfolder/ [^"]+?"
,如果folder/subfolder
是应触发构建的文件夹。我在另一篇文章中回答了这个问题:
如何在Jenkins/Hudson中获取自上次构建以来更改的文件列表
#!/bin/bash
set -e
job_name="whatever"
JOB_URL="http://myserver:8080/job/${job_name}/"
FILTER_PATH="path/to/folder/to/monitor"
python_func="import json, sys
obj = json.loads(sys.stdin.read())
ch_list = obj['changeSet']['items']
_list = [ j['affectedPaths'] for j in ch_list ]
for outer in _list:
for inner in outer:
print inner
"
_affected_files=`curl --silent ${JOB_URL}${BUILD_NUMBER}'/api/json' | python -c "$python_func"`
if [ -z "`echo \"$_affected_files\" | grep \"${FILTER_PATH}\"`" ]; then
echo "[INFO] no changes detected in ${FILTER_PATH}"
exit 0
else
echo "[INFO] changed files detected: "
for a_file in `echo "$_affected_files" | grep "${FILTER_PATH}"`; do
echo " $a_file"
done;
fi;