Comment dire à Jenkins / Hudson de déclencher une compilation uniquement pour les changements sur un projet particulier dans mon arbre Git?
Comment dire à Jenkins / Hudson de déclencher une compilation uniquement pour les changements sur un projet particulier dans mon arbre Git?
Réponses:
Le plugin Git a une option (région exclue) pour utiliser des expressions régulières pour déterminer s'il faut ignorer la construction en fonction du fait que les fichiers du commit correspondent à l'expression régulière de la région exclue.
Malheureusement, le plugin Git stock n'a pas de fonctionnalité "région incluse" pour le moment (1.15). Cependant, quelqu'un a publié des correctifs sur GitHub qui fonctionnent sur Jenkins et Hudson et qui implémentent la fonctionnalité souhaitée.
C'est un peu de travail à construire, mais cela fonctionne comme annoncé et a été extrêmement utile car l'un de mes arbres Git a plusieurs projets indépendants.
https://github.com/jenkinsci/git-plugin/pull/49
Mise à jour: Le plugin Git (1.16) a maintenant la fonction de région «incluse».
Ignored commit c6e2b1dca0d1885: No paths matched included region whitelist
. Un indice? Plus de détails ici: stackoverflow.com/questions/47439042/…
En gros, vous avez besoin de deux emplois. Un pour vérifier si les fichiers ont changé et un pour faire la construction réelle:
Emploi n ° 1
Cela devrait être déclenché lors des changements dans votre référentiel Git. Il teste ensuite si le chemin que vous spécifiez ("src" ici) a changé, puis utilise la CLI de Jenkins pour déclencher un deuxième travail.
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
Emploi n ° 2
Configurez ce travail pour prendre un paramètre GIT_REVISION comme ceci, pour vous assurer que vous construisez exactement la révision que le premier travail a choisi de construire.
$? || exit 0
... test $? -eq 0 || exit 0
peut-être?
Si vous utilisez une syntaxe déclarative de Jenkinsfile pour décrire votre pipeline de construction, vous pouvez utiliser la condition de changeset pour limiter l'exécution de l'étape uniquement au cas où des fichiers spécifiques sont modifiés. C'est maintenant une fonctionnalité standard de Jenkins et ne nécessite aucune configuration / logiciel supplémentaire.
stages {
stage('Nginx') {
when { changeset "nginx/*"}
steps {
sh "make build-nginx"
sh "make start-nginx"
}
}
}
Vous pouvez combiner plusieurs conditions à l'aide de mots clés anyOf
ou allOf
pour le comportement OR ou AND en conséquence:
when {
anyOf {
changeset "nginx/**"
changeset "fluent-bit/**"
}
}
steps {
sh "make build-nginx"
sh "make start-nginx"
}
Bien que cela n'affecte pas les tâches uniques, vous pouvez utiliser ce script pour ignorer certaines étapes si la dernière validation ne contenait aucune modification:
/*
* 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/
dossier.) Si vous pouvez résoudre ce problème, j'aimerais une modification suggérée !
Vous pouvez utiliser Generic Webhook Trigger Plugin pour cela.
Avec une variable comme changed_files
et une expression$.commits[*].['modified','added','removed'][*]
.
Vous pouvez avoir un texte de filtre comme $changed_files
et une expression régulière de filtre comme "folder/subfolder/[^"]+?"
si folder/subfolder
est le dossier qui devrait déclencher les compilations.
J'ai répondu à cette question dans un autre post:
Comment obtenir la liste des fichiers modifiés depuis la dernière construction dans 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;
Vous pouvez ajouter la vérification directement en haut du shell d'exécution du travail, et ce sera le exit 0
cas si aucun changement n'est détecté ... Par conséquent, vous pouvez toujours interroger le niveau supérieur pour que les check-in déclenchent une construction.
J'ai écrit ce script pour ignorer ou exécuter des tests s'il y a des changements:
#!/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 "$@"
Vous pouvez donc faire quelque chose comme:
./scripts/git-run-if-changed.sh cmd vendor go.mod go.sum fixtures/ tools/ -- go test