Jenkins / Hudson'a yalnızca Git ağacımdaki belirli bir projedeki değişiklikler için bir derlemeyi tetiklemesini nasıl söylerim?
Jenkins / Hudson'a yalnızca Git ağacımdaki belirli bir projedeki değişiklikler için bir derlemeyi tetiklemesini nasıl söylerim?
Yanıtlar:
Git eklentisinin, kaydetmedeki dosyaların hariç tutulan bölge normal ifadesiyle eşleşip eşleşmediğine bağlı olarak derlemeyi atlayıp atlamayacağını belirlemek için normal ifadeleri kullanma seçeneği (hariç tutulan bölge) vardır.
Ne yazık ki, stok Git eklentisinin şu anda "dahil edilen bölge" özelliği yok (1.15). Ancak, birisi GitHub'da Jenkins ve Hudson üzerinde çalışan ve istediğiniz özelliği uygulayan yamalar yayınladı.
Yapılması gereken küçük bir iş, ancak reklamı yapıldığı gibi çalışıyor ve Git ağaçlarımdan birinin birden fazla bağımsız projesi olduğu için son derece yararlı oldu.
https://github.com/jenkinsci/git-plugin/pull/49
Güncelleme: Git eklentisi (1.16) artık 'dahil edilen' bölge özelliğine sahiptir.
Ignored commit c6e2b1dca0d1885: No paths matched included region whitelist
. Bir ipucu? Daha fazla ayrıntı burada: stackoverflow.com/questions/47439042/…
Temel olarak, iki işe ihtiyacınız var. Biri dosyaların değişip değişmediğini kontrol etmek için ve biri asıl derlemeyi yapmak için:
İş 1
Bu, Git deponuzdaki değişikliklerde tetiklenmelidir. Daha sonra belirttiğiniz yolda ("src" burada) değişiklik olup olmadığını test eder ve ardından ikinci bir işi tetiklemek için Jenkins'in CLI'sini kullanır .
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
İlk işin oluşturmayı seçtiği revizyonu tam olarak oluşturduğunuzdan emin olmak için bu işi GIT_REVISION parametresini alacak şekilde yapılandırın.
$? || exit 0
... test $? -eq 0 || exit 0
belki?
Bina ardışık düzeninizi tanımlamak için açıklayıcı bir Jenkinsfile sözdizimi kullanıyorsanız , şunu kullanabilirsiniz: değişiklik kümesi belirli dosyalar değiştiğinde sadece davaya sınır sahne yürütmeye koşulu. Bu artık Jenkins'in standart bir özelliğidirve herhangi bir ek yapılandırma / yazılım gerektirmez.
stages {
stage('Nginx') {
when { changeset "nginx/*"}
steps {
sh "make build-nginx"
sh "make start-nginx"
}
}
}
VEYA veya VE davranışı için anyOf
veya allOf
anahtar kelimelerini kullanarak birden çok koşulu buna göre birleştirebilirsiniz:
when {
anyOf {
changeset "nginx/**"
changeset "fluent-bit/**"
}
}
steps {
sh "make build-nginx"
sh "make start-nginx"
}
Bu, tek işleri etkilemese de, en son kaydetme herhangi bir değişiklik içermiyorsa, bu komut dosyasını belirli adımları yok saymak için kullanabilirsiniz:
/*
* 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/
klasörü de değiştirmediyse, bu işlemi yeniden denemezdi .) Bunu düzeltebilirseniz, önerilen bir değişikliği çok isterim. !
Sen kullanabilirsiniz Jenerik Webhook Tetik Plugin .
Değişken gibi changed_files
ve ifade ile$.commits[*].['modified','added','removed'][*]
.
Bir gibi filtre metin olabilir $changed_files
gibi ve filtre Regexp'i "folder/subfolder/[^"]+?"
eğer folder/subfolder
kurar tetiklemesi gereken klasördür.
Bu soruyu başka bir gönderide cevapladım:
Jenkins / Hudson'daki son derlemeden bu yana değişen dosyaların listesi nasıl alınır
#!/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;
Denetimi doğrudan işin yürütme kabuğunun üstüne ekleyebilirsiniz ve exit 0
herhangi bir değişiklik tespit edilmezse, bu nedenle, bir yapıyı tetiklemek için teslimatlar için her zaman en üst seviyeyi sorgulayabilirsiniz.
Değişiklikler varsa testleri atlamak veya yürütmek için bu komut dosyasını yazdım:
#!/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 "$@"
Böylece şöyle bir şey yapabilirsiniz:
./scripts/git-run-if-changed.sh cmd vendor go.mod go.sum fixtures/ tools/ -- go test