आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम

किसी समस्या की शिकायत करें सोर्स देखें Nightly · 7.4 .

इस पेज पर, आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम और उन्हें बनाने के पीछे की सोच के बारे में बताया गया है. Bazel, आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम है. हालांकि, टास्क पर आधारित बिल्ड सिस्टम, स्क्रिप्ट बनाने से बेहतर हैं, लेकिन ये अलग-अलग इंजीनियर को उनके टास्क तय करने की अनुमति देते हैं, जिससे उन्हें बहुत ज़्यादा सुविधाएं मिलती हैं.

आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम में, सिस्टम के तय किए गए कुछ टास्क होते हैं जिन्हें इंजीनियर सीमित तौर पर कॉन्फ़िगर कर सकते हैं. इंजीनियर अब भी सिस्टम को बताते हैं कि क्या बनाना है, लेकिन बिल्ड सिस्टम यह तय करता है कि इसे कैसे बनाना है. टास्क पर आधारित बिल्ड सिस्टम की तरह ही, Basel जैसे आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम में भी बिल्ड फ़ाइलें होंगी. हालांकि, इन बिल्ड फ़ाइलों का कॉन्टेंट काफ़ी अलग होगा. ट्यूरिंग-कंप्लीट स्क्रिप्टिंग भाषा में, आउटपुट बनाने का तरीका बताने वाले निर्देशों के सेट के बजाय, Bazel में मौजूद बिल्डफ़ाइलें एक एलान वाली मेनिफ़ेस्ट होती हैं. इनमें, बिल्ड करने के लिए आर्टफ़ैक्ट के सेट, उनकी डिपेंडेंसी, और विकल्पों के सीमित सेट के बारे में बताया जाता है. इन विकल्पों से, आर्टफ़ैक्ट के बिल्ड होने के तरीके पर असर पड़ता है. जब इंजीनियर bazel को कमांड लाइन पर चलाते हैं, तो वे बनाने के लिए टारगेट का एक सेट (नया) तय करते हैं. साथ ही, कंपाइलेशन चरणों (कैसे) को कॉन्फ़िगर करने, चलाने, और शेड्यूल करने के लिए बैज की ज़िम्मेदारी होती है. अब बिल्ड सिस्टम के पास यह तय करने का पूरा कंट्रोल है कि कौनसे टूल कब चलाए जाएं. इससे, बिल्ड सिस्टम को ज़्यादा बेहतर बनाने के साथ-साथ, सही होने की गारंटी भी मिलती है.

फ़ंक्शनल नज़रिया

आर्टफ़ैक्ट-आधारित बिल्ड सिस्टम और फ़ंक्शनल प्रोग्रामिंग के बीच तुलना करना आसान है. ट्रेडिशनल इंपेरेटिव प्रोग्रामिंग लैंग्वेज (जैसे, Java, C, और Python) एक के बाद एक लागू किए जाने वाले स्टेटमेंट की सूचियां तय करती है. उसी तरह, टास्क पर आधारित बिल्ड सिस्टम की मदद से प्रोग्रामर, लागू करने के लिए कई चरण तय कर सकते हैं. इसके उलट, फ़ंक्शनल प्रोग्रामिंग लैंग्वेज (जैसे, Haskell और ML) का स्ट्रक्चर, गणितीय समीकरणों की सीरीज़ की तरह होता है. फ़ंक्शनल भाषाओं में प्रोग्रामर, कंप्यूटेशन के बारे में बताता है. हालांकि, यह इस बात की जानकारी देता है कि कंपाइलर में यह कंप्यूटेशन कब और कैसे किया जाएगा.

यह आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम में मेनिफ़ेस्ट को एलान करने के आइडिया से मैप होता है और सिस्टम को बिल्ड को लागू करने का तरीका पता चलता है. फ़ंक्शनल प्रोग्रामिंग का इस्तेमाल करके, कई समस्याओं को आसानी से हल नहीं किया जा सकता. हालांकि, जिन समस्याओं को हल करने में यह भाषा काफ़ी मददगार होती है उनमें: भाषा, अक्सर ऐसे प्रोग्राम को आसानी से पैरलल कर सकती है और उनके सही होने की गारंटी दे सकती है. ऐसा, इंपरऐटिव भाषा में करना मुमकिन नहीं होता. फ़ंक्शनल प्रोग्रामिंग का इस्तेमाल करके, ऐसी समस्याओं को आसानी से हल किया जा सकता है जिनमें नियमों या फ़ंक्शन की सीरीज़ का इस्तेमाल करके, डेटा के एक हिस्से को दूसरे हिस्से में बदलना होता है. और यही बिल्कुल वैसा ही है जैसा कि एक बिल्ड सिस्टम होता है: पूरा सिस्टम, गणितीय फ़ंक्शन के तौर पर काम करता है. यह सोर्स फ़ाइलों (और कंपाइलर जैसे टूल) को इनपुट के तौर पर लेता है और आउटपुट के तौर पर बाइनरी बनाता है. इसलिए, इसमें कोई हैरानी नहीं कि फ़ंक्शनल प्रोग्रामिंग के सिद्धांतों के आधार पर, बिल्ड सिस्टम को बेहतर बनाया जा सकता है.

आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम को समझना

Google का बिल्ड सिस्टम, Blaze, आर्टफ़ैक्ट पर आधारित पहला बिल्ड सिस्टम था. Bazel, Blaze का ओपन-सोर्स वर्शन है.

Bazel में, बिल्डफ़ाइल (आम तौर पर इसका नाम 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 की डिपेंडेंसी).

टास्क पर आधारित बिल्ड सिस्टम की तरह ही, बेज़ल के कमांड-लाइन टूल का इस्तेमाल करके बिल्ड किया जा सकता है. MyBinary टारगेट बनाने के लिए, bazel build :MyBinary चलाएं. किसी क्लीन रिपॉज़िटरी में पहली बार यह कमांड डालने के बाद, Bazel:

  1. आर्टफ़ैक्ट में डिपेंडेंसी का ग्राफ़ बनाने के लिए, यह वर्कस्पेस में हर BUILD फ़ाइल को पार्स करता है.
  2. यह MyBinary की ट्रांज़िटिव डिपेंडेंसी का पता लगाने के लिए ग्राफ़ का इस्तेमाल करता है. इसका मतलब है कि यह हर उस टारगेट के लिए है जिस पर MyBinary निर्भर करता है और वे हर टारगेट पर बार-बार निर्भर करते हैं.
  3. इनमें से हर डिपेंडेंसी को क्रम में बनाता है. Baज़ल, हर टारगेट को बनाकर शुरुआत करता है जिस पर कोई और डिपेंडेंसी नहीं है. साथ ही, यह ट्रैक करता है कि हर टारगेट के लिए अब भी कौनसी डिपेंडेंसी बनाने की ज़रूरत है. जैसे ही टारगेट की सभी डिपेंडेंसी बन जाती हैं, Baज़ल उस टारगेट को पूरा करना शुरू कर देता है. यह प्रोसेस तब तक जारी रहती है, जब तक MyBinary की सभी ट्रांज़िटिव डिपेंडेंसी नहीं बन जाती.
  4. MyBinary को बिल्ड करके, आखिरी एक्सीक्यूटेबल बाइनरी बनाई जाती है. यह बाइनरी, तीसरे चरण में बनाई गई सभी डिपेंडेंसी को लिंक करती है.

बुनियादी तौर पर, ऐसा नहीं लग सकता कि यहां जो हो रहा है उससे बहुत अलग है. असल में, आखिर में वही बाइनरी बनती है. इसे बनाने की प्रोसेस में, कई चरणों का विश्लेषण करके, उनमें मौजूद डिपेंडेंसी ढूंढी जाती हैं. इसके बाद, उन चरणों को क्रम से चलाया जाता है. हालांकि, कुछ बड़े अंतर भी हैं. पहला फ़ायदा तीसरे चरण में दिखता है: Bazel को पता है कि हर टारगेट सिर्फ़ एक Java लाइब्रेरी बनाता है. इसलिए, उसे उपयोगकर्ता की तय की गई किसी भी स्क्रिप्ट के बजाय, Java कंपाइलर को चलाना होता है. इसलिए, यह पता चलता है कि इन चरणों को एक साथ चलाना सुरक्षित है. इससे मल्टीकोर मशीन पर, एक बार में एक टारगेट बनाने की तुलना में परफ़ॉर्मेंस में काफ़ी सुधार हो सकता है. ऐसा सिर्फ़ इसलिए हो सकता है, क्योंकि आर्टफ़ैक्ट पर आधारित तरीके से, बिल्ड सिस्टम को अपनी रणनीति को लागू करने की ज़िम्मेदारी मिल जाती है, ताकि यह पैरलल प्रोसेसिंग के बारे में बेहतर गारंटी दे सके.

