फ़ाइलों के विशेष सेट पर परिवर्तन होने पर ही बिल्ड को ट्रिगर कैसे करें


87

मैं जेनकिन्स / हडसन को अपने गिट पेड़ में किसी विशेष परियोजना पर बदलाव के लिए एक निर्माण को ट्रिगर करने के लिए कैसे कहूं?

जवाबों:


65

Git plugin के पास regexes का उपयोग करने के लिए एक विकल्प (बहिष्कृत क्षेत्र) है, यह निर्धारित करने के लिए कि क्या प्रतिबद्ध क्षेत्र की फ़ाइलों को छोड़कर क्षेत्र regex से मेल खाता है।

दुर्भाग्य से, स्टॉक गिट प्लगइन में इस समय (1.15) "शामिल क्षेत्र" सुविधा नहीं है। हालांकि, किसी ने GitHub पर पैच पोस्ट किए जो जेनकिंस और हडसन पर काम करते हैं जो आपके इच्छित फीचर को लागू करते हैं।

यह निर्माण करने के लिए एक छोटा सा काम है, लेकिन यह विज्ञापित के रूप में काम करता है और बेहद उपयोगी रहा है क्योंकि मेरे एक गिट के पेड़ में कई स्वतंत्र परियोजनाएं हैं।

https://github.com/jenkinsci/git-plugin/pull/49

अद्यतन: Git प्लगइन (1.16) में अब 'शामिल' क्षेत्र सुविधा है।


5
1.1.16 शामिल सुविधा के लिए सही संस्करण संख्या है। (कोई 1.16 नहीं है)
डैन कार्टर

मैं इसे काम नहीं कर सकता, मेरे पास कई मॉड्यूल्स (डोमेन, कॉमन, एपीआई, डेस्कटॉप_एप्प ...) के साथ एक रिपॉजिटरी है। मैं उदाहरण के लिए डेस्कटॉप_एप्प के लिए एक बिल्ड ट्रिगर चाहता हूं, मैंने "शामिल क्षेत्रों" प्रोडक्शन_प्प / * पर रखा। मैंने कई संयोजनों की कोशिश की जैसे ./desktop_app यहां तक ​​कि पूर्ण पथ। एंडी हमेशा मिला Ignored commit c6e2b1dca0d1885: No paths matched included region whitelist। कोई सुराग? यहाँ अधिक जानकारी: stackoverflow.com/questions/47439042/…
FranAguiar

38

मूल रूप से, आपको दो नौकरियों की आवश्यकता है। एक यह जाँचने के लिए कि क्या फाइलें बदल गई हैं और एक वास्तविक निर्माण करने के लिए:

नौकरी # 1

यह आपके गिट रिपॉजिटरी में बदलाव पर शुरू किया जाना चाहिए। यह तब परीक्षण करता है कि आप जिस पथ को निर्दिष्ट करते हैं ("src" यहां) में परिवर्तन है और फिर दूसरी नौकरी को ट्रिगर करने के लिए जेनकिन्स सीएलआई का उपयोग करता है ।

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

एक पैरामीटर GIT_REVISION लेने के लिए इस नौकरी को कॉन्फ़िगर करें, यह सुनिश्चित करने के लिए कि आप बिलकुल संशोधन का निर्माण कर रहे हैं जिसे पहले नौकरी ने चुना था।

पैरामीटर निर्मित स्ट्रिंग पैरामीटर परिमित निर्मित Git चेकआउट


6
यदि अंतिम निर्माण के बाद से दो या दो से अधिक बार हुआ तो क्या होगा? मुझे लगता है कि आप src में परिवर्तनों को याद कर सकते हैं क्योंकि आप केवल HEAD प्रतिबद्ध की जांच कर रहे हैं।
एडम मोंसेन

@AdamMonsen राइट लेकिन आप उपरोक्त स्क्रिप्ट को जिस भी स्थिति / स्थिति के खिलाफ परीक्षण करना चाहते हैं, उसके लिए आसानी से अनुकूलित कर सकते हैं .. उदाहरण के लिए HEAD के खिलाफ अलग नहीं है, लेकिन स्क्रिप्ट चलने पर पिछली बार HEAD क्या था।
पेरिटस

वहाँ कुछ याद आ रही है $? || exit 0... test $? -eq 0 || exit 0शायद?
मारक २

31

यदि आप एक घोषणात्मक वाक्यविन्यास का उपयोग कर रहे हैं Jenkinsfile अपने भवन पाइपलाइन का वर्णन करने के, आप उपयोग कर सकते हैं changeset केवल मामले को सीमा मंच निष्पादन के लिए शर्त है जब विशिष्ट फ़ाइलों को परिवर्तित कर रहे हैं। यह अब जेनकिंस की एक मानक विशेषता है और इसके लिए किसी अतिरिक्त विन्यास / सॉफ्टवेयर की आवश्यकता नहीं है।

