Как мне сказать Jenkins / Hudson запускать сборку только для изменений в конкретном проекте в моем дереве Git?
Как мне сказать Jenkins / Hudson запускать сборку только для изменений в конкретном проекте в моем дереве Git?
Ответы:
В подключаемом модуле Git есть опция (исключенная область) для использования регулярных выражений, чтобы определить, пропускать ли построение на основе того, соответствуют ли файлы в фиксации регулярному выражению исключенной области.
К сожалению, стандартный плагин Git в настоящее время не имеет функции «включенного региона» (1.15). Однако кто-то разместил на GitHub патчи, которые работают с Jenkins и Hudson и реализуют нужную вам функцию.
Это небольшая работа для создания, но она работает так, как рекламируется, и была чрезвычайно полезна, поскольку в одном из моих деревьев Git есть несколько независимых проектов.
https://github.com/jenkinsci/git-plugin/pull/49
Обновление: плагин Git (1.16) теперь имеет функцию «включенного» региона.
Ignored commit c6e2b1dca0d1885: No paths matched included region whitelist
. Есть подсказка? Подробнее здесь: stackoverflow.com/questions/47439042/…
По сути, вам нужно две работы. Один для проверки, изменились ли файлы, и один для выполнения фактической сборки:
Работа №1
Это должно срабатывать при изменениях в вашем репозитории Git. Затем он проверяет, есть ли изменения в указанном вами пути (здесь "src"), а затем использует CLI Jenkins для запуска второго задания.
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
может быть?
Если вы используете декларативный синтаксис Jenkinsfile для описания конвейера сборки, вы можете использовать условие набора изменений, чтобы ограничить выполнение стадии только тем случаем, когда были изменены определенные файлы. Теперь это стандартная функция Jenkins и не требует дополнительной настройки / программного обеспечения.
stages {
stage('Nginx') {
when { changeset "nginx/*"}
steps {
sh "make build-nginx"
sh "make start-nginx"
}
}
}
Вы можете комбинировать несколько условий, используя ключевые слова anyOf
или allOf
для поведения ИЛИ или И соответственно:
when {
anyOf {
changeset "nginx/**"
changeset "fluent-bit/**"
}
}
steps {
sh "make build-nginx"
sh "make start-nginx"
}
Хотя это не влияет на отдельные задания, вы можете использовать этот сценарий, чтобы игнорировать определенные шаги, если последняя фиксация не содержала никаких изменений:
/*
* 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/
папку). Если вы можете это исправить, мне бы понравилось предлагаемое изменение !
Для этого вы можете использовать плагин Generic Webhook Trigger .
С такой переменной, как 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;
Вы можете добавить проверку непосредственно в верхнюю часть оболочки exec задания, и она будет, exit 0
если никаких изменений не обнаружено ... Следовательно, вы всегда можете опросить верхний уровень для проверки, чтобы запустить сборку.
Я написал этот скрипт, чтобы пропустить или выполнить тесты, если есть изменения:
#!/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 "$@"
Итак, вы можете сделать что-то вроде:
./scripts/git-run-if-changed.sh cmd vendor go.mod go.sum fixtures/ tools/ -- go test