हालांकि, इसके फ़ायदे पैरलल प्रोसेसिंग से भी ज़्यादा हैं. इस तरीके से हमें एक और फ़ायदा मिलता है. यह तब पता चलता है, जब डेवलपर कोई बदलाव किए बिना bazel build :MyBinary को दूसरी बार टाइप करता है: Bazel एक सेकंड से भी कम समय में बंद हो जाता है और यह मैसेज दिखाता है कि टारगेट अप-टू-डेट है. यह मुमकिन है, क्योंकि हमने फ़ंक्शनल प्रोग्रामिंग मॉडल के बारे में शुरुआत में बात की थी. फ़िलहाल, हम इस बारे में बात करते हैं. बैजेल जानते हैं कि हर टारगेट, सिर्फ़ Java कंपाइलर चलाने का नतीजा है. साथ ही, इसे पता है कि Java कंपाइलर का आउटपुट सिर्फ़ उसके इनपुट पर निर्भर करता है. जब तक इनपुट में बदलाव नहीं होता, तब तक आउटपुट का फिर से इस्तेमाल किया जा सकता है. यह विश्लेषण हर लेवल पर काम करता है. अगर MyBinary.java में बदलाव होता है, तो Bazel को MyBinary को फिर से बनाना होगा, लेकिन mylib का फिर से इस्तेमाल करना होगा. अगर //java/com/example/common के लिए कोई सोर्स फ़ाइल बदलती है, तो Bazel उस लाइब्रेरी, mylib, और MyBinary को फिर से बनाता है. हालांकि, वह //java/com/example/myproduct/otherlib का फिर से इस्तेमाल करता है. Bazel हर चरण में इस्तेमाल होने वाले टूल की प्रॉपर्टी के बारे में जानता है. इसलिए, वह हर बार आर्टफ़ैक्ट का सिर्फ़ कम से कम सेट फिर से बना पाता है. साथ ही, यह भी पक्का करता है कि पुराने बिल्ड न बनें.

टास्क के बजाय आर्टफ़ैक्ट के हिसाब से बिल्ड प्रोसेस को फिर से तैयार करना आसान है, लेकिन काफ़ी असरदार है. प्रोग्रामर को कम सुविधाएं देकर, बिल्ड सिस्टम को इस बारे में ज़्यादा जानकारी मिल सकती है कि बिल्ड के हर चरण में क्या किया जा रहा है. बिल्ड प्रोसेस को साथ-साथ रखकर और उनके आउटपुट को फिर से इस्तेमाल करके, यह इस जानकारी का इस्तेमाल करके बिल्ड को ज़्यादा कारगर बना सकता है. हालांकि, यह सिर्फ़ पहला कदम है. एक साथ काम करने और दोबारा इस्तेमाल करने की ये सुविधाएं, डिस्ट्रिब्यूट किए गए और बड़े स्तर पर काम करने वाले बिल्ड सिस्टम की बुनियाद हैं.

बेज़ेल की अन्य शानदार ट्रिक

आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम, टास्क पर आधारित बिल्ड सिस्टम में मौजूद, पैरलल प्रोसेस और फिर से इस्तेमाल करने से जुड़ी समस्याओं को हल करते हैं. हालांकि, अब भी कुछ ऐसी समस्याएं हैं जिनका हमने अब तक समाधान नहीं किया है. Bazel में इनमें से हर समस्या को हल करने के बेहतर तरीके हैं. आगे बढ़ने से पहले, इनके बारे में चर्चा करना ज़रूरी है.

डिपेंडेंसी के तौर पर टूल

हमें पहले एक समस्या का सामना करना पड़ा था. यह समस्या यह थी कि बिल्ड, हमारी मशीन पर इंस्टॉल किए गए टूल पर निर्भर करते थे. साथ ही, टूल के अलग-अलग वर्शन या जगहों की वजह से, सभी सिस्टम पर बिल्ड फिर से बनाना मुश्किल हो सकता था. यह समस्या तब और भी मुश्किल हो जाती है जब आपका प्रोजेक्ट उन भाषाओं का इस्तेमाल करता है जिनमें अलग-अलग टूल की ज़रूरत होती है कि उन्हें किस प्लैटफ़ॉर्म पर बनाया जा रहा है या किस प्लैटफ़ॉर्म के लिए कंपाइल किया जा रहा है (जैसे कि Windows बनाम Linux). उनमें से हर प्लैटफ़ॉर्म पर वही काम करने के लिए अलग-अलग टूल की ज़रूरत पड़ती है.

