Làm cách nào để nói Jenkins / Hudson chỉ kích hoạt một bản dựng cho những thay đổi trên một dự án cụ thể trong cây Git của tôi?
Làm cách nào để nói Jenkins / Hudson chỉ kích hoạt một bản dựng cho những thay đổi trên một dự án cụ thể trong cây Git của tôi?
Câu trả lời:
Plugin Git có một tùy chọn (vùng bị loại trừ) để sử dụng các regex để xác định xem có bỏ qua việc xây dựng hay không dựa trên việc các tệp trong cam kết có khớp với regex của vùng bị loại trừ hay không.
Thật không may, plugin Git cổ phiếu không có tính năng "khu vực được bao gồm" tại thời điểm này (1.15). Tuy nhiên, ai đó đã đăng các bản vá trên GitHub hoạt động trên Jenkins và Hudson triển khai tính năng bạn muốn.
Nó là một công việc nhỏ để xây dựng, nhưng nó hoạt động như quảng cáo và cực kỳ hữu ích vì một trong những cây Git của tôi có nhiều dự án độc lập.
https://github.com/jenkinsci/git-plugin/pull/49
Cập nhật: Plugin Git (1.16) hiện có tính năng khu vực 'bao gồm'.
Ignored commit c6e2b1dca0d1885: No paths matched included region whitelist
. Có manh mối nào không? Thêm chi tiết tại đây: stackoverflow.com/questions/47439042/…
Về cơ bản, bạn cần hai công việc. Một để kiểm tra xem các tệp đã thay đổi hay chưa và một để thực hiện việc xây dựng thực tế:
Công việc số 1
Điều này sẽ được kích hoạt khi có những thay đổi trong kho lưu trữ Git của bạn. Sau đó, nó kiểm tra xem đường dẫn bạn chỉ định ("src" ở đây) có thay đổi hay không và sau đó sử dụng CLI của Jenkins để kích hoạt công việc thứ hai.
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
Công việc số 2
Định cấu hình công việc này để nhận tham số GIT_REVISION như vậy, để đảm bảo rằng bạn đang tạo chính xác bản sửa đổi mà công việc đầu tiên đã chọn để tạo.
$? || exit 0
... test $? -eq 0 || exit 0
có thể?
Nếu bạn đang sử dụng một cú pháp khai báo của Jenkinsfile để mô tả đường ống tòa nhà của bạn, bạn có thể sử dụng changeset điều kiện để thực hiện giai đoạn giới hạn chỉ với trường hợp khi các tập tin cụ thể được thay đổi. Đây hiện là một tính năng tiêu chuẩn của Jenkins và không yêu cầu bất kỳ cấu hình / phần mềm bổ sung nào.
stages {
stage('Nginx') {
when { changeset "nginx/*"}
steps {
sh "make build-nginx"
sh "make start-nginx"
}
}
}
Bạn có thể kết hợp nhiều điều kiện bằng cách sử dụng anyOf
hoặc allOf
từ khóa cho hành vi HOẶC hoặc VÀ cho phù hợp:
when {
anyOf {
changeset "nginx/**"
changeset "fluent-bit/**"
}
}
steps {
sh "make build-nginx"
sh "make start-nginx"
}
Mặc dù điều này không ảnh hưởng đến các công việc đơn lẻ, nhưng bạn có thể sử dụng tập lệnh này để bỏ qua các bước nhất định nếu bản cam kết mới nhất không có bất kỳ thay đổi nào:
/*
* 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/
thư mục.) Nếu bạn có thể khắc phục điều này, tôi rất thích một thay đổi được đề xuất !
Bạn có thể sử dụng Generic Webhook Trigger Plugin cho việc này.
Với một biến like changed_files
và biểu thức $.commits[*].['modified','added','removed'][*]
.
Bạn có thể có một văn bản bộ lọc như $changed_files
và bộ lọc regexp như "folder/subfolder/[^"]+?"
nếu folder/subfolder
là thư mục sẽ kích hoạt các bản dựng.
Tôi đã trả lời câu hỏi này trong một bài đăng khác:
Cách lấy danh sách các tệp đã thay đổi kể từ lần xây dựng cuối cùng trong 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;
Bạn có thể thêm séc trực tiếp vào đầu trình bao thực thi của công việc và nó sẽ làm exit 0
như vậy nếu không có thay đổi nào được phát hiện ... Do đó, bạn luôn có thể thăm dò ý kiến cấp cao nhất về đăng ký để kích hoạt bản dựng.
Tôi đã viết tập lệnh này để bỏ qua hoặc thực hiện kiểm tra nếu có thay đổi:
#!/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 "$@"
Vì vậy, bạn có thể làm điều gì đó như:
./scripts/git-run-if-changed.sh cmd vendor go.mod go.sum fixtures/ tools/ -- go test