Bagaimana cara memberi tahu Jenkins / Hudson untuk memicu build hanya untuk perubahan pada proyek tertentu di pohon Git saya?
Bagaimana cara memberi tahu Jenkins / Hudson untuk memicu build hanya untuk perubahan pada proyek tertentu di pohon Git saya?
Jawaban:
Plugin Git memiliki opsi (wilayah yang dikecualikan) untuk menggunakan regex guna menentukan apakah akan melewati pembuatan berdasarkan apakah file dalam komit cocok dengan regex wilayah yang dikecualikan.
Sayangnya, plugin Git stok saat ini tidak memiliki fitur "wilayah yang disertakan" (1.15). Namun, seseorang memposting tambalan di GitHub yang berfungsi di Jenkins dan Hudson yang menerapkan fitur yang Anda inginkan.
Ini adalah pekerjaan kecil untuk dibangun, tetapi berfungsi seperti yang diiklankan dan sangat berguna karena salah satu pohon Git saya memiliki beberapa proyek independen.
https://github.com/jenkinsci/git-plugin/pull/49
Pembaruan: Plugin Git (1.16) sekarang memiliki fitur wilayah 'disertakan'.
Ignored commit c6e2b1dca0d1885: No paths matched included region whitelist
. Ada petunjuk? Detail lebih lanjut di sini: stackoverflow.com/questions/47439042/…
Pada dasarnya, Anda membutuhkan dua pekerjaan. Satu untuk memeriksa apakah file berubah dan satu untuk melakukan build yang sebenarnya:
Pekerjaan # 1
Ini harus dipicu pada perubahan di repositori Git Anda. Ini kemudian menguji apakah jalur yang Anda tentukan ("src" di sini) memiliki perubahan dan kemudian menggunakan CLI Jenkins untuk memicu pekerjaan kedua.
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
Pekerjaan # 2
Konfigurasi pekerjaan ini untuk mengambil parameter GIT_REVISION seperti itu, untuk memastikan Anda membuat revisi persis seperti yang dipilih oleh pekerjaan pertama untuk dibuat.
$? || exit 0
... test $? -eq 0 || exit 0
mungkin?
Jika Anda menggunakan sintaks deklaratif Jenkinsfile untuk mendeskripsikan pipeline bangunan Anda, Anda bisa menggunakan kondisi changeset untuk membatasi eksekusi tahapan hanya pada kasus ketika file tertentu diubah. Ini sekarang menjadi fitur standar Jenkins dan tidak memerlukan konfigurasi / perangkat lunak tambahan.
stages {
stage('Nginx') {
when { changeset "nginx/*"}
steps {
sh "make build-nginx"
sh "make start-nginx"
}
}
}
Anda dapat menggabungkan beberapa ketentuan menggunakan anyOf
atau allOf
kata kunci untuk ATAU atau DAN perilaku yang sesuai:
when {
anyOf {
changeset "nginx/**"
changeset "fluent-bit/**"
}
}
steps {
sh "make build-nginx"
sh "make start-nginx"
}
Meskipun ini tidak memengaruhi pekerjaan tunggal, Anda dapat menggunakan skrip ini untuk mengabaikan langkah-langkah tertentu jika komit terbaru tidak berisi perubahan apa pun:
/*
* 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/
foldernya.) Jika Anda dapat memperbaiki ini, saya akan menyukai perubahan yang disarankan !
Anda dapat menggunakan Plugin Pemicu Webhook Generik untuk ini.
Dengan variabel suka changed_files
dan ekspresi$.commits[*].['modified','added','removed'][*]
.
Anda dapat memiliki teks filter seperti $changed_files
dan filter regexp seperti "folder/subfolder/[^"]+?"
jika folder/subfolder
folder yang harus memicu build.
Saya menjawab pertanyaan ini di posting lain:
Cara mendapatkan daftar file yang diubah sejak pembuatan terakhir di 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;
Anda dapat menambahkan pemeriksaan langsung ke bagian atas shell exec pekerjaan, dan ini akan terjadi exit 0
jika tidak ada perubahan yang terdeteksi ... Oleh karena itu, Anda selalu dapat melakukan polling di tingkat teratas untuk check-in guna memicu build.
Saya menulis skrip ini untuk melewati atau menjalankan tes jika ada perubahan:
#!/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 "$@"
Jadi Anda bisa melakukan sesuatu seperti:
./scripts/git-run-if-changed.sh cmd vendor go.mod go.sum fixtures/ tools/ -- go test