Basel ने हर टारगेट के लिए टूल को डिपेंडेंसी के तौर पर इस्तेमाल करके, इस समस्या के पहले हिस्से को हल किया. फ़ाइल फ़ोल्डर का हर java_library, Java कंपाइलर पर निर्भर करता है, जो जाने-माने कंपाइलर को डिफ़ॉल्ट रूप से सेट करता है. जब भी Bazel कोई java_library बनाता है, तो यह पक्का करता है कि तय किया गया कंपाइलर, किसी जानी-पहचानी जगह पर उपलब्ध हो. किसी भी दूसरी डिपेंडेंसी की तरह, अगर Java कंपाइलर में बदलाव होता है, तो उस पर निर्भर हर आर्टफ़ैक्ट को फिर से बनाया जाता है.

Bazel, बिल्ड कॉन्फ़िगरेशन सेट करके, समस्या के दूसरे हिस्से, प्लैटफ़ॉर्म के हिसाब से काम करने की सुविधा को हल करता है. टारगेट, टूल के बजाय कॉन्फ़िगरेशन के टाइप पर निर्भर करते हैं:

  • होस्ट कॉन्फ़िगरेशन: बिल्ड के दौरान चलने वाले बिल्डिंग टूल
  • टारगेट कॉन्फ़िगरेशन: वह बाइनरी बनाना जिसका आपने अनुरोध किया था

बिल्ड सिस्टम को बेहतर बनाना

Basel का टारगेट, कई लोकप्रिय प्रोग्रामिंग भाषाओं के लिए है. हालांकि, इंजीनियर हमेशा कुछ और करना चाहते हैं. टास्क-आधारित सिस्टम का एक फ़ायदा यह है कि वे किसी भी तरह की बिल्ड प्रोसेस को सपोर्ट कर सकते हैं. बेहतर होगा कि इसे आर्टफ़ैक्ट-आधारित बिल्ड सिस्टम में न दें. अच्छी बात यह है कि Ba जानना, इसके साथ काम करने वाले टारगेट टाइप को कस्टम नियम जोड़कर बढ़ाने की अनुमति देता है.

Bazel में कोई नियम तय करने के लिए, नियम बनाने वाला व्यक्ति उन इनपुट के बारे में बताता है जिनकी BUILD फ़ाइल में एट्रिब्यूट के तौर पर ज़रूरत होती है. साथ ही, वह नियम से मिलने वाले आउटपुट के तय किए गए सेट के बारे में भी बताता है. लेखक यह भी तय करता है कि उस नियम से कौनसी कार्रवाइयां जनरेट होंगी. हर कार्रवाई अपने इनपुट और आउटपुट की जानकारी देती है, किसी खास एक्सीक्यूटेबल को चलाती है या किसी फ़ाइल में कोई खास स्ट्रिंग लिखती है. साथ ही, अपने इनपुट और आउटपुट की मदद से, अन्य कार्रवाइयों से कनेक्ट की जा सकती है. इसका मतलब है कि कार्रवाइयां, बिल्ड सिस्टम में सबसे निचले लेवल की कंपोज की जा सकने वाली यूनिट होती हैं. जब तक कोई कार्रवाई सिर्फ़ अपने एलान किए गए इनपुट और आउटपुट का इस्तेमाल करती है, तब तक वह अपनी मर्ज़ी से कुछ भी कर सकती है. साथ ही, Bazel कार्रवाइयों को शेड्यूल करने और उनके नतीजों को ज़रूरत के हिसाब से कैश मेमोरी में सेव करने का काम करती है.

यह सिस्टम पूरी तरह से सुरक्षित नहीं है, क्योंकि ऐक्शन डेवलपर को कुछ करने से रोकने का कोई तरीका नहीं है. जैसे, कार्रवाई के तौर पर कोई तय प्रक्रिया शुरू करना. हालांकि, ऐसा अक्सर नहीं होता. साथ ही, गलत इस्तेमाल की संभावनाओं को कार्रवाई के लेवल तक ले जाने से, गड़बड़ियों की संभावनाएं बहुत कम हो जाती हैं. कई सामान्य भाषाओं और टूल के लिए नियम, ऑनलाइन उपलब्ध हैं. ज़्यादातर प्रोजेक्ट के लिए, कभी भी अपने नियम तय करने की ज़रूरत नहीं पड़ती. जो लोग ऐसा करते हैं उनके लिए भी, नियम की परिभाषाएं, डेटा स्टोर करने की जगह में सिर्फ़ एक ही जगह पर बताई जानी चाहिए. इसका मतलब है कि ज़्यादातर इंजीनियर इन नियमों का इस्तेमाल, लागू होने की चिंता किए बिना कर पाएंगे.

