Come faccio a dire a Jenkins / Hudson di attivare una build solo per le modifiche su un particolare progetto nel mio albero Git?
Come faccio a dire a Jenkins / Hudson di attivare una build solo per le modifiche su un particolare progetto nel mio albero Git?
Risposte:
Il plug-in Git ha un'opzione (regione esclusa) per utilizzare le espressioni regolari per determinare se saltare la creazione in base alla corrispondenza dei file nel commit con la regione esclusa.
Sfortunatamente, il plugin Git di serie non ha una funzione "regione inclusa" al momento (1.15). Tuttavia, qualcuno ha pubblicato patch su GitHub che funzionano su Jenkins e Hudson che implementano la funzionalità desiderata.
È un po 'di lavoro da costruire, ma funziona come pubblicizzato ed è stato estremamente utile poiché uno dei miei alberi Git ha più progetti indipendenti.
https://github.com/jenkinsci/git-plugin/pull/49
Aggiornamento: il plug-in Git (1.16) ora ha la funzione di regione "inclusa".
Ignored commit c6e2b1dca0d1885: No paths matched included region whitelist
. Qualche indizio? Maggiori dettagli qui: stackoverflow.com/questions/47439042/...
Fondamentalmente, hai bisogno di due lavori. Uno per verificare se i file sono cambiati e uno per eseguire la build effettiva:
Lavoro n. 1
Questo dovrebbe essere attivato in caso di modifiche nel tuo repository Git. Quindi verifica se il percorso specificato ("src" qui) presenta modifiche e quindi utilizza la CLI di Jenkins per attivare un secondo lavoro.
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
Lavoro n. 2
Configura questo lavoro per prendere un parametro GIT_REVISION in questo modo, per assicurarti di costruire esattamente la revisione che il primo lavoro ha scelto di costruire.
$? || exit 0
... test $? -eq 0 || exit 0
forse?
Se si utilizza una sintassi dichiarativa di Jenkinsfile per descrivere la pipeline di costruzione, è possibile utilizzare la condizione changeset per limitare l'esecuzione della fase solo nel caso in cui vengano modificati file specifici. Questa è ora una caratteristica standard di Jenkins e non richiede alcuna configurazione / software aggiuntivo.
stages {
stage('Nginx') {
when { changeset "nginx/*"}
steps {
sh "make build-nginx"
sh "make start-nginx"
}
}
}
Puoi combinare più condizioni utilizzando anyOf
o allOf
parole chiave per il comportamento OR o AND di conseguenza:
when {
anyOf {
changeset "nginx/**"
changeset "fluent-bit/**"
}
}
steps {
sh "make build-nginx"
sh "make start-nginx"
}
Sebbene ciò non influisca sui singoli lavori, è possibile utilizzare questo script per ignorare determinati passaggi se l'ultimo commit non conteneva modifiche:
/*
* 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/
cartella.) Se puoi risolvere questo problema, mi piacerebbe una modifica suggerita !
Puoi usare Generic Webhook Trigger Plugin per questo.
Con una variabile like changed_files
and expression $.commits[*].['modified','added','removed'][*]
.
Puoi avere un filtro di testo come $changed_files
e filtro regexp come "folder/subfolder/[^"]+?"
se folder/subfolder
fosse la cartella che dovrebbe attivare le build.
Ho risposto a questa domanda in un altro post:
Come ottenere l'elenco dei file modificati dall'ultima build in 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;
Puoi aggiungere il controllo direttamente all'inizio della shell di esecuzione del lavoro e lo farà exit 0
se non vengono rilevate modifiche ... Quindi, puoi sempre eseguire il polling del livello più alto per i check-in per attivare una build.
Ho scritto questo script per saltare o eseguire test se ci sono modifiche:
#!/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 "$@"
Quindi puoi fare qualcosa come:
./scripts/git-run-if-changed.sh cmd vendor go.mod go.sum fixtures/ tools/ -- go test