इस पेज में आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम और उनके पीछे के सिद्धांत के बारे में बताया गया है बनाना. Basel एक आर्टफ़ैक्ट-आधारित बिल्ड सिस्टम है. टास्क के हिसाब से बिल्ड सिस्टम, स्क्रिप्ट बनाने के ऊपर अच्छा चरण रखते हैं, और ये स्क्रिप्ट को बहुत अच्छी तरह से अलग-अलग इंजीनियरों को उनके टास्क तय करने की अनुमति दी.
आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम में, सिस्टम की ओर से तय किए गए कुछ ही टास्क होते हैं
जिसे इंजीनियर सीमित तरीके से कॉन्फ़िगर कर सकते हैं. इंजीनियर अब भी सिस्टम को बताते हैं कि क्या बनाना है, लेकिन बिल्ड सिस्टम यह तय करता है कि इसे कैसे बनाना है. जैसा कि
टास्क पर आधारित बिल्ड सिस्टम, आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम, जैसे कि Basel का वर्शन
बिल्ड-फ़ाइलें होती हैं, लेकिन इन बिल्डफ़ाइलों का कॉन्टेंट बहुत अलग होता है. ट्यूरिंग-कंप्लीट स्क्रिप्टिंग भाषा में, आउटपुट बनाने का तरीका बताने वाले निर्देशों के सेट के बजाय, Bazel में मौजूद बिल्डफ़ाइलें एक एलान वाली मेनिफ़ेस्ट होती हैं. इनमें, बिल्ड करने के लिए आर्टफ़ैक्ट के सेट, उनकी डिपेंडेंसी, और विकल्पों के सीमित सेट के बारे में बताया जाता है. इन विकल्पों से, आर्टफ़ैक्ट के बिल्ड होने के तरीके पर असर पड़ता है. जब इंजीनियर कमांड-लाइन पर bazel
को चलाते हैं, तो वे क्या बनाएं, यह तय करते हैं. साथ ही, संकलन के चरणों (कैसे) को कॉन्फ़िगर करने, चलाने, और शेड्यूल करने की ज़िम्मेदारी, Bazel की होती है. क्योंकि बिल्ड सिस्टम के पास अब
चलाने के लिए उपलब्ध टूल की मदद से, यह इस बात की बहुत बड़ी गारंटी दे सकता है कि यह
और उनके सही होने की गारंटी देते हुए भी बेहतर तरीके से काम कर सकते हैं.
फ़ंक्शनल पर्सपेक्टिव
आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम और फ़ंक्शनल प्रोग्रामिंग के बीच तुलना करना आसान है. Java, C, और Python जैसी प्रोग्रामिंग की पारंपरिक भाषाओं में, एक के बाद एक निर्देशों को लागू करने के लिए सूचियां तय की जाती हैं. ठीक उसी तरह जैसे टास्क पर आधारित बिल्ड सिस्टम, प्रोग्रामर को लागू करने के लिए चरणों की एक सीरीज़ तय करने की सुविधा देते हैं. फ़ंक्शनल प्रोग्रामिंग लैंग्वेज (जैसे, Haskell और ML). इन्हें काफ़ी हद तक गणित के समीकरणों की तरह बनाया जाता है. फ़ंक्शनल लैंग्वेज में, प्रोग्रामर कैलकुलेशन करने का तरीका बताता है. हालांकि, वह यह नहीं बताता कि कैलकुलेशन कब और कैसे किया जाएगा. यह जानकारी कंपाइलर को देनी होती है.
इससे पता चलता है कि आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम में मेनिफ़ेस्ट का एलान किया जा सकता है और सिस्टम को बिल्ड को एक्ज़ीक्यूट करने का तरीका पता लगाने देता है. बहुत सारे सवाल एक ही जगह पर फ़ंक्शनल प्रोग्रामिंग का इस्तेमाल करके, साफ़ तौर पर बताया जा सकता है. हालांकि, इससे जिन लोगों को फ़ायदा होता है से बहुत अलग है: भाषा अक्सर इस तरह के प्रोग्राम और उनके सही होने की मज़बूत गारंटी देने के लिए किया जा सकता है. कर सकती है. फ़ंक्शनल प्रोग्रामिंग का इस्तेमाल करके, ऐसी समस्याओं को आसानी से हल किया जा सकता है जिनमें नियमों या फ़ंक्शन की सीरीज़ का इस्तेमाल करके, डेटा के एक हिस्से को दूसरे हिस्से में बदलना होता है. और यही बिल्कुल वैसा ही है जैसा कि एक बिल्ड सिस्टम होता है: पूरा सिस्टम, गणितीय फ़ंक्शन के तौर पर काम करता है. यह सोर्स फ़ाइलों (और कंपाइलर जैसे टूल) को इनपुट के तौर पर लेता है और आउटपुट के तौर पर बाइनरी बनाता है. इसलिए, इसमें कोई हैरानी नहीं कि फ़ंक्शनल प्रोग्रामिंग के सिद्धांतों के आधार पर, बिल्ड सिस्टम को बेहतर बनाया जा सकता है.
आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम को समझना
Google का बिल्ड सिस्टम, Blaze, आर्टफ़ैक्ट पर आधारित पहला बिल्ड सिस्टम था. Bazel, Blaze का ओपन-सोर्स वर्शन है.
बेज़ेल में बिल्डफ़ाइल (इसे आम तौर पर BUILD
कहा जाता है) कैसी दिखती है:
java_binary(
name = "MyBinary",
srcs = ["MyBinary.java"],
deps = [
":mylib",
],
)
java_library(
name = "mylib",
srcs = ["MyLibrary.java", "MyHelper.java"],
visibility = ["//java/com/example/myproduct:__subpackages__"],
deps = [
"//java/com/example/common",
"//java/com/example/myproduct/otherlib",
],
)
Bazel में, BUILD
फ़ाइलें टारगेट तय करती हैं—यहां दो तरह के टारगेट होते हैं—java_binary
और java_library
. हर टारगेट एक आर्टफ़ैक्ट से जुड़ा होता है, जो
सिस्टम से बनाया जा सकता है: बाइनरी टारगेट, ऐसे बाइनरी बनाते हैं जिन्हें
किया जा सकता है और लाइब्रेरी टारगेट ऐसी लाइब्रेरी बनाते हैं जिनका इस्तेमाल
बाइनरी या अन्य लाइब्रेरी का इस्तेमाल करना चाहिए. हर टारगेट में:
name
: कमांड लाइन पर और दूसरे में टारगेट का रेफ़रंस कैसे दिया जाता है टारगेटsrcs
: टारगेट के लिए आर्टफ़ैक्ट बनाने के लिए, कंपाइल की जाने वाली सोर्स फ़ाइलेंdeps
: ऐसे अन्य टारगेट जिन्हें इस टारगेट से पहले बनाया जाना चाहिए और उससे लिंक किया जाना चाहिए
डिपेंडेंसी या तो एक ही पैकेज में हो सकती हैं (जैसे कि MyBinary
निर्भरता :mylib
पर निर्भर है) या इसी सोर्स हैरारकी में किसी दूसरे पैकेज पर
(जैसे, //java/com/example/common
पर mylib
की डिपेंडेंसी).
टास्क पर आधारित बिल्ड सिस्टम की तरह ही, Bazel के कमांड-लाइन टूल का इस्तेमाल करके बिल्ड किए जाते हैं. MyBinary
टारगेट बनाने के लिए, bazel build :MyBinary
चलाएं. इस तारीख के बाद
किसी क्लीन रिपॉज़िटरी (डेटा स्टोर करने की जगह) में पहली बार उस कमांड को डालकर, Basel:
- आर्टफ़ैक्ट के बीच डिपेंडेंसी का ग्राफ़ बनाने के लिए, वर्कस्पेस में मौजूद हर
BUILD
फ़ाइल को पार्स करता है. MyBinary
की ट्रांज़िटिव डिपेंडेंसी का पता लगाने के लिए ग्राफ़ का इस्तेमाल करता है; वह हर टारगेट जोMyBinary
पर निर्भर करता है और उन सभी टारगेट के लिए पर निर्भर करता है.- इनमें से हर डिपेंडेंसी को क्रम में बनाता है. Bazel, हर उस टारगेट को बनाना शुरू करता है जिसमें कोई दूसरी डिपेंडेंसी नहीं होती. साथ ही, यह ट्रैक करता है कि हर टारगेट के लिए किन डिपेंडेंसी को अब भी बनाया जाना है. किसी टारगेट की सभी डिपेंडेंसी बन जाने के बाद, Bazel उस टारगेट को बनाना शुरू कर देता है. यह प्रोसेस तब तक जारी रहती है, जब तक
MyBinary
की सभी ट्रांज़िशन डिपेंडेंसी बन नहीं जातीं. MyBinary
को बिल्ड करके, आखिरी एक्सीक्यूटेबल बाइनरी बनाई जाती है. यह बाइनरी, तीसरे चरण में बनाई गई सभी डिपेंडेंसी को लिंक करती है.
बुनियादी तौर पर, ऐसा नहीं लगता कि यहां जो हो रहा है वह टास्क पर आधारित बिल्ड सिस्टम का इस्तेमाल करने पर होने वाली प्रोसेस से काफ़ी अलग है. सच में, आखिरी नतीजा एक ही बाइनरी है और इसे बनाने की प्रोसेस डिपेंडेंसी खोजने के लिए कई चरणों का विश्लेषण किया गया है. इसके बाद, क्रम में रखा है. हालांकि, इनमें काफ़ी अंतर है. पहला फ़ायदा तीसरे चरण में दिखता है: Bazel को पता है कि हर टारगेट सिर्फ़ एक Java लाइब्रेरी बनाता है. इसलिए, उसे उपयोगकर्ता की तय की गई किसी भी स्क्रिप्ट के बजाय, Java कंपाइलर को चलाना होता है. इसलिए, यह पता चलता है कि इन चरणों को एक साथ चलाना सुरक्षित है. इससे इमारत की परफ़ॉर्मेंस में बहुत ज़्यादा सुधार हो सकता है मल्टीकोर मशीन को एक-एक करके टारगेट करता है और ऐसा सिर्फ़ इसलिए मुमकिन है, क्योंकि आर्टफ़ैक्ट पर आधारित तरीके की मदद से, बिल्ड सिस्टम को उसके काम करने की ज़िम्मेदारी खुद ही मिल जाती है रणनीति बनाई, ताकि यह समानता को लेकर गारंटी दे सके.
हालांकि, इसके फ़ायदे पैरलल प्रोसेसिंग से भी ज़्यादा हैं. इस तरीके से हमें एक और फ़ायदा मिलता है. यह तब पता चलता है, जब डेवलपर कोई बदलाव किए बिना bazel
build :MyBinary
को दूसरी बार टाइप करता है: Bazel एक सेकंड से भी कम समय में बंद हो जाता है और यह मैसेज दिखाता है कि टारगेट अप-टू-डेट है. ऐसा फ़ंक्शनल प्रोग्रामिंग पैराडाइम की वजह से होता है, जिसके बारे में हमने पहले बात की थी—Bazel को पता है कि हर टारगेट सिर्फ़ Java कंपाइलर को चलाने का नतीजा है. साथ ही, यह भी पता है कि Java कंपाइलर का आउटपुट सिर्फ़ उसके इनपुट पर निर्भर करता है. इसलिए, जब तक इनपुट में बदलाव नहीं होता, तब तक आउटपुट का फिर से इस्तेमाल किया जा सकता है.
यह विश्लेषण हर लेवल पर काम करता है. अगर MyBinary.java
में बदलाव होता है, तो Bazel को MyBinary
को फिर से बनाना होगा, लेकिन mylib
का फिर से इस्तेमाल करना होगा. अगर //java/com/example/common
के लिए कोई सोर्स फ़ाइल बदलती है, तो Bazel उस लाइब्रेरी, mylib
, और MyBinary
को फिर से बनाता है. हालांकि, //java/com/example/myproduct/otherlib
का फिर से इस्तेमाल किया जाता है.
बेज़ल हर कदम पर चलाए जाने वाले टूल की खूबियों के बारे में जानते हैं,
यह हर बार आर्टफ़ैक्ट के कम से कम सेट को फिर से बना सकता है.
यह गारंटी देना कि इससे पुराने सामान नहीं बनेंगे.
बिल्ड प्रोसेस को टास्क के बजाय आर्टफ़ैक्ट के तौर पर दिखाना आसान होता है लेकिन शक्तिशाली. प्रोग्रामर के सामने आने वाले लचीलेपन को कम करके, बिल्ड तो सिस्टम इस बारे में ज़्यादा जान सकता है कि बिल्ड के हर चरण पर क्या किया जा रहा है. यह इस जानकारी का इस्तेमाल करके, बिल्ड प्रोसेस को पैरलल बनाकर और उनके आउटपुट का फिर से इस्तेमाल करके, बिल्ड को ज़्यादा असरदार बना सकता है. हालांकि, यह तो सिर्फ़ पहला कदम है और ये सब, समानता और फिर से इस्तेमाल किए जाने वाले ब्लॉक, किसी भी ऐसी नीति का आधार बने बिल्ड सिस्टम इस्तेमाल किया जा सकता है.
बेज़ेल की अन्य शानदार ट्रिक
आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम, टास्क पर आधारित बिल्ड सिस्टम में मौजूद, पैरलल प्रोसेस और फिर से इस्तेमाल करने से जुड़ी समस्याओं को हल करते हैं. हालांकि, अब भी कुछ जिन्हें हम हल नहीं कर पाए हैं. Bazel में इनमें से हर समस्या को हल करने के बेहतर तरीके हैं. आगे बढ़ने से पहले, इनके बारे में चर्चा करना ज़रूरी है.
डिपेंडेंसी के तौर पर टूल
हमने पहले एक समस्या का सामना किया था. यह समस्या, इंस्टॉल किए गए टूल पर निर्भर करती थी वह हमारे सिस्टम पर बिल्ड को फिर से जनरेट कर सकता है. इस प्रोसेस की वजह से, टूल के अलग-अलग वर्शन या जगहों से जुड़ा हो. यह समस्या तब और भी मुश्किल हो जाती है, जब आपके प्रोजेक्ट में ऐसी भाषाओं का इस्तेमाल किया जाता है जिन्हें अलग-अलग प्लैटफ़ॉर्म के लिए अलग-अलग टूल की ज़रूरत होती है. जैसे, Windows बनाम Linux. साथ ही, एक ही काम करने के लिए, उन सभी प्लैटफ़ॉर्म को टूल के अलग-अलग सेट की ज़रूरत होती है.
Basel ने टूल को डिपेंडेंसी के तौर पर इस्तेमाल करके, इस समस्या के पहले हिस्से को हल किया
हर टारगेट पर लागू होती है. फ़ाइल फ़ोल्डर में हर java_library
, साफ़ तौर पर Java पर निर्भर करता है
कंपाइलर, जो किसी जाने-माने कंपाइलर पर डिफ़ॉल्ट रूप से लागू होता है. जब भी Basel ने
java_library
, यह जांच करता है कि बताया गया कंपाइलर उपलब्ध है या नहीं
किसी ज्ञात स्थान पर. किसी भी दूसरी डिपेंडेंसी की तरह, अगर Java कंपाइलर में बदलाव होता है, तो उस पर निर्भर हर आर्टफ़ैक्ट को फिर से बनाया जाता है.
Bazel, बिल्ड कॉन्फ़िगरेशन सेट करके, समस्या के दूसरे हिस्से, प्लैटफ़ॉर्म के हिसाब से काम करने की सुविधा को हल करता है. इसके बजाय टारगेट के लिए सेट अप करना मुश्किल होता है. ये कॉन्फ़िगरेशन के टाइप पर निर्भर करते हैं:
- होस्ट कॉन्फ़िगरेशन: बिल्ड के दौरान काम करने वाले टूल बनाना
- टारगेट कॉन्फ़िगरेशन: वह बाइनरी बनाना जिसका आपने अनुरोध किया था
बिल्ड सिस्टम को बेहतर बनाना
Bazel में, कई लोकप्रिय प्रोग्रामिंग भाषाओं के लिए टारगेट पहले से मौजूद होते हैं. हालांकि, इंजीनियर हमेशा ज़्यादा करना चाहते हैं. टास्क पर आधारित सिस्टम का एक फ़ायदा यह है कि वे किसी भी तरह की बिल्ड प्रोसेस के साथ काम करने में आसान होते हैं. इसलिए, आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम में इस सुविधा को न छोड़ें. अच्छी बात यह है कि Bazel में कस्टम नियम जोड़कर, काम करने वाले टारगेट टाइप को बढ़ाया जा सकता है.
बेज़ल में कोई नियम तय करने के लिए, नियम का लेखक ऐसे इनपुट का एलान करता है जो नियम
की ज़रूरत होती है (BUILD
फ़ाइल में पास की गई विशेषताओं के रूप में) और
आउटपुट का सेट होता है, जिसे नियम के तहत जनरेट किया जाता है. लेखक यह भी तय करता है कि उस नियम से कौनसी कार्रवाइयां जनरेट होंगी. हर कार्रवाई के इनपुट और आउटपुट की जानकारी होती है. साथ ही, वह किसी खास एक्सीक्यूटेबल को चलाती है या किसी फ़ाइल में कोई खास स्ट्रिंग लिखती है. साथ ही, अपने इनपुट और आउटपुट की मदद से, अन्य कार्रवाइयों से कनेक्ट की जा सकती है. इसका मतलब है कि कार्रवाइयां, बिल्ड सिस्टम में सबसे निचले लेवल की कंपोज की जा सकने वाली यूनिट होती हैं. जब तक कोई कार्रवाई सिर्फ़ अपने एलान किए गए इनपुट और आउटपुट का इस्तेमाल करती है, तब तक वह अपनी मर्ज़ी से कुछ भी कर सकती है. साथ ही, Bazel कार्रवाइयों को शेड्यूल करने और उनके नतीजों को ज़रूरत के हिसाब से कैश मेमोरी में सेव करने का काम करती है.
यह सिस्टम पूरी तरह से सुरक्षित नहीं है, क्योंकि किसी ऐक्शन डेवलपर को अपनी ऐक्शन के हिस्से के तौर पर, नॉन-डेटरमिनिस्टिक प्रोसेस को शामिल करने से रोकने का कोई तरीका नहीं है. हालांकि, आम तौर पर ऐसा बहुत कम होता है. साथ ही, गलत इस्तेमाल की संभावनाओं को कार्रवाई के लेवल तक ले जाने से, गड़बड़ियों की संभावनाएं बहुत कम हो जाती हैं. कई सामान्य भाषाओं और टूल के लिए नियम, ऑनलाइन उपलब्ध हैं. ज़्यादातर प्रोजेक्ट के लिए, कभी भी अपने नियम तय करने की ज़रूरत नहीं पड़ती. जिन लोगों के पास यह जानकारी है उनके लिए भी, नियमों की परिभाषाओं को सिर्फ़ एक जगह, यानी रिपॉज़िटरी में तय करना ज़रूरी है. इसका मतलब है कि ज़्यादातर इंजीनियर उन नियमों का इस्तेमाल कर पाएंगे और उन्हें लागू करने के बारे में चिंता करने की ज़रूरत नहीं होगी.
एनवायरमेंट को अलग करना
कार्रवाइयां करने से ऐसा लगता है कि उनमें वही समस्याएं हो सकती हैं जो अन्य टास्क में होती हैं सिस्टम—क्या अब भी ऐसी कार्रवाइयां लिखना मुमकिन नहीं है जो दोनों एक ही और एक-दूसरे से टकराव होता है? असल में, Bazel सैंडबॉक्सिंग का इस्तेमाल करके, इन संघर्षों को रोकता है. समर्थित पर हर कार्रवाई को फ़ाइल सिस्टम के ज़रिए अलग-अलग करके, हर दूसरी कार्रवाई से अलग कर दिया जाता है सैंडबॉक्स. असल में, हर कार्रवाई फ़ाइल सिस्टम का सिर्फ़ सीमित व्यू देख सकती है. इसमें, ऐसे इनपुट शामिल होते हैं जिन्हें उसने एलान किया है और ऐसे आउटपुट जो उसने जनरेट किए हैं. इसे Linux पर LXC जैसे सिस्टम से लागू किया जाता है. Docker की मदद से. इसका मतलब है कि कार्रवाइयां एक-दूसरे के साथ कभी भी संघर्ष नहीं कर सकतीं, क्योंकि वे ऐसी किसी भी फ़ाइल को नहीं पढ़ सकतीं जिसके बारे में उन्होंने एलान नहीं किया है. साथ ही, ऐसी किसी भी फ़ाइल को मिटा दिया जाएगा जिसे वे लिखती हैं, लेकिन जिसके बारे में एलान नहीं किया जाता. Baze, इसके ज़रिए बातचीत करने से रोकने के लिए सैंडबॉक्स का भी इस्तेमाल करते हैं नेटवर्क.
बाहरी डिपेंडेंसी को डिटरमिनिस्टिक बनाना
अब भी एक समस्या बाकी है: बिल्ड सिस्टम को अक्सर डाउनलोड करना पड़ता है
पर निर्भर करता है कि
उन्हें सीधे तौर पर तैयार किया जा रहा है. उदाहरण में, @com_google_common_guava_guava//jar
डिपेंडेंसी के ज़रिए इसे देखा जा सकता है. यह डिपेंडेंसी, Maven से JAR
फ़ाइल डाउनलोड करती है.
मौजूदा फ़ाइल फ़ोल्डर से बाहर की फ़ाइलों पर निर्भर रहना जोखिम भरा है. वे फ़ाइलें यह कर सकती थीं किसी भी समय बदला जा सकता है. ऐसा करने पर, बिल्ड सिस्टम को लगातार जांच करनी पड़ती है भले ही वे नए हों. अगर कोई रिमोट फ़ाइल बिना किसी बदलाव के बदल जाती है है, तो इसकी वजह से ऐसे बिल्ड भी हो सकते हैं जिन्हें दोहराया नहीं जा सकता—एक बिल्ड किसी का ध्यान न जाने की वजह से, किसी दिन काम कर सकता है और बिना किसी साफ़ वजह के अगले दिन फ़ेल हो सकता है डिपेंडेंसी में बदलाव हुआ है. आख़िर में, एक्सटर्नल डिपेंडेंसी, एक बहुत बड़ी सुरक्षा किसी तीसरे पक्ष के मालिकाना हक वाले कॉन्टेंट का जोखिम हो सकता है: अगर कोई हमलावर आपके खाते में घुसपैठ कर सकता है तो तीसरे पक्ष के सर्वर का इस्तेमाल कर रहे हैं, तो वे निर्भरता फ़ाइल को कुछ अपनी पसंद का डिज़ाइन बना सकते हैं. इससे उन्हें आपके बिल्ड पर पूरा कंट्रोल मिल सकता है पर्यावरण और उसके आउटपुट की जानकारी देता है.
मूल समस्या यह है कि हम चाहते हैं कि बिल्ड सिस्टम इन बातों के बारे में और सोर्स कंट्रोल में जाने की ज़रूरत नहीं है. डिपेंडेंसी अपडेट करना यह एक सोच-समझकर चुना जाने वाला विकल्प होना चाहिए, लेकिन यह फ़ैसला एक नहीं बल्कि अलग-अलग इंजीनियर द्वारा या स्वचालित रूप से सिस्टम. इसकी वजह यह है कि “Live at Head” मॉडल के साथ भी, हम चाहते हैं कि बिल्ड डिटरमिनिस्टिक हों. इसका मतलब है कि अगर पिछले हफ़्ते के किसी कमिट को चेक आउट किया जाता है, तो आपको अपनी डिपेंडेंसी अब की तरह नहीं, बल्कि उस समय की तरह दिखनी चाहिए.
Basel और कुछ दूसरे बिल्ड सिस्टम इस समस्या को हल करते हैं. इसके लिए, फ़ाइल फ़ोल्डर में मौजूद मेनिफ़ेस्ट फ़ाइल, जिसमें हर बाहरी फ़ाइल के लिए क्रिप्टोग्राफ़िक हैश मौजूद होता है पर निर्भर है. हैश, टैग को सटीक तरीके से दिखाने का एक छोटा तरीका है. सोर्स कंट्रोल में जाने के लिए, पूरी फ़ाइल की जांच नहीं की जाती. जब भी किसी वर्कस्पेस से किसी नई बाहरी डिपेंडेंसी का रेफ़रंस दिया जाता है, तो उस डिपेंडेंसी का हैश मैन्युअल तरीके से या अपने-आप मेनिफ़ेस्ट में जुड़ जाता है. जब बेज़ल बिल्ड में मौजूद है, तो यह कैश मेमोरी में सेव की गई डिपेंडेंसी के असल हैश की जांच उम्मीद के मुताबिक करता है हैश को मेनिफ़ेस्ट में तय किया गया है और हैश अलग होने पर ही फ़ाइल को फिर से डाउनलोड करता है.
अगर हम जिस आर्टफ़ैक्ट को डाउनलोड करते हैं उसका हैश, मेनिफ़ेस्ट के साथ अटैच की गई फ़ाइलें तब तक काम नहीं करती हैं, जब तक मेनिफ़ेस्ट में हैश को अपडेट नहीं किया जाता. यह स्वचालित रूप से किया जा सकता है, लेकिन उस परिवर्तन को स्वीकृत होना चाहिए और उसमें चेक इन किया जाना चाहिए बिल्ड के लिए नई डिपेंडेंसी स्वीकार करने से पहले सोर्स कंट्रोल. इसका मतलब है कि किसी डिपेंडेंसी के अपडेट होने का रिकॉर्ड हमेशा मौजूद होता है. साथ ही, किसी बाहरी डिपेंडेंसी में बदलाव करने के लिए, वर्कस्पेस सोर्स में भी बदलाव करना ज़रूरी होता है. इसका यह भी मतलब है कि सोर्स कोड के पुराने वर्शन को चेक आउट करते समय, बिल्ड में उन ही डिपेंडेंसी का इस्तेमाल किया जाएगा जिनका इस्तेमाल उस वर्शन को चेक इन करते समय किया गया था. अगर वे डिपेंडेंसी अब उपलब्ध नहीं हैं, तो बिल्ड नहीं हो पाएगा.
हालांकि, अगर कोई रिमोट सर्वर उपलब्ध नहीं होता है या वह गलत डेटा दिखाना शुरू कर देता है, तो भी समस्या हो सकती है. अगर आपके पास उस डिपेंडेंसी की कोई दूसरी कॉपी उपलब्ध नहीं है, तो इससे आपके सभी बिल्ड काम करना बंद कर सकते हैं. इस समस्या से बचने के लिए, हमारा सुझाव है कि किसी भी मुश्किल प्रोजेक्ट के लिए, उसकी सभी डिपेंडेंसी को उन सर्वर या सेवाओं पर मिरर करें जिन पर आपका भरोसा है और जिन्हें आप कंट्रोल कर सकते हैं. नहीं तो, आप आपके बिल्ड सिस्टम के लिए हमेशा कोई तीसरा पक्ष कंट्रोल करता है उपलब्धता, भले ही चेक-इन हैश अपनी सुरक्षा की गारंटी देते हों.