एनवायरमेंट को आइसोलेट करना

ऐसा लगता है कि कार्रवाइयों में, दूसरे सिस्टम में टास्क से जुड़ी समस्याएं आ सकती हैं—क्या अब भी ऐसी कार्रवाइयां लिखी जा सकती हैं जो एक ही फ़ाइल में लिखती हैं और एक-दूसरे से मेल नहीं खाती हैं? दरअसल, बेज़ल इन समस्याओं को सैंडबॉक्सिंग का इस्तेमाल करके नामुमकिन बना देता है. काम करने वाले सिस्टम पर, हर कार्रवाई को फ़ाइल सिस्टम सैंडबॉक्स के ज़रिए अलग-अलग कार्रवाई से अलग किया जाता है. हर कार्रवाई में फ़ाइल सिस्टम का सिर्फ़ एक सीमित व्यू हो सकता है. इसमें वे इनपुट शामिल होते हैं जिनके बारे में उसने एलान किया है और जिनसे वह आउटपुट जनरेट करता है. इसे Linux पर LXC जैसे सिस्टम से लागू किया जाता है. यह Docker के पीछे काम करने वाली टेक्नोलॉजी है. इसका मतलब है कि एक-दूसरे के साथ कार्रवाइयों का विरोध करना असंभव है, क्योंकि वे ऐसी किसी भी फ़ाइल को नहीं पढ़ सकते जिनके बारे में उन्होंने एलान नहीं किया है. साथ ही, ऐसी किसी भी फ़ाइल को लिखने पर जिसकी जानकारी उन्होंने नहीं दी है उसे कार्रवाई पूरी होने के बाद हटा दिया जाएगा. Bazel, सैंडबॉक्स का इस्तेमाल करके भी कार्रवाई को नेटवर्क के ज़रिए कम्यूनिकेट करने से रोकता है.

बाहरी डिपेंडेंसी को डिटरमिनिस्टिक बनाना

अब भी एक समस्या बाकी है: बिल्ड सिस्टम को अक्सर बाहरी सोर्स से डिपेंडेंसी (चाहे टूल या लाइब्रेरी) डाउनलोड करनी पड़े, न कि उन्हें सीधे बनाना. उदाहरण में, @com_google_common_guava_guava//jar डिपेंडेंसी के ज़रिए इसे देखा जा सकता है. यह डिपेंडेंसी, Maven से JAR फ़ाइल डाउनलोड करती है.

मौजूदा फ़ाइल फ़ोल्डर के बाहर की फ़ाइलों के हिसाब से, नुकसान पहुंचाने वाला कॉन्टेंट हो सकता है. ये फ़ाइलें किसी भी समय बदली जा सकती हैं. ऐसा हो सकता है कि बिल्ड सिस्टम को लगातार यह जांचना पड़े कि वे नई हैं या नहीं. अगर कोई रिमोट फ़ाइल, फ़ाइल फ़ोल्डर के सोर्स कोड में बिना किसी बदलाव के बदल जाती है, तो इसकी वजह से ऐसे बिल्ड भी हो सकते हैं जिन्हें फिर से बनाया नहीं जा सकता. बिल्ड एक दिन काम कर सकता है और किसी दूसरे डिपेंडेंसी में हुए बदलाव की वजह से बिना किसी साफ़ वजह के, अगले चरण में फ़ेल हो सकता है. आखिर में, अगर किसी बाहरी डिपेंडेंसी का मालिकाना हक तीसरे पक्ष के पास है, तो इससे सुरक्षा से जुड़ा बड़ा खतरा हो सकता है: अगर कोई हमलावर उस तीसरे पक्ष के सर्वर में घुसपैठ कर पाता है, तो वह डिपेंडेंसी फ़ाइल को अपने डिज़ाइन की किसी चीज़ से बदल सकता है. इससे, उसे आपके बिल्ड एनवायरमेंट और उसके आउटपुट पर पूरा कंट्रोल मिल सकता है.

