<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>DevOps on kenji.blog</title><link>http://kenji.blog/hi/categories/devops/</link><description>Recent content in DevOps on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>hi</language><copyright>kenjinote</copyright><lastBuildDate>Sun, 13 Sep 2026 09:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/hi/categories/devops/index.xml" rel="self" type="application/rss+xml"/><item><title>【Git कमांड】rebase और merge के बीच का अंतर, और व्यवहार में इनका सही उपयोग कैसे करें</title><link>http://kenji.blog/hi/p/git-rebase-vs-merge-practical-guide/</link><pubDate>Sun, 13 Sep 2026 09:00:00 +0900</pubDate><guid>http://kenji.blog/hi/p/git-rebase-vs-merge-practical-guide/</guid><description>&lt;img src="http://kenji.blog/p/git-rebase-vs-merge-practical-guide/img/eyecatch.jpg" alt="Featured image of post 【Git कमांड】rebase और merge के बीच का अंतर, और व्यवहार में इनका सही उपयोग कैसे करें" />&lt;h1 id="1-परचय-merge-य-rebase-हमश-एक-बहस-क-वषय-कय-ह">1. परिचय: &amp;ldquo;merge या rebase&amp;rdquo; हमेशा एक बहस का विषय क्यों है?
&lt;/h1>&lt;p>Git आधुनिक सॉफ़्टवेयर विकास में एक अपरिहार्य वर्ज़न कंट्रोल सिस्टम है। जब कई डेवलपर्स एक साथ कोडबेस में परिवर्तन करते हैं, तो Git का शक्तिशाली ब्रांच मॉडल अपनी ताकत दिखाता है। हालाँकि, टीम डेवलपमेंट में &amp;ldquo;क्या &lt;code>merge&lt;/code> या &lt;code>rebase&lt;/code> का उपयोग करना चाहिए&amp;rdquo; यह चर्चा हमेशा शुरुआती लोगों से लेकर अनुभवी डेवलपर्स तक को परेशान करने वाले विषयों में से एक रही है।&lt;/p>
&lt;p>इस लेख में, हम Git की आंतरिक संरचना, जैसे DAG (Directed Acyclic Graph) और कमिट हैश के गणितीय गुणों से शुरू करते हुए, &lt;code>git merge&lt;/code> और &lt;code>git rebase&lt;/code> के मैकेनिज़्म के बीच के अंतर को गहराई से समझेंगे। इसके अलावा, हम व्यावहारिक वर्कफ़्लो के साथ विस्तार से बताएंगे कि वास्तविक काम में इनका सही तरीके से उपयोग कैसे किया जाए। केवल कमांड्स के परिचय से आगे बढ़कर, बैकग्राउंड में Git किस तरह की गणनाएँ कर रहा है, यह समझने से आपका कॉन्फ्लिक्ट (टकराव) का डर खत्म हो जाएगा और आप एक साफ़ और ट्रैक करने योग्य इतिहास (history) बना सकेंगे।&lt;/p>
&lt;hr>
&lt;h1 id="2-git-क-आतरक-सरचन-कमट-हश-और-ऑबजकट-मडल">2. Git की आंतरिक संरचना: कमिट हैश और ऑब्जेक्ट मॉडल
&lt;/h1>&lt;p>Git इतिहास को कैसे इंटीग्रेट (एकीकृत) करता है, इसे समझने के लिए पहले यह जानना ज़रूरी है कि Git डेटा को कैसे सेव करता है। Git केवल फ़ाइल में बदलावों के अंतर (पैच) को सेव नहीं करता है, बल्कि यह किसी विशिष्ट समय पर पूरे फ़ाइल सिस्टम के स्नैपशॉट को सेव करता है।&lt;/p>
&lt;h2 id="21-कमट-हश-क-करपटगरफक-गण">2.1 कमिट हैश के क्रिप्टोग्राफ़िक गुण
&lt;/h2>&lt;p>Git का प्रत्येक कमिट इसके कंटेंट के आधार पर कैलकुलेट किए गए SHA-1 (Secure Hash Algorithm 1) हैश फ़ंक्शन द्वारा 40-अंकीय हेक्साडेसिमल संख्या से विशिष्ट रूप से पहचाना जाता है। कमिट ऑब्जेक्ट में निम्नलिखित तत्व (elements) होते हैं:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Tree ऑब्जेक्ट का पॉइंटर&lt;/strong>: उस समय के डायरेक्टरी स्ट्रक्चर और फ़ाइल (Blob) का स्नैपशॉट।&lt;/li>
&lt;li>&lt;strong>पैरेंट कमिट का पॉइंटर&lt;/strong>: एक या अधिक पैरेंट कमिट्स के हैश मान (पहले कमिट का कोई पैरेंट नहीं होता है, और मर्ज कमिट के 2 या अधिक पैरेंट होते हैं)।&lt;/li>
&lt;li>&lt;strong>लेखक की जानकारी (Author)&lt;/strong>: वह व्यक्ति जिसने कोड लिखा है और उसका समय।&lt;/li>
&lt;li>&lt;strong>कमिटर की जानकारी (Committer)&lt;/strong>: वह व्यक्ति जिसने कमिट बनाया/लागू किया है और उसका समय।&lt;/li>
&lt;li>&lt;strong>कमिट मैसेज&lt;/strong>: बदलाव के उद्देश्य को स्पष्ट करने वाला टेक्स्ट।&lt;/li>
&lt;/ol>
&lt;p>गणितीय रूप से व्यक्त करें, तो कमिट ऑब्जेक्ट $C$ के लिए हैश मान $H(C)$ को इस प्रकार परिभाषित किया गया है:&lt;/p>
$$
H(C) = \text{SHA-1}( \text{tree} \parallel \text{parent} \parallel \text{author} \parallel \text{committer} \parallel \text{message} )
$$&lt;p>यहाँ, $\parallel$ डेटा के संयोजन को दर्शाता है। हैश फ़ंक्शन की विशेषताओं के कारण, भले ही कमिट मैसेज में एक अक्षर बदल दिया जाए, या पैरेंट कमिट अलग हो, पूरी तरह से अलग हैश मान उत्पन्न होता है। दूसरे शब्दों में, &lt;strong>कमिट अपरिवर्तनीय (Immutable) होते हैं&lt;/strong>। बाद में जिस &lt;code>rebase&lt;/code> का वर्णन &amp;ldquo;इतिहास को फिर से लिखने&amp;rdquo; के रूप में किया गया है, वह वास्तव में &amp;ldquo;एक नया कमिट बना रहा है जिसकी सामग्री समान है लेकिन हैश मान अलग है।&amp;rdquo;&lt;/p>
&lt;p>हैश स्पेस का आकार $2^{160}$ है, और टकराव की संभावना (Collision) (यह संभावना कि विभिन्न कमिट्स का हैश मान समान होगा) $P$ को बर्थडे पैराडॉक्स (Birthday Paradox) थ्योरी का उपयोग करके इस प्रकार अनुमानित किया जा सकता है ($n$ कमिट्स की संख्या है):&lt;/p>
$$
P(\text{collision}) \approx 1 - \exp\left(-\frac{n^2}{2 \times 2^{160}}\right)
$$&lt;p>यह संभावना बहुत ही कम है, और व्यावहारिक रूप से यह लगभग असंभव है कि Git का कमिट हैश आपस में टकराए।&lt;/p>
&lt;hr>
&lt;h1 id="3-गरफ-थयर-और-dag-git-इतहस-क-गणतय-मडल">3. ग्राफ़ थ्योरी और DAG: Git इतिहास का गणितीय मॉडल
&lt;/h1>&lt;p>Git के कमिट इतिहास को ग्राफ़ थ्योरी में &amp;ldquo;डायरेक्टेड एसाइक्लिक ग्राफ़ (Directed Acyclic Graph, DAG)&amp;rdquo; के रूप में मॉडल किया गया है।&lt;/p>
&lt;h2 id="31-dag-डयरकटड-एसइकलक-गरफ-कय-ह">3.1 DAG (डायरेक्टेड एसाइक्लिक ग्राफ़) क्या है?
&lt;/h2>&lt;p>ग्राफ़ $G = (V, E)$ में, $V$ कमिट्स (Vertices) का सेट है, और $E$ कमिट्स के बीच पैरेंट-चाइल्ड संबंध को दर्शाने वाले डायरेक्टेड एजेज़ (Directed Edges) का सेट है। Git में, एजेज़ की दिशा &amp;ldquo;चाइल्ड कमिट से पैरेंट कमिट&amp;rdquo; की ओर होती है। ऐसा इसलिए है क्योंकि नए कमिट पिछले कमिट का पॉइंटर रखते हैं।&lt;/p>
&lt;pre class="mermaid">
graph BT
A[&amp;#34;कमिट A (प्रारंभिक)&amp;#34;]
B[&amp;#34;कमिट B&amp;#34;]
C[&amp;#34;कमिट C (Main)&amp;#34;]
D[&amp;#34;कमिट D (Feature)&amp;#34;]
E[&amp;#34;कमिट E (Merge)&amp;#34;]
B --&amp;gt; A
C --&amp;gt; B
D --&amp;gt; B
E --&amp;gt; C
E --&amp;gt; D
&lt;/pre>
&lt;p>DAG की सबसे बड़ी विशेषता यह है कि &amp;ldquo;इसमें कोई चक्र (Cycle) नहीं होता है&amp;rdquo;। इस वजह से, कमिट इतिहास को पीछे ट्रेस करने वाला एल्गोरिदम कभी भी अनंत लूप में नहीं फँसता है, और यह निश्चित रूप से अंत (प्रारंभिक कमिट) तक पहुँच सकता है।&lt;/p>
&lt;h2 id="32-टपलजकल-सरट-और-इतहस-क-करम">3.2 टोपोलॉजिकल सॉर्ट और इतिहास का क्रम
&lt;/h2>&lt;p>जब Git के &lt;code>git log&lt;/code> कमांड आदि का उपयोग करके इतिहास प्रदर्शित किया जाता है, तो DAG को टोपोलॉजिकल सॉर्ट (Topological Sort) एल्गोरिदम का उपयोग करके एक 1-आयामी (1-dimensional) सूची के रूप में क्रमित किया जाता है। DAG में किसी भी डायरेक्टेड एज $u \to v$ ($u$, $v$ का चाइल्ड है) के लिए, यह इस तरह से पुनर्व्यवस्थित होता है कि सूची में $u$, $v$ से पहले आए।&lt;/p>
&lt;hr>
&lt;h1 id="4-git-merge-क-मकनजम-और-परकर">4. git merge का मैकेनिज़्म और प्रकार
&lt;/h1>&lt;p>ब्रांच के बदलावों को इंटीग्रेट करने के लिए सबसे बुनियादी कमांड &lt;code>git merge&lt;/code> है। हालाँकि, वर्तमान स्थिति के आधार पर, Git स्वचालित रूप से अलग-अलग मर्ज रणनीतियों का चयन करता है।&lt;/p>
&lt;h2 id="41-fast-forward-मरज---ff">4.1 Fast-Forward मर्ज (&amp;ndash;ff)
&lt;/h2>&lt;p>यदि लक्ष्य (जैसे: &lt;code>main&lt;/code>) ब्रांच सोर्स (जैसे: &lt;code>feature&lt;/code>) ब्रांच का प्रत्यक्ष पूर्वज (direct ancestor) है, तो Git &amp;ldquo;Fast-Forward&amp;rdquo; (तेज़ी से आगे बढ़ाना) मर्ज को निष्पादित करता है। यह एक ऐसा ऑपरेशन है जो नया कमिट नहीं बनाता है, बल्कि यह बस ब्रांच पॉइंटर को आगे बढ़ाता है।&lt;/p>
&lt;pre class="mermaid">
gitGraph
commit id: &amp;#34;A&amp;#34;
commit id: &amp;#34;B&amp;#34;
branch feature
checkout feature
commit id: &amp;#34;C&amp;#34;
commit id: &amp;#34;D&amp;#34;
checkout main
merge feature
&lt;/pre>
&lt;p>Fast-Forward मर्ज इतिहास को एक सीधी रेखा में रखता है, लेकिन इसका एक नुकसान यह है कि &amp;ldquo;कौन से कमिट्स का समूह एक फीचर (feature) के विकास के रूप में एक साथ था&amp;rdquo;, इसका संदर्भ (Context) खो जाता है।&lt;/p>
&lt;h2 id="42-non-fast-forward-मरज---no-ff">4.2 Non-Fast-Forward मर्ज (&amp;ndash;no-ff)
&lt;/h2>&lt;p>यदि आप स्पष्ट रूप से &lt;code>git merge --no-ff&lt;/code> निर्दिष्ट करते हैं, तो भले ही Fast-Forward संभव हो, यह हमेशा एक नया &amp;ldquo;मर्ज कमिट&amp;rdquo; बनाएगा। मर्ज कमिट 2 पैरेंट्स वाला एक विशेष कमिट होता है।&lt;/p>
&lt;pre class="mermaid">
gitGraph
commit id: &amp;#34;A&amp;#34;
commit id: &amp;#34;B&amp;#34;
branch feature
checkout feature
commit id: &amp;#34;C&amp;#34;
commit id: &amp;#34;D&amp;#34;
checkout main
commit id: &amp;#34;Main Work 1&amp;#34;
merge feature type: NORMAL
&lt;/pre>
&lt;p>इस पद्धति का लाभ यह है कि फीचर ब्रांच का अस्तित्व और इतिहास DAG पर स्पष्ट रूप से रहता है। जब कोई समस्या उत्पन्न होती है, तो आप &lt;code>git revert -m 1 &amp;lt;मर्ज कमिट का हैश&amp;gt;&lt;/code> चलाकर पूरे फीचर को एक ही बार में सुरक्षित रूप से पूर्ववत (रिवर्ट) कर सकते हैं।&lt;/p>
&lt;h2 id="43-3-व-मरज-3-way-merge-एलगरदम">4.3 3-वे मर्ज (3-Way Merge) एल्गोरिदम
&lt;/h2>&lt;p>जब लक्ष्य ब्रांच और सोर्स ब्रांच दोनों के अपने स्वयं के कमिट होते हैं, तो Git 3-वे मर्ज निष्पादित करता है। इस समय, Git DAG को खोजता है और दोनों ब्रांचों के &amp;ldquo;न्यूनतम सामान्य पूर्वज (Lowest Common Ancestor, LCA)&amp;rdquo; का पता लगाता है।&lt;/p>
&lt;p>LCA खोजने के लिए एल्गोरिदम की कम्प्यूटेशनल जटिलता (Computational Complexity) $T_{\text{LCA}}$ को वर्टिसेस की संख्या $|V|$ और एजेज़ की संख्या $|E|$ के सापेक्ष रैखिक समय (Linear Time) में निष्पादित किया जा सकता है:&lt;/p>
$$
T_{\text{LCA}} = \mathcal{O}(|V| + |E|)
$$&lt;p>Git तीन चीजों की तुलना करता है: &amp;ldquo;LCA की स्थिति&amp;rdquo;, &amp;ldquo;वर्तमान ब्रांच की स्थिति&amp;rdquo;, और &amp;ldquo;दूसरी ब्रांच की स्थिति&amp;rdquo;, और यदि परिवर्तनों में कोई टकराव (conflict) नहीं होता है, तो यह स्वचालित रूप से एक मर्ज कमिट उत्पन्न करता है।&lt;/p>
&lt;hr>
&lt;h1 id="5-git-rebase-क-मकनजम-और-इतहस-क-पनरनरमण">5. git rebase का मैकेनिज़्म और इतिहास का पुनर्निर्माण
&lt;/h1>&lt;p>जबकि &lt;code>git merge&lt;/code> इतिहास को &amp;ldquo;एकीकृत (Integrate)&amp;rdquo; करता है, &lt;code>git rebase&lt;/code> इतिहास का &amp;ldquo;पुनर्निर्माण (Rebuild)&amp;rdquo; करता है।&lt;/p>
&lt;h2 id="51-rebase-क-पछ-क-करयपरणल">5.1 Rebase के पीछे की कार्यप्रणाली
&lt;/h2>&lt;p>जब आप &lt;code>feature&lt;/code> ब्रांच को &lt;code>main&lt;/code> ब्रांच में रिबेस करते हैं (&lt;code>git rebase main&lt;/code>), तो आंतरिक कार्यप्रणाली इस प्रकार होती है:&lt;/p>
&lt;ol>
&lt;li>&lt;code>feature&lt;/code> ब्रांच और &lt;code>main&lt;/code> ब्रांच के सामान्य पूर्वज (LCA) का पता लगाएं।&lt;/li>
&lt;li>LCA से लेकर &lt;code>feature&lt;/code> ब्रांच के शीर्ष तक के कमिट्स के अंतर को एक अस्थायी क्षेत्र (Temporary Area) में सेव करें।&lt;/li>
&lt;li>&lt;code>feature&lt;/code> ब्रांच के पॉइंटर को &lt;code>main&lt;/code> ब्रांच के शीर्ष (Tip) पर ले जाएं।&lt;/li>
&lt;li>सहेजे गए अंतरों को एक-एक करके नए बेस (&lt;code>main&lt;/code> के शीर्ष) पर क्रमिक रूप से लागू (Cherry-Pick) करें, और नए कमिट्स बनाएं।&lt;/li>
&lt;/ol>
&lt;pre class="mermaid">
graph TD
A[&amp;#34;कमिट A&amp;#34;] --&amp;gt; B[&amp;#34;कमिट B&amp;#34;]
B --&amp;gt; C[&amp;#34;कमिट C (Main)&amp;#34;]
B --&amp;gt; D[&amp;#34;कमिट D (पुराना फीचर)&amp;#34;]
D -.-&amp;gt; E[&amp;#34;कमिट D&amp;#39; (नया फीचर)&amp;#34;]
C --&amp;gt; E
style D stroke-dasharray: 5 5, fill: #f9f9f9, color: #999
&lt;/pre>
&lt;p>यहाँ सबसे महत्वपूर्ण बात यह है कि रिबेस द्वारा उत्पन्न कमिट $D'$, मूल कमिट $D$ से &lt;strong>एक अलग पैरेंट कमिट होने के कारण, पूरी तरह से अलग हैश मान रखता है&lt;/strong> (ऊपर उल्लिखित हैश फ़ंक्शन परिभाषा $H(C)$ देखें)।&lt;/p>
&lt;h2 id="52-इटरएकटव-रबस-interactive-rebase">5.2 इंटरएक्टिव रिबेस (Interactive Rebase)
&lt;/h2>&lt;p>&lt;code>git rebase -i&lt;/code> (या &lt;code>--interactive&lt;/code>) का उपयोग करके, आप अपनी इच्छानुसार कमिट इतिहास में हेरफेर कर सकते हैं। स्थानीय (Local) इतिहास को व्यवस्थित करने के लिए यह सबसे शक्तिशाली टूल है।&lt;/p>
&lt;ul>
&lt;li>&lt;code>pick&lt;/code> : कमिट को वैसे ही अपनाएं।&lt;/li>
&lt;li>&lt;code>reword&lt;/code> : केवल कमिट मैसेज को संशोधित करें।&lt;/li>
&lt;li>&lt;code>edit&lt;/code> : कमिट के कंटेंट को संशोधित करने के लिए रुकें।&lt;/li>
&lt;li>&lt;code>squash&lt;/code> : इस कमिट को पिछले कमिट के साथ मिलाएँ, और संदेशों को भी जोड़ें।&lt;/li>
&lt;li>&lt;code>fixup&lt;/code> : &lt;code>squash&lt;/code> के समान, लेकिन इस कमिट के मैसेज को हटा दें।&lt;/li>
&lt;li>&lt;code>drop&lt;/code> : कमिट को पूरी तरह से हटा दें।&lt;/li>
&lt;/ul>
&lt;p>गणितीय दृष्टिकोण से देखें तो, यदि किसी ब्रांच में $N$ कमिट हैं, तो रिबेस के क्रम को बदलकर उत्पन्न किए जा सकने वाले रैखिक इतिहास के रूपों (Permutations) $P$ की गणना इस प्रकार है:&lt;/p>
$$
P = N!
$$&lt;p>Git डेवलपर्स को $N!$ तरीकों की स्वतंत्रता देता है, जिससे वे अपने इतिहास को एक तार्किक और सुंदर स्थिति में रख सकते हैं।&lt;/p>
&lt;hr>
&lt;h1 id="6-रबस-क-सनहर-नयम-the-golden-rule-of-rebase">6. रिबेस का सुनहरा नियम (The Golden Rule of Rebase)
&lt;/h1>&lt;p>&lt;code>rebase&lt;/code> बहुत शक्तिशाली है, लेकिन इसका एक निरपेक्ष नियम (Absolute Rule) है:&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>&amp;ldquo;सार्वजनिक (Public) किए गए इतिहास पर कभी भी रिबेस (Rebase) न करें&amp;rdquo;&lt;/strong>
&lt;em>(Never rebase public history)&lt;/em>&lt;/p>
&lt;/blockquote>
&lt;h2 id="61-सरवजनक-इतहस-क-रबस-कय-नह-करन-चहए">6.1 सार्वजनिक इतिहास को रिबेस क्यों नहीं करना चाहिए?
&lt;/h2>&lt;p>Git एक डिस्ट्रिब्यूटेड (Distributed) सिस्टम है। आपने जो कमिट &lt;code>origin/main&lt;/code> पर पुश किए हैं, उन्हें अन्य डेवलपर्स के स्थानीय रिपॉजिटरी में भी क्लोन (प्रतिलिपि) किया गया है। अगर आप पहले से ही पुश किए गए कमिट्स को रिबेस करके इतिहास को फिर से लिखते हैं और &lt;code>git push --force&lt;/code> का उपयोग करके इसे जबरन ओवरराइट करते हैं, तो क्या होगा?&lt;/p>
&lt;p>अन्य डेवलपर्स के स्थानीय (Local) DAG और रिमोट (Remote) DAG मौलिक रूप से अलग हो जाएंगे। जब अन्य डेवलपर &lt;code>git pull&lt;/code> निष्पादित करते हैं, तो Git अलग-अलग इतिहास वाले कमिट्स को जबरन मर्ज करने का प्रयास करेगा, जिससे भारी मात्रा में कॉन्फ्लिक्ट्स और डुप्लिकेट कमिट्स (समान परिवर्तन लेकिन अलग-अलग हैश वाले कमिट) उत्पन्न होंगे, और रिपॉजिटरी में अफरा-तफरी मच जाएगी।&lt;/p>
&lt;p>यह एक सख्त नियम है कि रिबेस केवल &lt;strong>&amp;ldquo;उन स्थानीय ब्रांचों पर किया जाना चाहिए जिन्हें अभी तक किसी के साथ साझा नहीं किया गया है&amp;rdquo;&lt;/strong>।&lt;/p>
&lt;hr>
&lt;h1 id="7-कनफलकट-टकरव-क-समधन-और-git-rebase---continue">7. कॉन्फ्लिक्ट (टकराव) का समाधान और git rebase &amp;ndash;continue
&lt;/h1>&lt;p>जब कई लोग एक ही फ़ाइल के एक ही हिस्से में बदलाव करते हैं, तो कॉन्फ्लिक्ट होता है। &lt;code>merge&lt;/code> और &lt;code>rebase&lt;/code> में कॉन्फ्लिक्ट को हल करने की प्रक्रिया अलग-अलग होती है।&lt;/p>
&lt;h2 id="71-merge-म-कनफलकट-क-समधन">7.1 Merge में कॉन्फ्लिक्ट का समाधान
&lt;/h2>&lt;p>&lt;code>git merge&lt;/code> के मामले में, कॉन्फ्लिक्ट का समाधान &lt;strong>केवल एक बार&lt;/strong> होता है। आप अंतिम मर्ज कमिट बनाने से ठीक पहले सभी टकराव वाले हिस्सों को एक ही बार में ठीक करते हैं।&lt;/p>
&lt;h2 id="72-rebase-म-कनफलकट-क-समधन">7.2 Rebase में कॉन्फ्लिक्ट का समाधान
&lt;/h2>&lt;p>&lt;code>git rebase&lt;/code> के मामले में, कमिट्स को एक-एक करके फिर से लागू करने की प्रकृति के कारण, &lt;strong>प्रत्येक कमिट पर कॉन्फ्लिक्ट होने की संभावना&lt;/strong> होती है।&lt;/p>
&lt;p>यदि रिबेस के दौरान कोई कॉन्फ्लिक्ट होता है, तो Git प्रक्रिया को रोक देगा। समाधान का प्रवाह (Flow) इस प्रकार है:&lt;/p>
&lt;ol>
&lt;li>एडिटर या IDE (जैसे VS Code) खोलें और कॉन्फ्लिक्ट मार्कर्स (&lt;code>&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/code> , &lt;code>======&lt;/code>, और &lt;code>&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code>) को मैन्युअल रूप से ठीक करें।&lt;/li>
&lt;li>संशोधित फ़ाइल को इंडेक्स में जोड़ें:
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git add &amp;lt;संशोधित_फ़ाइल&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;/li>
&lt;li>बिना कोई कमिट बनाए रिबेस प्रक्रिया फिर से शुरू करें:
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git rebase --continue
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;/li>
&lt;/ol>
&lt;p>यदि आप रिबेस को रद्द करना चाहते हैं और मूल स्थिति में वापस लौटना चाहते हैं, तो यह कमांड चलाएँ:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git rebase --abort
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>(* यदि आपको कॉन्फ्लिक्ट को हल करने की आवश्यकता नहीं है और आप उस कमिट को पूरी तरह से छोड़ना चाहते हैं, तो &lt;code>git rebase --skip&lt;/code> का उपयोग करें।)&lt;/p>
&lt;hr>
&lt;h1 id="8-वयवहरक-रप-स-सह-उपयग-वरकफल-परकटस">8. व्यावहारिक रूप से सही उपयोग (वर्कफ़्लो प्रैक्टिस)
&lt;/h1>&lt;p>तो, वास्तविक विकास के वातावरण में आपको &lt;code>merge&lt;/code> और &lt;code>rebase&lt;/code> का उपयोग कैसे करना चाहिए? यहाँ हम सबसे मानक (Standard) और सुरक्षित दृष्टिकोण प्रस्तुत कर रहे हैं।&lt;/p>
&lt;h2 id="81-परदशय-1-सथनय-करय-इतहस-क-वयवसथत-करन-rebase-क-उपयग">8.1 [परिदृश्य 1] स्थानीय कार्य इतिहास को व्यवस्थित करना (Rebase का उपयोग)
&lt;/h2>&lt;p>मान लीजिए कि किसी फीचर ब्रांच में विकास के दौरान बहुत सारे छोटे-छोटे कमिट्स (&amp;ldquo;Typo फिक्स&amp;rdquo;, &amp;ldquo;अस्थायी सेव&amp;rdquo;, आदि) जमा हो गए हैं। पुल रिक्वेस्ट (PR) सबमिट करने से पहले, इन कमिट्स को सार्थक इकाइयों में व्यवस्थित करने के लिए इंटरएक्टिव रिबेस का उपयोग करें।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># फीचर ब्रांच में रहते हुए निष्पादित करें&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git rebase -i HEAD~5
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># (एडिटर खुलेगा, जहाँ आप squash और fixup का उपयोग करके इतिहास को साफ़ कर सकते हैं)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इससे, आप एक सुंदर कमिट इतिहास बना सकते हैं जिससे समीक्षकों (Reviewers) के लिए आपके इरादे को समझना आसान हो जाएगा।&lt;/p>
&lt;h2 id="82-परदशय-2-नवनतम-main-बरच-क-सथ-अपडट-रहन-rebase-क-उपयग">8.2 [परिदृश्य 2] नवीनतम main ब्रांच के साथ अपडेट रहना (Rebase का उपयोग)
&lt;/h2>&lt;p>यदि विकास में अधिक समय लग रहा है, और अन्य लोगों के परिवर्तन लगातार &lt;code>main&lt;/code> ब्रांच में मर्ज किए जा रहे हैं, तो आपकी &lt;code>feature&lt;/code> ब्रांच पुरानी हो जाएगी। इस स्थिति में, आप अपनी &lt;code>feature&lt;/code> ब्रांच को नवीनतम &lt;code>main&lt;/code> ब्रांच में रिबेस करके इसे अपडेट कर सकते हैं।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># main की नवीनतम जानकारी प्राप्त करें&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git fetch origin
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># फीचर ब्रांच को नवीनतम main के शीर्ष पर स्थानांतरित करें&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git rebase origin/main
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इससे इतिहास एक सीधी रेखा बन जाता है, जिससे भविष्य में मर्ज करते समय कॉन्फ्लिक्ट्स को रोका जा सकता है। इसके अलावा, यह अनावश्यक मर्ज कमिट्स (&amp;ldquo;Merge branch &amp;lsquo;main&amp;rsquo; into feature&amp;rdquo;) उत्पन्न होने से भी रोकता है।&lt;/p>
&lt;h2 id="83-परदशय-3-परण-हए-फचर-क-एककत-करन-merge-क-उपयग">8.3 [परिदृश्य 3] पूर्ण हुए फीचर को एकीकृत करना (Merge का उपयोग)
&lt;/h2>&lt;p>यह वह चरण है जब &lt;code>feature&lt;/code> ब्रांच में विकास पूरा हो चुका है, और आप अंततः इसे &lt;code>main&lt;/code> ब्रांच में एकीकृत (Integrate) कर रहे हैं। यहाँ, हम &lt;strong>&lt;code>git merge --no-ff&lt;/code>&lt;/strong> का उपयोग करेंगे (यह GitHub जैसे प्लेटफ़ॉर्म पर पुल रिक्वेस्ट में &amp;ldquo;Create a merge commit&amp;rdquo; चुनने के समान है)।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git checkout main
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git merge --no-ff feature -m &lt;span class="s2">&amp;#34;Merge feature: यूज़र लॉगिन फीचर का कार्यान्वयन&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git push origin main
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इससे, &lt;code>main&lt;/code> ब्रांच के DAG पर एक ऐतिहासिक नोड (मर्ज कमिट) बन जाएगा जो यह दर्शाएगा कि &amp;ldquo;यहाँ एक फीचर मर्ज किया गया था&amp;rdquo;। जब आप बाद में इतिहास को देखेंगे, तो फीचर के आधार पर कोड को ट्रैक करना आसान होगा।&lt;/p>
&lt;hr>
&lt;h1 id="9-नषकरष-सरश">9. निष्कर्ष (सारांश)
&lt;/h1>&lt;p>Git ऑपरेशन्स में &amp;ldquo;सब कुछ Merge के साथ करना&amp;rdquo; या &amp;ldquo;सब कुछ Rebase के साथ सीधा करना&amp;rdquo; जैसे चरम (Extreme) दृष्टिकोणों के अपने-अपने फायदे और नुकसान हैं।&lt;/p>
&lt;p>वास्तविक अभ्यास में सबसे अच्छी प्रथा (Best Practice) यह हाइब्रिड (Hybrid) दृष्टिकोण है: &lt;strong>&amp;ldquo;अपने स्थानीय निजी इतिहास को खूबसूरती से व्यवस्थित करने के लिए rebase का उपयोग करें, और सार्वजनिक एकीकरण इतिहास के संदर्भ को बनाए रखने के लिए merge &amp;ndash;no-ff का उपयोग करें।&amp;rdquo;&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>स्थानीय (व्यक्तिगत कार्यक्षेत्र - Local)&lt;/strong>: अनावश्यक कमिट्स को खत्म करने के लिए &lt;code>rebase&lt;/code> का उपयोग करें, और नवीनतम मेनलाइन के साथ अपडेट रहकर एक सीधा इतिहास बनाए रखें।&lt;/li>
&lt;li>&lt;strong>ग्लोबल (साझा कार्यक्षेत्र - Global)&lt;/strong>: फीचर ब्रांच के अस्तित्व को मर्ज कमिट के रूप में DAG में दर्ज करने के लिए &lt;code>merge --no-ff&lt;/code> का उपयोग करें, ताकि इसे रिवर्ट या ट्रैक करना आसान हो।&lt;/li>
&lt;/ul>
&lt;p>DAG की संरचना और हैश फ़ंक्शन्स के तंत्र जैसी गणितीय और संरचनात्मक पृष्ठभूमि को समझकर, Git कमांड्स का उपयोग केवल याद रखने से &amp;ldquo;इरादे के साथ इतिहास डिजाइन करने&amp;rdquo; में बदल जाता है। रिबेस के सुनहरे नियम का पालन करते हुए, स्थिति के अनुसार सबसे उपयुक्त कमांड चुनें, और एक साफ़ कमिट इतिहास बनाएँ जिसे पूरी टीम के लिए पढ़ना और मेंटेन करना आसान हो।&lt;/p></description></item><item><title>GitHub Actions का उपयोग करके C++ प्रोजेक्ट के लिए CI/CD पाइपलाइन बनाना</title><link>http://kenji.blog/hi/p/github-actions-cpp-cicd-pipeline/</link><pubDate>Sat, 12 Sep 2026 18:00:00 +0900</pubDate><guid>http://kenji.blog/hi/p/github-actions-cpp-cicd-pipeline/</guid><description>&lt;img src="http://kenji.blog/p/github-actions-cpp-cicd-pipeline/img/eyecatch.jpg" alt="Featured image of post GitHub Actions का उपयोग करके C++ प्रोजेक्ट के लिए CI/CD पाइपलाइन बनाना" />&lt;h1 id="github-actions-क-उपयग-करक-c-परजकट-क-लए-cicd-पइपलइन-बनन-पर-गइड">GitHub Actions का उपयोग करके C++ प्रोजेक्ट के लिए CI/CD पाइपलाइन बनाना: पूरी गाइड
&lt;/h1>&lt;p>आधुनिक सॉफ्टवेयर विकास प्रतिमान में, निरंतर एकीकरण (Continuous Integration: CI) और निरंतर वितरण/परिनियोजन (Continuous Delivery/Deployment: CD) एक चुस्त (agile) विकास प्रक्रिया और उच्च गुणवत्ता वाले सॉफ्टवेयर को बनाए रखने के लिए आवश्यक तत्व हैं। कई प्रोग्रामिंग भाषाओं के अस्तित्व के बीच, C++ में CI/CD पाइपलाइन का निर्माण अन्य भाषाओं (जैसे Python, JavaScript, Go, आदि) की तुलना में अपनी अनूठी कठिनाइयों और जटिलताओं के साथ आता है।&lt;/p>
&lt;p>इस लेख में, हम बहुत विस्तार से बताएंगे कि GitHub Actions का उपयोग करके C++ प्रोजेक्ट्स के लिए स्क्रैच से एक मजबूत और व्यावहारिक CI/CD पाइपलाइन कैसे बनाई जाए। इसमें क्रॉस-प्लेटफॉर्म (Windows, Linux, macOS) पर मैट्रिक्स बिल्ड, CMake का उपयोग करके बिल्ड सिस्टम एकीकरण, CTest के साथ स्वचालित परीक्षण, स्थिर और गतिशील विश्लेषण (static and dynamic analysis) का स्वचालन, कवरेज मापन, और GitHub Releases के माध्यम से संकलित बाइनरी के स्वचालित वितरण जैसी सभी व्यावहारिक तकनीकें शामिल होंगी।&lt;/p>
&lt;h2 id="1-c-परजकटस-म-cicd-क-महतव-और-वशषट-चनतय">1. C++ प्रोजेक्ट्स में CI/CD का महत्व और विशिष्ट चुनौतियाँ
&lt;/h2>&lt;p>वेब एप्लिकेशन और स्क्रिप्टिंग भाषाओं के विकास में, एक सिंगल Docker कंटेनर पर परीक्षण और निर्माण (build) ज्यादातर मामलों में पर्याप्त होता है। हालांकि, C++ एक मूल रूप से संकलित (natively compiled) भाषा है, जो निष्पादन वातावरण (execution environment) के हार्डवेयर आर्किटेक्चर और ऑपरेटिंग सिस्टम पर अत्यधिक निर्भर करती है।&lt;/p>
&lt;p>C++ प्रोजेक्ट में CI/CD को लागू करते समय सामने आने वाली मुख्य चुनौतियाँ निम्नलिखित हैं:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>प्लेटफॉर्म की विविधता&lt;/strong>: Windows, Linux, और macOS जैसे विभिन्न ऑपरेटिंग सिस्टम में अलग-अलग API (Windows API, POSIX, आदि) होते हैं। यह आम बात है कि जो कोड डेवलपर के स्थानीय वातावरण (जैसे macOS) में काम करता है, वह Linux या Windows पर कंपाइल त्रुटि (compile error) दे दे।&lt;/li>
&lt;li>&lt;strong>कंपाइलर में अंतर&lt;/strong>: Microsoft Visual C++ (MSVC), GNU Compiler Collection (GCC), और Clang जैसे प्रमुख कंपाइलर C++ मानकों (C++17, C++20, C++23) के कार्यान्वयन, व्याख्या और चेतावनी की कठोरता में भिन्न होते हैं।&lt;/li>
&lt;li>&lt;strong>बिल्ड का समय&lt;/strong>: बड़े C++ प्रोजेक्ट्स में बिल्ड होने में दसियों मिनट से लेकर घंटों तक का समय लगना आम बात है। CI वातावरण में सीमित कंप्यूटिंग संसाधनों के साथ कुशलतापूर्वक बिल्ड करने के लिए कैशिंग रणनीतियों और समानांतरकरण (parallelization) की आवश्यकता होती है।&lt;/li>
&lt;li>&lt;strong>निर्भरता प्रबंधन (Dependency Management)&lt;/strong>: C++ में npm या pip जैसा कोई पूर्ण मानक पैकेज मैनेजर नहीं है। CI वातावरण में हर बार लाइब्रेरी को सही ढंग से हल करने के लिए vcpkg, Conan, या CMake के &lt;code>FetchContent&lt;/code> आदि का उपयोग करना आवश्यक है।&lt;/li>
&lt;li>&lt;strong>मेमोरी प्रबंधन और अपरिभाषित व्यवहार (Undefined Behavior)&lt;/strong>: चूँकि इसमें पॉइंटर हेरफेर और मैनुअल मेमोरी प्रबंधन शामिल होता है, इसलिए केवल तर्क का परीक्षण करना ही पर्याप्त नहीं है, बल्कि मेमोरी लीक और अपरिभाषित व्यवहार का पता लगाने को भी स्वचालित करना आवश्यक है।&lt;/li>
&lt;/ol>
&lt;p>इन चुनौतियों को हल करने के लिए, GitHub Actions सबसे अच्छा समाधान है, जो मांग (on-demand) पर विभिन्न OS वर्चुअल मशीनों को प्रोविजन कर सकता है, और जटिल वर्कफ़्लो को कोड के रूप में परिभाषित (Configuration as Code) कर सकता है।&lt;/p>
&lt;h2 id="2-cicd-पइपलइन-आरकटकचर-क-अवलकन">2. CI/CD पाइपलाइन आर्किटेक्चर का अवलोकन
&lt;/h2>&lt;p>आइए हम जिस CI/CD पाइपलाइन का निर्माण करने जा रहे हैं, उसकी समग्र तस्वीर की कल्पना करें। नीचे दिया गया Mermaid अनुक्रम आरेख (sequence diagram) कोड के Push से लेकर रिलीज़ तक के वर्कफ़्लो को दर्शाता है।&lt;/p>
&lt;pre class="mermaid">
sequenceDiagram
participant Dev as &amp;#34;डेवलपर&amp;#34;
participant Repo as &amp;#34;GitHub रिपॉजिटरी&amp;#34;
participant Action as &amp;#34;GitHub Actions CI/CD&amp;#34;
participant Rel as &amp;#34;GitHub रिलीज़&amp;#34;
Dev-&amp;gt;&amp;gt;Repo: &amp;#34;ब्रांच पुश करें / PR खोलें&amp;#34;
Repo-&amp;gt;&amp;gt;Action: &amp;#34;CI वर्कफ़्लो ट्रिगर करें&amp;#34;
activate Action
Action-&amp;gt;&amp;gt;Action: &amp;#34;लिंट और स्थिर विश्लेषण (Clang-Tidy)&amp;#34;
rect rgb(200, 220, 240)
note right of Action: &amp;#34;क्रॉस-प्लेटफॉर्म मैट्रिक्स बिल्ड&amp;#34;
Action-&amp;gt;&amp;gt;Action: &amp;#34;Ubuntu (GCC/Clang) पर बिल्ड करें&amp;#34;
Action-&amp;gt;&amp;gt;Action: &amp;#34;Windows (MSVC) पर बिल्ड करें&amp;#34;
Action-&amp;gt;&amp;gt;Action: &amp;#34;macOS (Apple Clang) पर बिल्ड करें&amp;#34;
end
Action-&amp;gt;&amp;gt;Action: &amp;#34;CTest चलाएं (ASAN/UBSAN के साथ)&amp;#34;
Action-&amp;gt;&amp;gt;Action: &amp;#34;कवरेज रिपोर्ट जनरेट करें&amp;#34;
alt &amp;#34;अगर टैग पुश किया गया (उदा., v1.0.0)&amp;#34;
Action-&amp;gt;&amp;gt;Action: &amp;#34;CPack के साथ बाइनरी पैक करें&amp;#34;
Action-&amp;gt;&amp;gt;Rel: &amp;#34;Release में ZIP/Tarball अपलोड करें&amp;#34;
end
deactivate Action
Repo--&amp;gt;&amp;gt;Dev: &amp;#34;CI स्थिति रिपोर्ट करें (Pass/Fail)&amp;#34;
&lt;/pre>
&lt;p>इस आर्किटेक्चर में, हम पुल रिक्वेस्ट (Pull Request) के चरण में तेज़ फीडबैक (स्थिर विश्लेषण और बिल्ड/टेस्ट) प्रदान करते हैं, और जब वर्जन टैग दिया जाता है, तब आउटपुट को पैक और वितरित किया जाता है।&lt;/p>
&lt;h2 id="3-आधनक-cmake-क-सथ-परजकट-सटअप">3. आधुनिक CMake के साथ प्रोजेक्ट सेटअप
&lt;/h2>&lt;p>एक उत्कृष्ट CI पाइपलाइन की नींव एक मजबूत बिल्ड सिस्टम है। हम CMake का उपयोग करेंगे, जो C++ के लिए वास्तविक मानक (de facto standard) है। यहाँ, हम &amp;ldquo;आधुनिक CMake&amp;rdquo; नामक लक्ष्य-उन्मुख (target-oriented) दृष्टिकोण अपनाएंगे।&lt;/p>
&lt;p>मान लें कि प्रोजेक्ट की निर्देशिका संरचना (directory structure) इस प्रकार है:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;span class="lnt">9
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">my_cpp_project/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── CMakeLists.txt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── src/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ ├── main.cpp
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ ├── calculator.cpp
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ └── calculator.h
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">└── tests/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ├── CMakeLists.txt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> └── test_calculator.cpp
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>रूट &lt;code>CMakeLists.txt&lt;/code> के लिए एक कॉन्फ़िगरेशन उदाहरण:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cmake" data-lang="cmake">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cmake_minimum_required&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">VERSION&lt;/span> &lt;span class="s">3.20&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">project&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MyCppProject&lt;/span> &lt;span class="s">VERSION&lt;/span> &lt;span class="s">1.0.0&lt;/span> &lt;span class="s">LANGUAGES&lt;/span> &lt;span class="s">CXX&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># C++ मानक सेटिंग
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CMAKE_CXX_STANDARD&lt;/span> &lt;span class="s">20&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CMAKE_CXX_STANDARD_REQUIRED&lt;/span> &lt;span class="s">ON&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CMAKE_CXX_EXTENSIONS&lt;/span> &lt;span class="s">OFF&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c"># पोर्टेबिलिटी बढ़ाने के लिए कंपाइलर-विशिष्ट एक्सटेंशन अक्षम करें
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># कंपाइलर चेतावनी को सख्त करना
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">function&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">set_project_warnings&lt;/span> &lt;span class="s">target_name&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MSVC&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">target_compile_options&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">${&lt;/span>&lt;span class="nv">target_name&lt;/span>&lt;span class="o">}&lt;/span> &lt;span class="s">PRIVATE&lt;/span> &lt;span class="s">/W4&lt;/span> &lt;span class="s">/WX&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">else&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">target_compile_options&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">${&lt;/span>&lt;span class="nv">target_name&lt;/span>&lt;span class="o">}&lt;/span> &lt;span class="s">PRIVATE&lt;/span> &lt;span class="s">-Wall&lt;/span> &lt;span class="s">-Wextra&lt;/span> &lt;span class="s">-Wpedantic&lt;/span> &lt;span class="s">-Werror&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">endif&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">endfunction&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># लाइब्रेरी लक्ष्य (target) बनाना
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">add_library&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CalculatorLib&lt;/span> &lt;span class="s">src/calculator.cpp&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">target_include_directories&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CalculatorLib&lt;/span> &lt;span class="s">PUBLIC&lt;/span> &lt;span class="o">${&lt;/span>&lt;span class="nv">CMAKE_CURRENT_SOURCE_DIR&lt;/span>&lt;span class="o">}&lt;/span>&lt;span class="s">/src&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">set_project_warnings&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CalculatorLib&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># एक्ज़ीक्यूटेबल लक्ष्य (target) बनाना
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">add_executable&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MyApplication&lt;/span> &lt;span class="s">src/main.cpp&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">target_link_libraries&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MyApplication&lt;/span> &lt;span class="s">PRIVATE&lt;/span> &lt;span class="s">CalculatorLib&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">set_project_warnings&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MyApplication&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># परीक्षण सक्षम करना
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">enable_testing&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">add_subdirectory&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">tests&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># इंस्टॉल नियम परिभाषित करना (CPack के लिए)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">include&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">GNUInstallDirs&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">install&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">TARGETS&lt;/span> &lt;span class="s">MyApplication&lt;/span> &lt;span class="s">CalculatorLib&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">RUNTIME&lt;/span> &lt;span class="s">DESTINATION&lt;/span> &lt;span class="o">${&lt;/span>&lt;span class="nv">CMAKE_INSTALL_BINDIR&lt;/span>&lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">LIBRARY&lt;/span> &lt;span class="s">DESTINATION&lt;/span> &lt;span class="o">${&lt;/span>&lt;span class="nv">CMAKE_INSTALL_LIBDIR&lt;/span>&lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">ARCHIVE&lt;/span> &lt;span class="s">DESTINATION&lt;/span> &lt;span class="o">${&lt;/span>&lt;span class="nv">CMAKE_INSTALL_LIBDIR&lt;/span>&lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># CPack द्वारा पैकेजिंग सेटिंग
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CPACK_PROJECT_NAME&lt;/span> &lt;span class="o">${&lt;/span>&lt;span class="nv">PROJECT_NAME&lt;/span>&lt;span class="o">}&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CPACK_PROJECT_VERSION&lt;/span> &lt;span class="o">${&lt;/span>&lt;span class="nv">PROJECT_VERSION&lt;/span>&lt;span class="o">}&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CPACK_GENERATOR&lt;/span> &lt;span class="s2">&amp;#34;ZIP;TGZ&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">WIN32&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CPACK_GENERATOR&lt;/span> &lt;span class="s2">&amp;#34;ZIP&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">endif&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">include&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CPack&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>महत्वपूर्ण बिंदु:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;code>CMAKE_CXX_EXTENSIONS OFF&lt;/code>: GNU एक्सटेंशन जैसी गैर-मानक विशेषताओं पर निर्भरता को रोकता है, जिससे क्रॉस-प्लेटफॉर्म संगतता (cross-platform compatibility) सुनिश्चित होती है।&lt;/li>
&lt;li>&lt;strong>चेतावनी को सख्त करना (&lt;code>-Werror&lt;/code> / &lt;code>/WX&lt;/code>)&lt;/strong>: CI वातावरण में कंपाइलर चेतावनियों को त्रुटियों के रूप में मानकर, उच्च कोड गुणवत्ता को सख्ती से बनाए रखा जाता है।&lt;/li>
&lt;li>&lt;strong>GNUInstallDirs&lt;/strong>: OS के अनुसार मानक इंस्टॉलेशन पथ (जैसे &lt;code>/usr/local/bin&lt;/code> या &lt;code>C:\Program Files&lt;/code>) को स्वचालित रूप से हल करता है।&lt;/li>
&lt;/ul>
&lt;h2 id="4-github-actions-क-मल-बत-और-मटरकस-रणनत">4. GitHub Actions की मूल बातें और मैट्रिक्स रणनीति
&lt;/h2>&lt;p>GitHub Actions को &lt;code>.github/workflows/&lt;/code> निर्देशिका में YAML फ़ाइलों द्वारा कॉन्फ़िगर किया जाता है।
C++ प्रोजेक्ट्स में सबसे शक्तिशाली विशेषता &amp;ldquo;मैट्रिक्स रणनीति (Matrix Strategy)&amp;rdquo; है। यह आपको OS और कंपाइलर संयोजनों को गतिशील रूप से उत्पन्न करने और उन्हें समानांतर में निष्पादित करने की अनुमति देता है।&lt;/p>
&lt;pre class="mermaid">
graph TD
A[&amp;#34;वर्कफ़्लो ट्रिगर करें&amp;#34;] --&amp;gt; B[&amp;#34;मैट्रिक्स जॉब मूल्यांकन&amp;#34;]
B --&amp;gt; C[&amp;#34;Ubuntu 22.04 (GCC 12)&amp;#34;]
B --&amp;gt; D[&amp;#34;Ubuntu 22.04 (Clang 15)&amp;#34;]
B --&amp;gt; E[&amp;#34;Windows Server 2022 (MSVC)&amp;#34;]
B --&amp;gt; F[&amp;#34;macOS 14 (Apple Clang)&amp;#34;]
&lt;/pre>
&lt;p>नीचे YAML जॉब परिभाषा दी गई है जो मैट्रिक्स बिल्ड के लिए आधार के रूप में कार्य करती है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">jobs&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">build&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Build &amp;amp; Test [${{ matrix.os }} - ${{ matrix.compiler }}]&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">runs-on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${{ matrix.os }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">strategy&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">fail-fast&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># अगर एक जॉब विफल हो जाता है, तो भी अन्य OS पर बिल्ड जारी रखें&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">matrix&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">include&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">os&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ubuntu-latest&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">gcc&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">c_compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">gcc&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">cpp_compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">g++&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">os&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ubuntu-latest&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">clang&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">c_compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">clang&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">cpp_compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">clang++&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">os&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">windows-latest&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">msvc&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">c_compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cl&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">cpp_compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cl&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">os&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">macos-latest&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">apple-clang&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">c_compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">clang&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">cpp_compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">clang++&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;code>fail-fast: false&lt;/code> बहुत महत्वपूर्ण है। उदाहरण के लिए, यदि आप गलती से Linux-विशिष्ट API का उपयोग करते हैं, तो Ubuntu बिल्ड विफल हो जाएगा, लेकिन आप यह भी जाँचना चाहेंगे कि क्या Windows बिल्ड उसी समय सफल होता है या नहीं।&lt;/p>
&lt;h2 id="5-बलड-लगत-और-अमदल-क-नयम-amdahls-law-क-उपयग-करक-समनतर-परससकरण-क-अनकलन">5. बिल्ड लागत और अमदाल के नियम (Amdahl&amp;rsquo;s Law) का उपयोग करके समानांतर प्रसंस्करण का अनुकूलन
&lt;/h2>&lt;p>क्लाउड वातावरण में CI/CD समय के खिलाफ एक दौड़ है, और बिल्ड का समय सीधे डेवलपर्स के प्रतीक्षा समय और रनिंग कॉस्ट से जुड़ा है।
यहाँ, आइए कंप्यूटर विज्ञान में &amp;ldquo;अमदाल के नियम (Amdahl&amp;rsquo;s Law)&amp;rdquo; का उपयोग करके बिल्ड समय के अनुकूलन के लिए एक गणितीय दृष्टिकोण अपनाएं।&lt;/p>
&lt;p>अमदाल का नियम एक प्रोग्राम में समानांतर किए जा सकने वाले हिस्से के अनुपात को $P$ के रूप में परिभाषित करता है, और $N$ प्रोसेसर का उपयोग करते समय सैद्धांतिक अधिकतम गति वृद्धि $S(N)$ को निम्नानुसार परिभाषित करता है:&lt;/p>
$$ S(N) = \frac{1}{(1 - P) + \frac{P}{N}} $$&lt;p>C++ बिल्ड प्रक्रिया में, स्रोत कोड के प्रत्येक अनुवाद इकाई (Translation Unit: &lt;code>.cpp&lt;/code> फ़ाइल) का संकलन (compilation) पूरी तरह से स्वतंत्र है और इसे समानांतर किया जा सकता है। दूसरी ओर, CMake कॉन्फ़िगरेशन और अंतिम बाइनरी का लिंक चरण मूल रूप से क्रमिक (समानांतर करने योग्य नहीं) होते हैं।&lt;/p>
&lt;p>मान लीजिए कि कुल प्रोजेक्ट बिल्ड समय का 80% संकलन चरण ($P = 0.8$) है और 20% क्रमिक चरण ($1 - P = 0.2$) है।
GitHub Actions मानक धावक (standard runner) (Linux) 2 कोर (थ्रेड्स) प्रदान करता है। इसलिए जब $N = 2$:&lt;/p>
$$ S(2) = \frac{1}{0.2 + \frac{0.8}{2}} = \frac{1}{0.2 + 0.4} = \frac{1}{0.6} \approx 1.67 $$&lt;p>केवल 2 कोर का उपयोग करके, आपको गति में लगभग 1.67 गुना सुधार मिलता है। इसे प्राप्त करने के लिए, CMake बिल्ड कमांड में &lt;code>--parallel&lt;/code> विकल्प निर्दिष्ट करना आवश्यक है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;प्रोजेक्ट बिल्ड करें&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cmake --build build --config Release --parallel 2&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इसके अलावा, हम लागत गणना पर भी विचार करते हैं। GitHub Actions के उपयोग की कुल लागत $C_{total}$, जॉब निष्पादन समय $T_i$ और रनर की इकाई लागत (unit price) $R_i$ के गुणनफल का योग है।&lt;/p>
$$ C_{total} = \sum_{i=1}^{M} \left( T_i \times R_i \right) $$&lt;p>बिल्ड समय कम करने से न केवल फीडबैक लूप तेज़ होता है, बल्कि प्रोजेक्ट की परिचालन लागत (विशेष रूप से निजी रिपॉजिटरी के लिए) भी सीधे कम होती है। यदि आप इसे और तेज़ करना चाहते हैं, तो संकलन परिणामों को कैश करने के लिए &lt;code>ccache&lt;/code> का उपयोग करना एक प्रभावी तरीका है।&lt;/p>
&lt;h2 id="6-सवचलत-परकषण-और-सनटइजर-sanitizers-क-एककरण">6. स्वचालित परीक्षण और सैनिटाइज़र (Sanitizers) का एकीकरण
&lt;/h2>&lt;p>C++ में बग्स को रोकने के लिए, यूनिट परीक्षणों के अलावा, रनटाइम पर मेमोरी लीक और अपरिभाषित व्यवहार का पता लगाने वाले &amp;ldquo;सैनिटाइज़र&amp;rdquo; को शामिल करने की दृढ़ता से अनुशंसा की जाती है। हम Google द्वारा विकसित AddressSanitizer (ASAN) और UndefinedBehaviorSanitizer (UBSAN) का उपयोग करेंगे।&lt;/p>
&lt;p>CMake में सैनिटाइज़र को सक्षम करने के लिए एक विकल्प जोड़ें।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cmake" data-lang="cmake">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">option&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">ENABLE_SANITIZERS&lt;/span> &lt;span class="s2">&amp;#34;ASAN और UBSAN सक्षम करें&amp;#34;&lt;/span> &lt;span class="s">OFF&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">ENABLE_SANITIZERS&lt;/span> &lt;span class="s">AND&lt;/span> &lt;span class="s">CMAKE_CXX_COMPILER_ID&lt;/span> &lt;span class="s">MATCHES&lt;/span> &lt;span class="s2">&amp;#34;GNU|Clang&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">add_compile_options&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">-fsanitize=address,undefined&lt;/span> &lt;span class="s">-fno-omit-frame-pointer&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">add_link_options&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">-fsanitize=address,undefined&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">endif&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>CI पाइपलाइन के Ubuntu जॉब में इस विकल्प को सक्षम करके परीक्षण चलाएं।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;CMake कॉन्फ़िगर करें&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">env&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">CC&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${{ matrix.c_compiler }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">CXX&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${{ matrix.cpp_compiler }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">&amp;gt;&lt;/span>&lt;span class="sd">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> cmake -B build
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> -DCMAKE_BUILD_TYPE=Release
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> -DENABLE_SANITIZERS=${{ matrix.os == &amp;#39;ubuntu-latest&amp;#39; &amp;amp;&amp;amp; &amp;#39;ON&amp;#39; || &amp;#39;OFF&amp;#39; }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;CTest चलाएं&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">working-directory&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">build&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">env&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">ASAN_OPTIONS&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;detect_leaks=1:symbolize=1&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">UBSAN_OPTIONS&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;print_stacktrace=1&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ctest --build-config Release --output-on-failure --parallel 2&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>परीक्षण निष्पादित करने के लिए &lt;code>ctest&lt;/code> कमांड का उपयोग किया जाता है। &lt;code>--output-on-failure&lt;/code> निर्दिष्ट करके, केवल विफल परीक्षणों के विस्तृत लॉग CI आउटपुट में प्रदर्शित किए जाएंगे, जिससे लॉग को बहुत बड़ा होने से रोका जा सकेगा।&lt;/p>
&lt;h2 id="7-कवरज-कड-कवरज-रट-मपन">7. कवरेज (कोड कवरेज रेट) मापना
&lt;/h2>&lt;p>गुणवत्ता आश्वासन के लिए यह कल्पना करना महत्वपूर्ण है कि परीक्षण कितने कोड को कवर करते हैं। हम Linux वातावरण (GCC) का उपयोग करके &lt;code>gcov&lt;/code> और &lt;code>lcov&lt;/code> के साथ कवरेज को मापेंगे।&lt;/p>
&lt;p>सबसे पहले, CMake में कवरेज मापन के लिए संकलन झंडे (compile flags) सेट करें।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cmake" data-lang="cmake">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">option&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">ENABLE_COVERAGE&lt;/span> &lt;span class="s2">&amp;#34;कवरेज रिपोर्टिंग सक्षम करें&amp;#34;&lt;/span> &lt;span class="s">OFF&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">ENABLE_COVERAGE&lt;/span> &lt;span class="s">AND&lt;/span> &lt;span class="s">CMAKE_CXX_COMPILER_ID&lt;/span> &lt;span class="s">STREQUAL&lt;/span> &lt;span class="s2">&amp;#34;GNU&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">add_compile_options&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">--coverage&lt;/span> &lt;span class="s">-O0&lt;/span> &lt;span class="s">-g&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">add_link_options&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">--coverage&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">endif&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>GitHub Actions में कवरेज मापने के लिए एक स्वतंत्र जॉब परिभाषित करें।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">coverage&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Test Coverage Analysis&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">runs-on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ubuntu-latest&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">steps&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">actions/checkout@v4&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;lcov इंस्टॉल करें&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">sudo apt-get update &amp;amp;&amp;amp; sudo apt-get install -y lcov&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;कवरेज के लिए CMake कॉन्फ़िगर करें&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cmake -B build -DCMAKE_BUILD_TYPE=Debug -DENABLE_COVERAGE=ON&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;बिल्ड और टेस्ट&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="sd">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> cmake --build build --parallel 2
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> cd build &amp;amp;&amp;amp; ctest --output-on-failure&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;lcov रिपोर्ट जनरेट करें&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">working-directory&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">build&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="sd">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> lcov --capture --directory . --output-file coverage.info
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> lcov --remove coverage.info &amp;#39;/usr/*&amp;#39; &amp;#39;*_deps/*&amp;#39; &amp;#39;*tests/*&amp;#39; --output-file coverage.info
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> &lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Codecov पर कवरेज अपलोड करें&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">codecov/codecov-action@v3&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">files&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">build/coverage.info&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;code>lcov --remove&lt;/code> कमांड का उपयोग करके, सिस्टम हेडर, थर्ड-पार्टी लाइब्रेरी और टेस्ट कोड को ही कवरेज मापन से बाहर रखा गया है। इससे आप प्रोजेक्ट के विशिष्ट स्रोत कोड का शुद्ध कवरेज प्राप्त कर सकते हैं।&lt;/p>
&lt;h2 id="8-github-releases-क-मधयम-स-बइनर-क-सवचलत-डलवर-cd">8. GitHub Releases के माध्यम से बाइनरी की स्वचालित डिलीवरी (CD)
&lt;/h2>&lt;p>आइए CI/CD के &amp;ldquo;CD&amp;rdquo; भाग का निर्माण करें। जब कोई डेवलपर गिट में संस्करण टैग (उदाहरण: &lt;code>v1.2.0&lt;/code>) जोड़ता है और उसे पुश करता है, तो यह स्वचालित रूप से प्रत्येक OS के लिए निष्पादन योग्य (executable) बाइनरी संकलित करेगा, उन्हें ZIP या Tarball में पैक करेगा, और उन्हें GitHub Releases पर अपलोड करेगा।&lt;/p>
&lt;p>इस चरण में, हम CMake के साथ शामिल पैकेजिंग टूल &lt;code>CPack&lt;/code> का उपयोग करेंगे।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;एप्लिकेशन पैकेज करें (CPack)&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">if&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">startsWith(github.ref, &amp;#39;refs/tags/v&amp;#39;)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">working-directory&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">build&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cpack -C Release -V&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;रिलीज़ एसेट्स अपलोड करें&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">if&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">startsWith(github.ref, &amp;#39;refs/tags/v&amp;#39;)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">softprops/action-gh-release@v1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">files&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="sd">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> build/*.tar.gz
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> build/*.zip
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> build/*.sh
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> build/*.exe&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">env&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">GITHUB_TOKEN&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${{ secrets.GITHUB_TOKEN }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इस सेटिंग के साथ, केवल &lt;code>git tag v1.0.0&lt;/code> और &lt;code>git push origin v1.0.0&lt;/code> को निष्पादित करने से, बिना किसी मानवीय हस्तक्षेप के, Windows उपयोगकर्ताओं के लिए ZIP फ़ाइलें और Linux/macOS उपयोगकर्ताओं के लिए Tarball स्वचालित रूप से रिलीज़ पेज पर प्रकाशित हो जाएँगी। उपयोगकर्ताओं तक सॉफ़्टवेयर पहुँचाने के लिए यह एक अत्यंत शक्तिशाली विशेषता है।&lt;/p>
&lt;h2 id="9-परण-workflow-yaml-फइल">9. पूर्ण Workflow YAML फ़ाइल
&lt;/h2>&lt;p>अब तक बताए गए सभी तत्वों को एकीकृत करते हुए एक मजबूत और व्यावहारिक &lt;code>.github/workflows/main.yml&lt;/code> का पूर्ण कोड नीचे दिया गया है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt"> 10
&lt;/span>&lt;span class="lnt"> 11
&lt;/span>&lt;span class="lnt"> 12
&lt;/span>&lt;span class="lnt"> 13
&lt;/span>&lt;span class="lnt"> 14
&lt;/span>&lt;span class="lnt"> 15
&lt;/span>&lt;span class="lnt"> 16
&lt;/span>&lt;span class="lnt"> 17
&lt;/span>&lt;span class="lnt"> 18
&lt;/span>&lt;span class="lnt"> 19
&lt;/span>&lt;span class="lnt"> 20
&lt;/span>&lt;span class="lnt"> 21
&lt;/span>&lt;span class="lnt"> 22
&lt;/span>&lt;span class="lnt"> 23
&lt;/span>&lt;span class="lnt"> 24
&lt;/span>&lt;span class="lnt"> 25
&lt;/span>&lt;span class="lnt"> 26
&lt;/span>&lt;span class="lnt"> 27
&lt;/span>&lt;span class="lnt"> 28
&lt;/span>&lt;span class="lnt"> 29
&lt;/span>&lt;span class="lnt"> 30
&lt;/span>&lt;span class="lnt"> 31
&lt;/span>&lt;span class="lnt"> 32
&lt;/span>&lt;span class="lnt"> 33
&lt;/span>&lt;span class="lnt"> 34
&lt;/span>&lt;span class="lnt"> 35
&lt;/span>&lt;span class="lnt"> 36
&lt;/span>&lt;span class="lnt"> 37
&lt;/span>&lt;span class="lnt"> 38
&lt;/span>&lt;span class="lnt"> 39
&lt;/span>&lt;span class="lnt"> 40
&lt;/span>&lt;span class="lnt"> 41
&lt;/span>&lt;span class="lnt"> 42
&lt;/span>&lt;span class="lnt"> 43
&lt;/span>&lt;span class="lnt"> 44
&lt;/span>&lt;span class="lnt"> 45
&lt;/span>&lt;span class="lnt"> 46
&lt;/span>&lt;span class="lnt"> 47
&lt;/span>&lt;span class="lnt"> 48
&lt;/span>&lt;span class="lnt"> 49
&lt;/span>&lt;span class="lnt"> 50
&lt;/span>&lt;span class="lnt"> 51
&lt;/span>&lt;span class="lnt"> 52
&lt;/span>&lt;span class="lnt"> 53
&lt;/span>&lt;span class="lnt"> 54
&lt;/span>&lt;span class="lnt"> 55
&lt;/span>&lt;span class="lnt"> 56
&lt;/span>&lt;span class="lnt"> 57
&lt;/span>&lt;span class="lnt"> 58
&lt;/span>&lt;span class="lnt"> 59
&lt;/span>&lt;span class="lnt"> 60
&lt;/span>&lt;span class="lnt"> 61
&lt;/span>&lt;span class="lnt"> 62
&lt;/span>&lt;span class="lnt"> 63
&lt;/span>&lt;span class="lnt"> 64
&lt;/span>&lt;span class="lnt"> 65
&lt;/span>&lt;span class="lnt"> 66
&lt;/span>&lt;span class="lnt"> 67
&lt;/span>&lt;span class="lnt"> 68
&lt;/span>&lt;span class="lnt"> 69
&lt;/span>&lt;span class="lnt"> 70
&lt;/span>&lt;span class="lnt"> 71
&lt;/span>&lt;span class="lnt"> 72
&lt;/span>&lt;span class="lnt"> 73
&lt;/span>&lt;span class="lnt"> 74
&lt;/span>&lt;span class="lnt"> 75
&lt;/span>&lt;span class="lnt"> 76
&lt;/span>&lt;span class="lnt"> 77
&lt;/span>&lt;span class="lnt"> 78
&lt;/span>&lt;span class="lnt"> 79
&lt;/span>&lt;span class="lnt"> 80
&lt;/span>&lt;span class="lnt"> 81
&lt;/span>&lt;span class="lnt"> 82
&lt;/span>&lt;span class="lnt"> 83
&lt;/span>&lt;span class="lnt"> 84
&lt;/span>&lt;span class="lnt"> 85
&lt;/span>&lt;span class="lnt"> 86
&lt;/span>&lt;span class="lnt"> 87
&lt;/span>&lt;span class="lnt"> 88
&lt;/span>&lt;span class="lnt"> 89
&lt;/span>&lt;span class="lnt"> 90
&lt;/span>&lt;span class="lnt"> 91
&lt;/span>&lt;span class="lnt"> 92
&lt;/span>&lt;span class="lnt"> 93
&lt;/span>&lt;span class="lnt"> 94
&lt;/span>&lt;span class="lnt"> 95
&lt;/span>&lt;span class="lnt"> 96
&lt;/span>&lt;span class="lnt"> 97
&lt;/span>&lt;span class="lnt"> 98
&lt;/span>&lt;span class="lnt"> 99
&lt;/span>&lt;span class="lnt">100
&lt;/span>&lt;span class="lnt">101
&lt;/span>&lt;span class="lnt">102
&lt;/span>&lt;span class="lnt">103
&lt;/span>&lt;span class="lnt">104
&lt;/span>&lt;span class="lnt">105
&lt;/span>&lt;span class="lnt">106
&lt;/span>&lt;span class="lnt">107
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;C++ CI/CD Pipeline&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">push&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">branches&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;main&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;develop&amp;#34;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">tags&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;v*.*.*&amp;#34;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">pull_request&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">branches&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;main&amp;#34;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">env&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">BUILD_TYPE&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Release&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">jobs&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">build-and-test&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Build [${{ matrix.os }} | ${{ matrix.compiler }}]&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">runs-on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${{ matrix.os }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">strategy&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">fail-fast&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">matrix&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">include&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">os&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ubuntu-latest&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">gcc&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">c_compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">gcc&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">cpp_compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">g++&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">os&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ubuntu-latest&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">clang&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">c_compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">clang&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">cpp_compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">clang++&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">os&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">windows-latest&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">msvc&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">c_compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cl&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">cpp_compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cl&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">os&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">macos-latest&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">apple-clang&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">c_compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">clang&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">cpp_compiler&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">clang++&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">steps&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;रिपॉजिटरी चेकआउट करें&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">actions/checkout@v4&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;CMake कॉन्फ़िगर करें&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">env&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">CC&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${{ matrix.c_compiler }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">CXX&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${{ matrix.cpp_compiler }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">&amp;gt;&lt;/span>&lt;span class="sd">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> cmake -B build
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }}
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> -DENABLE_SANITIZERS=${{ matrix.os == &amp;#39;ubuntu-latest&amp;#39; &amp;amp;&amp;amp; &amp;#39;ON&amp;#39; || &amp;#39;OFF&amp;#39; }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;प्रोजेक्ट बिल्ड करें&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cmake --build build --config ${{ env.BUILD_TYPE }} --parallel 2&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;यूनिट टेस्ट चलाएं (CTest)&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">working-directory&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">build&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">env&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">ASAN_OPTIONS&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;detect_leaks=1:symbolize=1&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">UBSAN_OPTIONS&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;print_stacktrace=1&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ctest --build-config ${{ env.BUILD_TYPE }} --output-on-failure --parallel 2&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;CPack के साथ पैकेज करें&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">if&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">startsWith(github.ref, &amp;#39;refs/tags/v&amp;#39;)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">working-directory&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">build&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cpack -C ${{ env.BUILD_TYPE }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;GitHub रिलीज़ बनाएं और एसेट्स अपलोड करें&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">if&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">startsWith(github.ref, &amp;#39;refs/tags/v&amp;#39;)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">softprops/action-gh-release@v1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">files&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="sd">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> build/*.tar.gz
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> build/*.zip&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">env&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">GITHUB_TOKEN&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${{ secrets.GITHUB_TOKEN }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">coverage&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Code Coverage Analysis&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">runs-on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ubuntu-latest&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">if&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">github.event_name == &amp;#39;pull_request&amp;#39; || github.ref == &amp;#39;refs/heads/main&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">steps&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;रिपॉजिटरी चेकआउट करें&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">actions/checkout@v4&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;lcov इंस्टॉल करें&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">sudo apt-get update &amp;amp;&amp;amp; sudo apt-get install -y lcov&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;कवरेज के लिए CMake कॉन्फ़िगर करें&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cmake -B build -DCMAKE_BUILD_TYPE=Debug -DENABLE_COVERAGE=ON&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;प्रोजेक्ट बिल्ड करें&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">cmake --build build --parallel 2&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;टेस्ट चलाएं&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">working-directory&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">build&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ctest --output-on-failure&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;lcov रिपोर्ट जनरेट करें&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">working-directory&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">build&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="sd">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> lcov --capture --directory . --output-file coverage.info
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> lcov --remove coverage.info &amp;#39;/usr/*&amp;#39; &amp;#39;*_deps/*&amp;#39; &amp;#39;*tests/*&amp;#39; --output-file coverage.info
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> &lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Codecov पर कवरेज अपलोड करें&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">codecov/codecov-action@v3&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">files&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">build/coverage.info&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">fail_ci_if_error&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="10-अधक-उननत-cicd-क-ओर-सथर-वशलषण-और-सवरपण">10. अधिक उन्नत CI/CD की ओर (स्थिर विश्लेषण और स्वरूपण)
&lt;/h2>&lt;p>यद्यपि हम यहाँ विस्तृत व्याख्या छोड़ रहे हैं, वास्तविक उत्पादन में पाइपलाइन में अतिरिक्त गुणवत्ता आश्वासन उपकरणों को शामिल करने की अनुशंसा की जाती है।&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Clang-Format को बाध्य करना&lt;/strong>: कोड समीक्षा के बोझ को कम करने के लिए, &lt;code>clang-format&lt;/code> का उपयोग करके कोड शैली जाँच को CI में एकीकृत करें, और यदि स्वरूपण (formatting) नियमों का उल्लंघन होता है तो पाइपलाइन को विफल करें।&lt;/li>
&lt;li>&lt;strong>स्थिर विश्लेषण (Clang-Tidy)&lt;/strong>: &lt;code>clang-tidy&lt;/code> को CMake में एकीकृत करें और इसे CI पर चलाएं ताकि संभावित बग्स और अकुशल कोड (जैसे अनावश्यक प्रतियां) का पता लगाया जा सके जिन्हें अकेले कंपाइलर चेतावनियों द्वारा नहीं रोका जा सकता है।&lt;/li>
&lt;li>&lt;strong>vcpkg / Conan कैश का उपयोग&lt;/strong>: यदि आप कई थर्ड-पार्टी लाइब्रेरी का उपयोग करते हैं, तो निर्भरताएँ बनाने (build dependencies) में लंबा समय लगता है। GitHub Actions के &lt;code>actions/cache&lt;/code> का उपयोग करके, vcpkg की इंस्टॉल की गई निर्देशिका या Conan के कैश को बनाए रखकर बिल्ड समय को काफी कम किया जा सकता है।&lt;/li>
&lt;/ol>
&lt;h2 id="नषकरष">निष्कर्ष
&lt;/h2>&lt;p>C++ प्रोजेक्ट्स में CI/CD पाइपलाइन बनाना प्लेटफ़ॉर्म निर्भरताओं और बिल्ड टूल्स की जटिलता के कारण पहली नज़र में एक बड़ी बाधा लग सकता है। हालाँकि, GitHub Actions, आधुनिक CMake, और CTest/CPack इकोसिस्टम को सही ढंग से संयोजित करके, आप एक अत्यधिक शक्तिशाली और स्वचालित विकास प्रवाह (development flow) प्राप्त कर सकते हैं।&lt;/p>
&lt;p>इस लेख में चर्चा की गई मैट्रिक्स रणनीति के साथ क्रॉस-प्लेटफॉर्म सत्यापन, सैनिटाइज़र के साथ रनटाइम बग्स का पता लगाना, कवरेज मापन, और GitHub Releases पर स्वचालित परिनियोजन (deployment) ऐसी सर्वोत्तम प्रथाएं (best practices) हैं जो वाणिज्यिक स्तर के ओपन-सोर्स प्रोजेक्ट्स में व्यापक रूप से अपनाई जाती हैं।&lt;/p>
&lt;p>एक स्वचालित CI/CD पाइपलाइन एक शक्तिशाली हथियार है जो डेवलपर्स द्वारा &amp;ldquo;बग खोजने&amp;rdquo; और &amp;ldquo;मैनुअल बिल्ड और रिलीज़ कार्यों&amp;rdquo; में बिताए गए समय को कम करता है, जिससे उन्हें अपनी मुख्य रचनात्मक कोडिंग गतिविधियों पर ध्यान केंद्रित करने की अनुमति मिलती है। कृपया इसे अपने C++ प्रोजेक्ट में लागू करें और एक चुस्त और सुरक्षित विकास जीवन प्राप्त करें।&lt;/p></description></item><item><title>Cloudflare Pages या GitHub Pages पर Hugo ब्लॉग को मुफ़्त और बहुत तेज़ी से कैसे होस्ट करें</title><link>http://kenji.blog/hi/p/hugo-hosting-cloudflare-vs-github-pages/</link><pubDate>Sat, 12 Sep 2026 12:00:00 +0900</pubDate><guid>http://kenji.blog/hi/p/hugo-hosting-cloudflare-vs-github-pages/</guid><description>&lt;img src="http://kenji.blog/p/hugo-hosting-cloudflare-vs-github-pages/img/eyecatch.jpg" alt="Featured image of post Cloudflare Pages या GitHub Pages पर Hugo ब्लॉग को मुफ़्त और बहुत तेज़ी से कैसे होस्ट करें" />&lt;p>Webसाइट या ब्लॉग को चलाने में, प्रदर्शन (लोडिंग स्पीड), संचालन लागत, और सुरक्षा बहुत महत्वपूर्ण कारक हैं। अतीत में, WordPress जैसे डायनेमिक CMS (कंटेंट मैनेजमेंट सिस्टम) और रेंटल सर्वर का संयोजन मुख्यधारा था, लेकिन वर्तमान में &amp;ldquo;Jamstack&amp;rdquo; नामक आर्किटेक्चर बहुत ध्यान आकर्षित कर रहा है। उनमें से, Go भाषा में बने एक सुपर फास्ट स्टैटिक साइट जनरेटर (SSG) &amp;ldquo;Hugo&amp;rdquo; और Cloudflare Pages या GitHub Pages जैसी आधुनिक होस्टिंग सेवाओं को मिलाकर, &lt;strong>पूरी तरह से मुफ़्त और सुपर-फ़ास्ट&lt;/strong> ब्लॉग वातावरण बनाना संभव है।&lt;/p>
&lt;p>इस लेख में, हम Hugo का उपयोग करके बनी स्टैटिक साइट को Cloudflare Pages या GitHub Pages पर पब्लिश करने के विशिष्ट चरण, प्रत्येक प्लेटफ़ॉर्म के आर्किटेक्चर के बीच अंतर, GitHub Actions का उपयोग करके CI/CD (निरंतर एकीकरण / निरंतर परिनियोजन) का निर्माण, DNS का अनुकूलन, कैशिंग रणनीति, और गोपनीयता को ध्यान में रखते हुए एक्सेस एनालिटिक्स को लागू करने तक के तकनीकी दृष्टिकोण से बहुत गहराई से समझाएंगे।&lt;/p>
&lt;hr>
&lt;h2 id="1-सटटक-सइट-जनरटर-ssg-और-jamstack-क-मल-सदधत">1. स्टैटिक साइट जनरेटर (SSG) और Jamstack के मूल सिद्धांत
&lt;/h2>&lt;h3 id="11-सटटक-सइट-कय">1.1 स्टैटिक साइट क्यों?
&lt;/h3>&lt;p>पारंपरिक डायनेमिक CMS (उदा: WordPress) उपयोगकर्ताओं के हर अनुरोध पर डेटाबेस (जैसे MySQL) पर क्वेरी भेजते हैं, और सर्वर-साइड (जैसे PHP) पर गतिशील रूप से HTML जनरेट करके वापस करते हैं। यह दृष्टिकोण बहुत लचीला है, लेकिन ट्रैफ़िक में अचानक वृद्धि (जैसे कि बज़ या DDoS हमले) के खिलाफ इसकी सहनशीलता कम है, और बुनियादी ढांचा (इन्फ्रास्ट्रक्चर) जटिल हो जाता है, जैसे कि सामने एक कैश सर्वर (Redis या Varnish) रखना पड़ता है।&lt;/p>
&lt;p>दूसरी ओर, Jamstack (JavaScript, APIs, and Markup) आर्किटेक्चर को अपनाने वाले स्टैटिक साइट जनरेटर्स (SSG) में, सभी HTML फ़ाइलें, CSS और JavaScript पहले से (बिल्ड के समय) जनरेट कर लिए जाते हैं। उपयोगकर्ता के अनुरोधों के लिए, वेब सर्वर (या CDN) पहले से जनरेट की गई स्टैटिक फ़ाइलों को सीधे वापस कर देता है, जिससे अभूतपूर्व गति और मजबूत सुरक्षा प्राप्त होती है।&lt;/p>
&lt;h3 id="12-hugo-क-शरषठत">1.2 Hugo की श्रेष्ठता
&lt;/h3>&lt;p>SSG में Next.js, Gatsby, Jekyll, Astro जैसे कई विकल्प हैं, लेकिन Hugo की सबसे बड़ी विशेषता इसकी &lt;strong>बिल्ड स्पीड&lt;/strong> है। Go भाषा की समवर्ती प्रसंस्करण (कंकरेंसी) का लाभ उठाते हुए, हजारों से लेकर हजारों पेजों वाली साइटों को भी कुछ ही सेकंड में बिल्ड किया जा सकता है। यह CI/CD पाइपलाइन में प्रतीक्षा समय को काफी कम करता है और सीधे डेवलपर अनुभव (DX: Developer Experience) को बेहतर बनाता है।&lt;/p>
&lt;hr>
&lt;h2 id="2-हसटग-सवओ-क-आरकटकचर-क-तलन">2. होस्टिंग सेवाओं के आर्किटेक्चर की तुलना
&lt;/h2>&lt;p>Hugo द्वारा जनरेट की गई स्टैटिक फ़ाइलों को कहाँ होस्ट करना है, यह अगला काम है। प्रतिनिधि विकल्पों के रूप में Cloudflare Pages, GitHub Pages और Netlify शामिल हैं, लेकिन इनके पीछे का नेटवर्क आर्किटेक्चर अलग-अलग है।&lt;/p>
&lt;h3 id="21-cdn-और-एज-कपयटग">2.1 CDN और एज कंप्यूटिंग
&lt;/h3>&lt;p>ये सभी प्लेटफ़ॉर्म वैश्विक रूप से वितरित CDN (कंटेंट डिलीवरी नेटवर्क) का उपयोग करके कंटेंट वितरित करते हैं। हालाँकि, केवल स्टैटिक फ़ाइलों को कैश करने के अलावा, उपयोगकर्ता के सबसे नज़दीकी PoP (Point of Presence) पर अनुरोधों की रूटिंग और हेडर को फिर से लिखने के लिए &amp;ldquo;एज कंप्यूटिंग&amp;rdquo; का निष्पादन एक महत्वपूर्ण विभेदक कारक बन गया है।&lt;/p>
&lt;pre class="mermaid">
graph TD
A[&amp;#34;उपयोगकर्ता (टोक्यो)&amp;#34;] --&amp;gt;|कम विलंबता (Low Latency)| B[&amp;#34;एज नोड (NRT)&amp;#34;]
C[&amp;#34;उपयोगकर्ता (न्यूयॉर्क)&amp;#34;] --&amp;gt;|कम विलंबता (Low Latency)| D[&amp;#34;एज नोड (EWR)&amp;#34;]
E[&amp;#34;उपयोगकर्ता (लंदन)&amp;#34;] --&amp;gt;|कम विलंबता (Low Latency)| F[&amp;#34;एज नोड (LHR)&amp;#34;]
B --&amp;gt; G[&amp;#34;ओरिजिन स्टोरेज / ऑब्जेक्ट स्टोर&amp;#34;]
D --&amp;gt; G
F --&amp;gt; G
&lt;/pre>
&lt;h3 id="22-github-pages">2.2 GitHub Pages
&lt;/h3>&lt;p>GitHub Pages एक ऐसी सेवा है जो आपको सीधे GitHub रिपॉजिटरी से HTML, CSS और JavaScript फ़ाइलों को प्रकाशित करने की अनुमति देती है। इसके पीछे Fastly जैसे CDN का उपयोग किया जाता है, जो पर्याप्त प्रदर्शन देता है। हालाँकि, हेडर के कस्टमाइज़ेशन (उदा: &lt;code>Cache-Control&lt;/code> और सुरक्षा हेडर की सेटिंग) पर प्रतिबंध हैं, और रीडायरेक्ट सेटिंग्स के लिए HTML के meta refresh या Jekyll प्लगइन्स पर निर्भरता जैसी सीमाएँ हैं, इसलिए एक शुद्ध बुनियादी ढांचे के रूप में इसके कार्य थोड़े सीमित हैं।&lt;/p>
&lt;h3 id="23-cloudflare-pages">2.3 Cloudflare Pages
&lt;/h3>&lt;p>Cloudflare Pages एक स्टैटिक साइट होस्टिंग सेवा है जो Cloudflare के दुनिया के सबसे बड़े Anycast नेटवर्क (275 से अधिक शहरों में फैला) के ऊपर बनाई गई है।
HTTP/3 (QUIC) का मानक समर्थन, इमेज ऑप्टिमाइज़ेशन, एज फंक्शंस (Cloudflare Workers) का एकीकरण, आदि जैसी जबरदस्त प्रदर्शन ट्यूनिंग संभव है। इसके अलावा, बैंडविड्थ के लिए कोई शुल्क नहीं है, जिसका अर्थ है कि ट्रैफ़िक कितना भी बढ़ जाए, इसे मुफ़्त में संचालित किया जा सकता है, जो एक बहुत बड़ा फायदा है।&lt;/p>
&lt;h3 id="24-netlify">2.4 Netlify
&lt;/h3>&lt;p>Netlify Jamstack का अग्रणी (पायनियर) है, और यह फॉर्म कार्यक्षमता, प्रमाणीकरण (Identity), सर्वरलेस फ़ंक्शंस आदि को एकीकृत करने वाला ऑल-इन-वन DX प्रदान करता है। हालाँकि, यदि आप मुफ़्त टियर बैंडविड्थ (100GB/माह) को पार करते हैं, तो उच्च पे-एज-यू-गो शुल्क लग सकता है, इसलिए इमेजेज़ या वीडियोज़ का अत्यधिक उपयोग करने वाले ब्लॉग्स में लागत प्रबंधन पर ध्यान देना आवश्यक है।&lt;/p>
&lt;hr>
&lt;h2 id="3-परदरशन-और-वलबत-क-सदधतक-गणन-latex-दवर-गणतय-मडल">3. प्रदर्शन और विलंबता की सैद्धांतिक गणना (LaTeX द्वारा गणितीय मॉडल)
&lt;/h2>&lt;p>वेब प्रदर्शन का मूल्यांकन करते समय, विलंबता (Latency) में कमी सबसे महत्वपूर्ण मीट्रिक है। आइए हम एक मॉडल बनाएं कि ओरिजिन सर्वर को सीधे एक्सेस करने की तुलना में CDN (एज) का उपयोग करके विलंबता को कितना कम किया जा सकता है।&lt;/p>
&lt;p>मान लें कि उपयोगकर्ता के अनुरोध के कैश से टकराने (हिट होने) की संभावना &amp;ldquo;कैश हिट अनुपात (Cache Hit Ratio)&amp;rdquo; है और इसे $C$ के रूप में दर्शाएं। $0 \le C \le 1$ है।
ओरिजिन सर्वर तक विलंबता को $L_{origin}$ और निकटतम एज नोड तक विलंबता को $L_{edge}$ मान लें।&lt;/p>
&lt;p>नई औसत विलंबता $L_{new}$ की गणना निम्नलिखित अपेक्षित मूल्य (expected value) के रूप में की जाती है:&lt;/p>
$$ L_{new} = C \times L_{edge} + (1 - C) \times (L_{edge} + L_{origin}) $$&lt;p>इस सूत्र को सरल करने पर निम्नलिखित प्राप्त होता है:&lt;/p>
$$ L_{new} = L_{edge} + (1 - C) \times L_{origin} $$&lt;p>उदाहरण के लिए, यदि टोक्यो का कोई उपयोगकर्ता संयुक्त राज्य अमेरिका के पूर्वी तट (न्यूयॉर्क) पर एक ओरिजिन सर्वर तक पहुँचता है, तो ऑप्टिकल फाइबर की भौतिक दूरी और राउटर पर प्रोसेसिंग विलंब को देखते हुए, $L_{origin}$ लगभग 200 ms होगा। दूसरी ओर, यदि Cloudflare जैसे CDN का उपयोग किया जाता है, तो यह टोक्यो में एज नोड से जुड़ सकता है, इसलिए $L_{edge}$ लगभग 10 ms तक कम हो जाएगा।&lt;/p>
&lt;p>मान लें कि कैश हिट अनुपात $C = 0.95$ (95%) है,&lt;/p>
$$ L_{new} = 10 + (1 - 0.95) \times 200 = 10 + 0.05 \times 200 = 10 + 10 = 20 \text{ ms} $$&lt;p>इस तरह, CDN को लागू करके औसत विलंबता को 210 ms से घटाकर 20 ms (लगभग 90%) तक कम करना संभव हो जाता है।&lt;/p>
&lt;hr>
&lt;h2 id="4-github-actions-क-उपयग-करक-cicd-पइपलइन-क-नरमण">4. GitHub Actions का उपयोग करके CI/CD पाइपलाइन का निर्माण
&lt;/h2>&lt;p>Hugo ब्लॉग की अपडेट प्रक्रिया को स्वचालित (ऑटोमेट) करने के लिए, हम GitHub Actions का उपयोग करके CI/CD पाइपलाइन का निर्माण करेंगे। इससे आप बस स्थानीय रूप से (लोकल) Markdown में लेख लिख सकते हैं और &lt;code>git push&lt;/code> कर सकते हैं, बिल्ड अपने आप चलेगा और इसे Cloudflare Pages या GitHub Pages पर तैनात (डिप्लॉय) कर दिया जाएगा।&lt;/p>
&lt;p>निम्नलिखित अनुक्रम आरेख (sequence diagram) एक लेख को पुश करने से लेकर उपयोगकर्ताओं तक पहुँचाए जाने तक के पूरे प्रवाह को दर्शाता है।&lt;/p>
&lt;pre class="mermaid">
sequenceDiagram
participant U as &amp;#34;उपयोगकर्ता (लेखक)&amp;#34;
participant G as &amp;#34;GitHub रेपो&amp;#34;
participant A as &amp;#34;GitHub Actions&amp;#34;
participant C as &amp;#34;Cloudflare Pages&amp;#34;
participant V as &amp;#34;विजिटर&amp;#34;
U-&amp;gt;&amp;gt;G: &amp;#34;git push origin main&amp;#34;
G-&amp;gt;&amp;gt;A: &amp;#34;Push इवेंट को ट्रिगर करें&amp;#34;
A-&amp;gt;&amp;gt;A: &amp;#34;चेकआउट और Hugo सेटअप करें&amp;#34;
A-&amp;gt;&amp;gt;A: &amp;#34;hugo --minify (बिल्ड)&amp;#34;
A-&amp;gt;&amp;gt;C: &amp;#34;Cloudflare Pages पर डिप्लॉय करें (डायरेक्ट अपलोड)&amp;#34;
C--&amp;gt;&amp;gt;A: &amp;#34;डिप्लॉयमेंट URL (सफलता)&amp;#34;
V-&amp;gt;&amp;gt;C: &amp;#34;वेब पेज के लिए अनुरोध&amp;#34;
C--&amp;gt;&amp;gt;V: &amp;#34;कैश्ड HTML वापस करें (एज)&amp;#34;
&lt;/pre>
&lt;h3 id="41-cloudflare-pages-क-लए-डपलयमट-सटगस-डयरकट-अपलड">4.1 Cloudflare Pages के लिए डिप्लॉयमेंट सेटिंग्स (डायरेक्ट अपलोड)
&lt;/h3>&lt;p>Cloudflare Pages पर, आपके पास GitHub रिपॉजिटरी को लिंक करके Cloudflare के इंफ्रास्ट्रक्चर पर बिल्ड करने का विकल्प है, या GitHub Actions का उपयोग करके बिल्ड की गई स्टैटिक फ़ाइलों को &amp;ldquo;डायरेक्ट अपलोड (Direct Upload)&amp;rdquo; करने का विकल्प है। यदि आप Hugo के संस्करणों को अधिक सख्ती से प्रबंधित करना चाहते हैं और इसे अन्य कार्यों (जैसे परीक्षण या इमेज ऑप्टिमाइज़ेशन) के साथ जोड़ना चाहते हैं, तो हम GitHub Actions पर बिल्ड करने और डायरेक्ट अपलोड का उपयोग करने की सलाह देते हैं।&lt;/p>
&lt;p>नीचे &lt;code>.github/workflows/deploy.yml&lt;/code> का एक व्यावहारिक उदाहरण है, जो Cloudflare Pages पर डिप्लॉय करने के लिए है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Deploy Hugo site to Cloudflare Pages&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">push&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">branches&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;main&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">workflow_dispatch&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">jobs&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">build-and-deploy&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">runs-on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;ubuntu-latest&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">steps&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Checkout repository&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;actions/checkout@v4&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">submodules&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;recursive&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">fetch-depth&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Setup Hugo&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;peaceiris/actions-hugo@v3&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">hugo-version&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;0.125.0&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">extended&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Build Hugo Site&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;hugo --minify --gc&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">env&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">HUGO_ENVIRONMENT&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;production&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Deploy to Cloudflare Pages&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;cloudflare/pages-action@v1&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">apiToken&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${{ secrets.CLOUDFLARE_API_TOKEN }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">accountId&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${{ secrets.CLOUDFLARE_ACCOUNT_ID }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">projectName&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;your-project-name&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">directory&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;public&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">gitHubToken&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${{ secrets.GITHUB_TOKEN }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">branch&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;main&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इस पाइपलाइन में, &lt;code>--minify&lt;/code> विकल्प के माध्यम से HTML/CSS/JS को छोटा (मिनिफ़ाई) किया गया है, और &lt;code>--gc&lt;/code> के माध्यम से अनावश्यक फ़ाइलों को हटा दिया जाता है। ये प्रदर्शन अनुकूलन (परफॉरमेंस ऑप्टिमाइज़ेशन) की मूल बातें हैं।&lt;/p>
&lt;hr>
&lt;h2 id="5-dns-सटगस-क-गहरई-म-कसटम-डमन-और-cname--alias-रकरड">5. DNS सेटिंग्स की गहराई में: कस्टम डोमेन और CNAME / ALIAS रिकॉर्ड
&lt;/h2>&lt;p>यदि आप कस्टम डोमेन (जैसे: &lt;code>kenji.blog&lt;/code>) का उपयोग करना चाहते हैं, तो उचित DNS (डोमेन नेम सिस्टम) कॉन्फ़िगरेशन आवश्यक है।&lt;/p>
&lt;h3 id="51-cname-रकरड-समए-और-zone-apex">5.1 CNAME रिकॉर्ड सीमाएँ और Zone Apex
&lt;/h3>&lt;p>आमतौर पर, जब आप एक सबडोमेन (उदा: &lt;code>www.kenji.blog&lt;/code>) को किसी बाहरी सेवा की ओर निर्देशित करते हैं, तो आप &lt;code>CNAME&lt;/code> रिकॉर्ड का उपयोग करते हैं। हालाँकि, DNS विशिष्टताओं (RFC 1034) के अनुसार, रूट डोमेन (Zone Apex, या नेकेड डोमेन, उदा: &lt;code>kenji.blog&lt;/code>) के लिए &lt;code>CNAME&lt;/code> रिकॉर्ड सेट नहीं किया जा सकता है। इसका कारण यह है कि Zone Apex में SOA (Start of Authority) रिकॉर्ड, NS (Name Server) रिकॉर्ड, या MX (Mail Exchange) रिकॉर्ड होना आवश्यक है, और यह नियम है कि CNAME अन्य रिसोर्स रिकॉर्ड के साथ सह-अस्तित्व में नहीं हो सकता है।&lt;/p>
&lt;h3 id="52-समधन-alias--aname--cname-flattening">5.2 समाधान: ALIAS / ANAME / CNAME Flattening
&lt;/h3>&lt;p>इस समस्या को हल करने के लिए, आधुनिक DNS प्रदाता अपने स्वयं के विस्तार (एक्सटेंशन) प्रदान करते हैं।&lt;/p>
&lt;ul>
&lt;li>&lt;strong>ALIAS / ANAME रिकॉर्ड&lt;/strong>: DNS सर्वर साइड पर गतिशील रूप से नाम का रिज़ॉल्यूशन करता है और अंतिम A रिकॉर्ड (IP एड्रेस) को क्लाइंट को वापस करता है। Amazon Route 53 आदि इसका समर्थन करते हैं।&lt;/li>
&lt;li>&lt;strong>CNAME Flattening&lt;/strong>: यह Cloudflare द्वारा प्रदान की जाने वाली एक सुविधा है। ऐसा व्यवहार करते हुए जैसे कि Zone Apex पर CNAME सेट किया गया हो, Cloudflare का आधिकारिक DNS सर्वर पारदर्शी रूप से क्लाइंट को IP एड्रेसेस (A रिकॉर्ड्स और AAAA रिकॉर्ड्स) लौटाता है जिसे उसने स्वचालित रूप से हल किया है।&lt;/li>
&lt;/ul>
&lt;p>जब आप Cloudflare Pages का उपयोग करते हैं, तो सबसे निर्बाध और उच्च-प्रदर्शन कॉन्फ़िगरेशन यह है कि डोमेन के नेम सर्वर को Cloudflare को सौंप दिया जाए और इस &amp;ldquo;CNAME Flattening&amp;rdquo; का लाभ उठाया जाए।&lt;/p>
&lt;hr>
&lt;h2 id="6-कशग-रणनत-और-http-हडर-नयतरण">6. कैशिंग रणनीति और HTTP हेडर नियंत्रण
&lt;/h2>&lt;p>स्टैटिक साइट को गति देने के लिए &amp;ldquo;कैशिंग रणनीति (Caching Strategy)&amp;rdquo; एक और महत्वपूर्ण पहलू है। Cloudflare Pages में, आप उत्पन्न फ़ाइलों (&lt;code>_headers&lt;/code> फ़ाइल) का उपयोग करके HTTP रिस्पांस हेडर को विस्तार से नियंत्रित कर सकते हैं।&lt;/p>
&lt;h3 id="61-edge-cache-बनम-browser-cache">6.1 Edge Cache बनाम Browser Cache
&lt;/h3>&lt;p>कैश को मोटे तौर पर दो प्रकारों में विभाजित किया जा सकता है: &amp;ldquo;Edge Cache&amp;rdquo; जिसे CDN पक्ष पर रखा जाता है, और &amp;ldquo;Browser Cache&amp;rdquo; जिसे उपयोगकर्ता के ब्राउज़र में संग्रहीत किया जाता है।&lt;/p>
&lt;p>स्टैटिक फ़ाइलों (जैसे इमेज, CSS, JS, आदि जिनके फ़ाइल नाम में हैश होता है) को लंबे समय तक ब्राउज़र में कैश करना आदर्श है। दूसरी ओर, HTML फ़ाइलों में अपडेट को तुरंत दर्शाने के लिए, ब्राउज़र कैश को छोटा करना (या अक्षम करना) और इसे एज कैश के माध्यम से संभालना एक सामान्य कॉन्फ़िगरेशन है।&lt;/p>
&lt;p>Cloudflare Pages में &lt;code>_headers&lt;/code> का कॉन्फ़िगरेशन उदाहरण:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;span class="lnt">9
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl"># HTML फ़ाइलों को ब्राउज़र द्वारा कैश नहीं किया जाएगा, उन्हें हर बार मान्य किया जाएगा
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/*.html
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Cache-Control: public, max-age=0, must-revalidate
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># एसेट फ़ाइलों (CSS/JS/इमेज) को ब्राउज़र में 1 वर्ष के लिए कैश किया जाएगा
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/assets/*
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Cache-Control: public, max-age=31536000, immutable
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/img/*
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Cache-Control: public, max-age=31536000, immutable
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="62-बडवडथ-लगत-म-कम-क-लए-गणन-सतर">6.2 बैंडविड्थ लागत में कमी के लिए गणना सूत्र
&lt;/h3>&lt;p>उचित कैश हेडर सेट करके, आप सर्वर (एज) से डेटा ट्रांसफर को काफी कम कर सकते हैं। मासिक बैंडविड्थ लागत $Cost$ को प्रत्येक संसाधन के ट्रांसफर वॉल्यूम $B_i$, कैश हिट अनुपात $C_i$ और बैंडविड्थ यूनिट मूल्य $R$ का उपयोग करके निम्न मॉडल द्वारा दर्शाया गया है:&lt;/p>
$$ Cost = \sum_{i=1}^{n} \left( B_i \times (1 - C_i) \times R \right) $$&lt;p>चूँकि Cloudflare मुफ़्त आउटबाउंड डेटा ट्रांसफर ($R = 0$) प्रदान करता है, इसलिए प्रत्यक्ष वित्तीय लागत $0$ है। हालाँकि, यदि आप GitHub Pages जैसे अन्य बुनियादी ढांचे के साथ काम करते हैं, या बैकेंड के रूप में AWS S3 आदि का उपयोग চৈতন্য करते हैं, तो इस कैश हिट अनुपात $C_i$ को अधिकतम करना बुनियादी ढांचा लागत को कम करने की कुंजी है।&lt;/p>
&lt;hr>
&lt;h2 id="7-एकसस-एनलटकस-ज-गपनयत-और-परदरशन-क-सतलत-करत-ह">7. एक्सेस एनालिटिक्स जो गोपनीयता और प्रदर्शन को संतुलित करता है
&lt;/h2>&lt;p>एक ब्लॉग चलाते समय, एक्सेस एनालिटिक्स (Web Analytics) यह जानने के लिए आवश्यक है कि कितने उपयोगकर्ता साइट पर आ रहे हैं। Google Analytics (GA4) लंबे समय से एक मानक रहा है, लेकिन हालिया गोपनीयता सुरक्षा प्रवृत्तियों (GDPR, CCPA) और थर्ड-पार्टी कुकीज़ के उन्मूलन के साथ स्थिति बदल रही है।&lt;/p>
&lt;h3 id="71-वब-परदरशन-पर-परभव">7.1 वेब प्रदर्शन पर प्रभाव
&lt;/h3>&lt;p>Google Analytics (विशेष रूप से &lt;code>gtag.js&lt;/code> या Google Tag Manager) को लागू करने से कई बाहरी स्क्रिप्ट लोड और निष्पादित होती हैं, जो प्रदर्शन को (विशेष रूप से TTFB और मुख्य थ्रेड ब्लॉकिंग समय को) नकारात्मक रूप से प्रभावित करता है।&lt;/p>
&lt;p>आइए साइट के लोड समय को तोड़कर समझें:&lt;/p>
&lt;pre class="mermaid">
pie title &amp;#34;विशिष्ट साइट लोडिंग समय का ब्रेकडाउन&amp;#34;
&amp;#34;TTFB (Time to First Byte)&amp;#34; : 15
&amp;#34;कंटेंट डाउनलोड (HTML/CSS)&amp;#34; : 20
&amp;#34;DOM पार्सिंग और रेंडरिंग&amp;#34; : 45
&amp;#34;एनालिटिक्स और थर्ड-पार्टी JS&amp;#34; : 20
&lt;/pre>
&lt;p>थर्ड-पार्टी JS एनालिटिक्स टूल के लिए कुल लोड समय का लगभग 20% से 30% लेना असामान्य नहीं है।&lt;/p>
&lt;h3 id="72-cloudflare-web-analytics-क-लग-करन">7.2 Cloudflare Web Analytics को लागू करना
&lt;/h3>&lt;p>यहीं पर कुकी-रहित (Cookieless), गोपनीयता-प्रथम एक्सेस एनालिटिक्स जैसे कि Cloudflare Web Analytics और Plausible Analytics ध्यान आकर्षित कर रहे हैं।&lt;/p>
&lt;p>Cloudflare Web Analytics एक बहुत ही हल्के JavaScript स्निपेट को एम्बेड करके काम करता है और यह कुकीज़ जारी नहीं करता है, इसलिए आपको कष्टप्रद कुकी सहमति बैनर (Cookie Consent Banner) सेट करने की आवश्यकता नहीं है।&lt;/p>
&lt;p>Hugo में इसे लागू करना भी बहुत आसान है। बस दिए गए स्निपेट को &lt;code>layouts/partials/head.html&lt;/code> या &lt;code>layouts/partials/analytics.html&lt;/code> में जोड़ें।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">{{ if eq hugo.Environment &amp;#34;production&amp;#34; }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&amp;lt;!-- Cloudflare Web Analytics --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">script&lt;/span> &lt;span class="na">defer&lt;/span> &lt;span class="na">src&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#39;https://static.cloudflareinsights.com/beacon.min.js&amp;#39;&lt;/span> &lt;span class="na">data-cf-beacon&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#39;{&amp;#34;token&amp;#34;: &amp;#34;YOUR_CLOUDFLARE_BEACON_TOKEN&amp;#34;}&amp;#39;&lt;/span>&lt;span class="p">&amp;gt;&amp;lt;/&lt;/span>&lt;span class="nt">script&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&amp;lt;!-- End Cloudflare Web Analytics --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ end }}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;code>defer&lt;/code> एट्रिब्यूट (attribute) जोड़ने से, स्क्रिप्ट को HTML पार्सिंग को रोके बिना अतुल्यकालिक (asynchronously) रूप से लोड किया जा सकता है, और DOM निर्माण के बाद निष्पादित किया जा सकता है। यह प्रारंभिक प्रदर्शन गति (LCP: Largest Contentful Paint और FCP: First Contentful Paint) पर प्रभाव को कम करता है।&lt;/p>
&lt;hr>
&lt;h2 id="8-नषकरष-और-सरवततम-अभयस-best-practices">8. निष्कर्ष और सर्वोत्तम अभ्यास (Best Practices)
&lt;/h2>&lt;p>Hugo का उपयोग करके स्टैटिक साइट को चलाने के लिए Cloudflare Pages और GitHub Pages जैसे आधुनिक होस्टिंग प्लेटफ़ॉर्म का चयन करना लागत प्रदर्शन, डिस्प्ले स्पीड और सुरक्षा के सभी पहलुओं में भारी लाभ प्रदान करता है।&lt;/p>
&lt;ol>
&lt;li>&lt;strong>सुपर-फ़ास्ट बिल्ड&lt;/strong>: Hugo की उच्च गति का लाभ उठाएं और CI/CD पाइपलाइन (GitHub Actions) के निष्पादन समय को कम करें।&lt;/li>
&lt;li>&lt;strong>एज पर डिलीवरी&lt;/strong>: दुनिया भर के उपयोगकर्ताओं को मिलीसेकंड विलंबता के साथ कंटेंट वितरित करने के लिए Cloudflare के एज नेटवर्क का उपयोग करें।&lt;/li>
&lt;li>&lt;strong>उचित DNS कॉन्फ़िगरेशन&lt;/strong>: Zone Apex (कस्टम डोमेन) को सुरक्षित और तेज़ी से संचालित करने के लिए CNAME Flattening का लाभ उठाएं।&lt;/li>
&lt;li>&lt;strong>कैशिंग रणनीति का अनुकूलन&lt;/strong>: संसाधन प्रकार (रिसर्च टाइप) द्वारा ब्राउज़र कैश और एज कैश को उचित रूप से अलग करने के लिए &lt;code>_headers&lt;/code> का उपयोग करें।&lt;/li>
&lt;li>&lt;strong>हल्के एनालिटिक्स&lt;/strong>: Cloudflare Web Analytics आदि लागू करें, जो गोपनीयता को ध्यान में रखता है लेकिन प्रदर्शन से समझौता नहीं करता है।&lt;/li>
&lt;/ol>
&lt;p>इन्हें मिलाकर, आप मुफ़्त में एक स्केलेबल और मजबूत ब्लॉग सिस्टम बना सकते हैं जो हर महीने लाखों पेज-व्यू के बड़े पैमाने पर ट्रैफ़िक का सामना कर सकता है। यदि आप एक तकनीकी ब्लॉग, कॉर्पोरेट साइट या पोर्टफोलियो साइट शुरू करने पर विचार कर रहे हैं, तो कृपया Jamstack + Hugo + Cloudflare Pages के इस संयोजन को आज़माएं।&lt;/p></description></item></channel></rss>