stages {
    stage('Nginx') {
        when { changeset "nginx/*"}
        steps {
            sh "make build-nginx"
            sh "make start-nginx"
        }
    }
}

आप एक से अधिक शर्तों का उपयोग गठजोड़ कर सकते हैं anyOfया allOfके लिए कीवर्ड या या और व्यवहार के हिसाब से:

when {
    anyOf {
        changeset "nginx/**"
        changeset "fluent-bit/**"
    }
}
steps {
    sh "make build-nginx"
    sh "make start-nginx"
}

1
ध्यान रखें कि यह कुछ मामलों के लिए काम नहीं करता है। अधिक जानकारी के लिए issues.jenkins-ci.org/browse/JENKINS-26354 देखें।
तमेरला

7

यदि यह एकल नौकरियों को प्रभावित नहीं करता है, तो आप इस स्क्रिप्ट का उपयोग कुछ चरणों को अनदेखा करने के लिए कर सकते हैं यदि नवीनतम प्रतिबद्ध में कोई परिवर्तन नहीं है:

/*
 * 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
}

1
अगर यह आपके लिए काम करता है तो @Karl कोड को ठीक करने के लिए स्वतंत्र महसूस करें। इस कोड को लागू करते समय मेरे पास एक ही मुद्दा था (बिल्ड विफलताओं पर, यह इस प्रतिबद्धता को वापस नहीं लेगा, अगर निरपेक्ष नवीनतम प्रतिबद्ध ने api/फ़ोल्डर को भी नहीं बदला है ।) यदि आप इसे ठीक कर सकते हैं, तो मैं एक सुझाया गया परिवर्तन पसंद करूंगा। !
Goodbye StackExchange

2

यदि फ़ाइलों को चुनने का तर्क तुच्छ नहीं है, तो मैं प्रत्येक बदलाव पर स्क्रिप्ट निष्पादन को ट्रिगर करूंगा और फिर यह जांचने के लिए एक स्क्रिप्ट लिखूंगा कि क्या वास्तव में एक बिल्ड की आवश्यकता है, तो एक बिल्ड ट्रिगर करना यदि यह है।


1

इसके लिए आप Generic Webhook Trigger Plugin का उपयोग कर सकते हैं ।

एक चर की तरह changed_filesऔर अभिव्यक्ति के साथ $.commits[*].['modified','added','removed'][*]

आपके पास एक फ़िल्टर पाठ हो सकता है $changed_filesऔर फ़िल्टर regexp जैसे "folder/subfolder/[^"]+?"कि folder/subfolderवह फ़ोल्डर है जिसमें बिल्ड ट्रिगर होना चाहिए।


मैं ऐसा करने की कोशिश कर रहा हूं लेकिन मैं थोड़ा सा खो गया हूं। बदली हुई फ़ाइल का पथ जेन्किन्स में कैसे भेजें? क्या आप थोड़ा और अधिक समझा सकते हैं? परिवर्तनशील_फाइल्स को कहां रखा जाए?
सूद

आपके द्वारा उपयोग की जा रही Git सेवा में आपको एक webhook कॉन्फ़िगर करने की आवश्यकता है। अगर यह GitHub है तो यहाँ एक उदाहरण है: github.com/jenkinsci/generic-webhook-trigger-plugin/blob/master/…
टॉमस बेजर्रे

वास्तव में जैसा कि मैं Bitbucket का उपयोग कर रहा हूं, मैंने महसूस किया कि Changed_files प्रविष्टि bibucket (Ref: confluence.atlassian.com/bitbucket/… ) में पुश ईवेंट के पेलोड में उपलब्ध नहीं है, इसलिए मुझे यकीन नहीं है कि मैं यह कैसे कर सकता हूं। मुझे लगता है कि मैं प्रतिबद्ध संदेश पर भरोसा करूंगा। धन्यवाद
Souad

1

मैंने एक और पोस्ट में इस सवाल का जवाब दिया:

जेनकिंस / हडसन में अंतिम निर्माण के बाद से परिवर्तित फ़ाइलों की सूची कैसे प्राप्त करें

#!/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;

आप चेक को सीधे नौकरी के निष्पादन शेल के शीर्ष पर जोड़ सकते हैं, और exit 0यदि कोई परिवर्तन नहीं पाए जाते हैं तो यह होगा ... इसलिए, आप चेक-इन के लिए एक निर्माण को ट्रिगर करने के लिए हमेशा शीर्ष स्तर पर चुनाव कर सकते हैं।


1

अगर परिवर्तन हो तो परीक्षण को छोड़ या निष्पादित करने के लिए मैंने यह स्क्रिप्ट लिखी है:

#!/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 "$@"

तो आप कुछ ऐसा कर सकते हैं:

./scripts/git-run-if-changed.sh cmd vendor go.mod go.sum fixtures/ tools/ -- go test

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.