मूल समस्या यह है कि हम चाहते हैं कि बिल्ड सिस्टम को इन फ़ाइलों के बारे में पता हो, लेकिन उन्हें सोर्स कंट्रोल में शामिल न करना पड़े. किसी डिपेंडेंसी को अपडेट करने का फ़ैसला सोच-समझकर लिया जाना चाहिए. हालांकि, यह फ़ैसला किसी एक इंजीनियर या सिस्टम के अपने-आप मैनेज होने के बजाय, एक ही जगह पर एक बार लिया जाना चाहिए. इसकी वजह यह है कि “Live at Head” मॉडल के साथ भी, हम चाहते हैं कि बिल्ड डिटरमिनिस्टिक हों. इसका मतलब है कि अगर पिछले हफ़्ते के किसी कमिट को चेक किया जाता है, तो आपको अपनी डिपेंडेंसी अब की तरह नहीं, बल्कि उस समय की तरह दिखनी चाहिए.

Babel और कुछ अन्य बिल्ड सिस्टम इस समस्या को हल करते हैं. इसके लिए, Workspace के उपयोगकर्ताओं को एक ऐसी मेनिफ़ेस्ट फ़ाइल की ज़रूरत होती है जिसमें, उनके संगठन से बाहर होने वाली हर डिपेंडेंसी के लिए क्रिप्टोग्राफ़िक हैश की सूची मौजूद हो. हैश, फ़ाइल को यूनीक तरीके से दिखाने का एक छोटा तरीका है. इसके लिए, सोर्स कंट्रोल में पूरी फ़ाइल की जांच करने की ज़रूरत नहीं होती. जब भी किसी वर्कस्पेस से किसी नई बाहरी डिपेंडेंसी का रेफ़रंस दिया जाता है, तो उस डिपेंडेंसी का हैश मैन्युअल तरीके से या अपने-आप मेनिफ़ेस्ट में जुड़ जाता है. जब Bazel कोई बिल्ड चलाता है, तो वह मेनिफ़ेस्ट में बताए गए अनुमानित हैश के मुकाबले, कैश मेमोरी में सेव की गई डिपेंडेंसी के असल हैश की जांच करता है. साथ ही, हैश में अंतर होने पर ही फ़ाइल को फिर से डाउनलोड करता है.

अगर डाउनलोड किए गए आर्टफ़ैक्ट का हैश, मेनिफ़ेस्ट में बताए गए हैश से अलग है, तो मेनिफ़ेस्ट में हैश अपडेट होने तक बिल्ड नहीं हो पाएगा. यह काम अपने-आप हो सकता है. हालांकि, बिल्ड को नई डिपेंडेंसी स्वीकार करने से पहले, बदलाव को मंज़ूरी देनी होगी और सोर्स कंट्रोल में चेक इन करना होगा. इसका मतलब है कि डिपेंडेंसी को अपडेट किए जाने का रिकॉर्ड हमेशा मौजूद होता है. साथ ही, बाहरी डिपेंडेंसी को फ़ाइल फ़ोल्डर के सोर्स में बदलाव किए बिना नहीं बदला जा सकता. इसका मतलब यह भी है कि सोर्स कोड के किसी पुराने वर्शन के बारे में पता करने पर, बिल्ड को उसी डिपेंडेंसी का इस्तेमाल करने की गारंटी होती है जिसका इस्तेमाल उस वर्शन को चेक इन करने के दौरान किया जा रहा था. ऐसा न होने पर, इस बात की गारंटी नहीं मिलती कि वे डिपेंडेंसी अब उपलब्ध नहीं होंगी.

हालांकि, अगर कोई रिमोट सर्वर उपलब्ध नहीं होता है या वह गलत डेटा दिखाना शुरू कर देता है, तो भी समस्या हो सकती है. अगर आपके पास उस डिपेंडेंसी की कोई दूसरी कॉपी उपलब्ध नहीं है, तो इससे आपके सभी बिल्ड काम करना बंद कर सकते हैं. इस समस्या से बचने के लिए, हमारा सुझाव है कि किसी भी मुश्किल प्रोजेक्ट के लिए, उसकी सभी डिपेंडेंसी को उन सर्वर या सेवाओं पर मिरर करें जिन पर आपका भरोसा है और जिन्हें आपने कंट्रोल किया है. ऐसा न करने पर, आपको अपने बिल्ड सिस्टम की उपलब्धता के लिए, हमेशा तीसरे पक्ष पर निर्भर रहना पड़ेगा. भले ही, चेक इन किए गए हैश से उसकी सुरक्षा की गारंटी मिलती हो.