8 पॉइंट द्वारा GN⁺ 2026-02-07 | 3 टिप्पणियां | WhatsApp पर शेयर करें
  • Repo में डिफ़ॉल्ट रूप से शामिल CI होने की वजह से इसका व्यापक उपयोग होता है, लेकिन संरचनात्मक अक्षम्यता और अस्थिर user experience डेवलपर productivity को घटाते हैं
  • Log viewer का धीमा loading और browser crash, जटिल YAML syntax और expression errors बार-बार debugging को जन्म देते हैं
  • Compute resources पर मालिकाना नियंत्रण न होने वाली संरचना के कारण performance, scalability और environment control के मामले में इसकी सीमाएँ सामने आती हैं
  • इन समस्याओं को दरकिनार करने की कोशिश में बार-बार जटिल YAML या विशाल Bash scripts के जरिए CI को फिर से बनाने की स्थिति पैदा होती है
  • इसके मुकाबले Buildkite सरल YAML संरचना, self-hosting योग्य agents और व्यावहारिक log experience के जरिए लंबे समय तक maintain किए जा सकने वाला CI विकल्प प्रस्तुत करता है

GitHub Actions की समस्याएँ

  • GitHub Actions का log viewer अक्षम है: साधारण error जाँचने के लिए भी कई चरणों में क्लिक और page loading की ज़रूरत पड़ती है
    • Build fail होने पर checks summary page → workflow run page → job page → collapsed step पर क्लिक तक पहुँचने के लिए 3~4 चरणों के page transition की ज़रूरत होती है, और हर चरण में अलग loading होती है
    • बड़े build logs में browser बार-बार crash हो जाता है, और search feature इस्तेमाल करते समय Chrome के freeze होने की समस्या पुन: उत्पन्न की जा सकती है
    • लंबे logs में scrolling ही काम नहीं करती, जिससे आखिरकार raw log artifact डाउनलोड करके text editor में खोलना पड़ता है
    • Back button मूल PR page पर लौटाने के बजाय अप्रत्याशित GitHub Actions UI pages पर ले जाता है, और browser history Actions URLs से भर जाती है
  • Debugging process की non-productive nature
    • Environment variables देखने के लिए run: env step जोड़कर फिर से push करने पर 20 मिनट का feedback loop बनता है, और एक लाइन के बदलाव के लिए यह प्रक्रिया दर्जनों बार दोहरानी पड़ती है
    • 20 मिनट वाले feedback loops बार-बार दोहरने से पूरे दिन का काम CI के इंतज़ार में निकल जाता है
  • YAML की संरचनात्मक सीमाएँ
    • GitHub Actions YAML, अपनी expression language, context object model और string interpolation rules से मिलकर बना एक विशेष रूप है
    • ${{ }} expression में एक quote गलत हो जाए तो runner spin up होने तक 4 मिनट इंतज़ार करने के बाद ही पता चलता है कि string गायब हो गई
    • Expression syntax configuration के लिए बहुत जटिल है, और औपचारिक programming language के रूप में इस्तेमाल करने के लिए बहुत सीमित — यह एक liminal space में मौजूद है
    • इसकी syntax documentation से नहीं, बल्कि failures के अनुभव से सीखनी पड़ती है
  • Marketplace के security risks
    • uses: syntax से external actions लाते समय, repository, secrets और build environment तक access unverified third parties को दे दिया जाता है
    • SHA pinning संभव है, लेकिन व्यवहार में बहुत कम लोग ऐसा करते हैं, और pinning के बाद भी बिना पढ़े गए opaque code को GITHUB_TOKEN access के साथ चलाया जाता है
    • Marketplace में अलग-अलग quality वाले community-maintained actions मिले-जुले रूप में मौजूद हैं, और ज़्यादातर shell scripts और Dockerfile पर आधारित हैं
    • Dependency management अपारदर्शी है और unsafe code execution की संभावना बनी रहती है
  • Compute environment की पाबंदियाँ
    • GitHub Actions के default runners Microsoft के स्वामित्व वाले shared runners हैं, जो धीमे, resource-limited और meaningful customization से लगभग रहित हैं
    • बड़े runners की लागत इतनी होती है कि finance team की ओर से "हमें इस पर बात करनी चाहिए" जैसा meeting request आ सकता है, और तब भी environment control नहीं मिलता
    • Namespace, Blacksmith, Actuated, Runs-on, BuildJet जैसी कम-से-कम 6 startups सिर्फ GitHub Actions runners की धीमी गति दूर करने पर केंद्रित हैं, जो खुद default computing environment की कमज़ोरी का प्रमाण है
    • Self-hosted runner सेट करने पर compute की समस्या हल हो सकती है, लेकिन YAML expressions, permission model, Marketplace, log viewer जैसी बाकी समस्याएँ जस की तस रहती हैं

छोटे लेकिन जमा होते जाने वाले मुद्दे

  • actions/cache: cache keys उलझाऊ हैं, cache miss चुपचाप होते हैं, और cache eviction अपारदर्शी है, इसलिए caching debugging में बचने वाले समय से ज़्यादा समय खर्च हो जाता है
  • Reusable workflows: एक तय गहराई से अधिक nesting संभव नहीं, calling workflow के context तक साफ़ access नहीं, और isolated testing भी संभव नहीं
  • GITHUB_TOKEN permission model: permissions: write-all बहुत व्यापक है, और granular permissions में repository, workflow और job-level settings के बीच की interaction भूलभुलैया जैसी जटिल हो जाती है
  • Concurrency control: उसी branch पर चल रही execution को cancel करना एक लाइन में संभव है, लेकिन उससे आगे की सूक्ष्म control capability उपलब्ध नहीं है
  • Secrets को if condition में इस्तेमाल न कर पाना: if: secrets.DEPLOY_KEY != '' जैसी conditional execution संभव नहीं, जो security की दृष्टि से तर्कसंगत है, लेकिन ऐसे workflows लिखने में जो fork और main repo दोनों पर काम करें workaround की ज़रूरत पड़ती है

"बस Bash script लिख लो" का जाल

  • CI YAML से थके engineers के लिए सब कुछ run: bash scripts से बदल देने का प्रलोभन रहता है, लेकिन समय के साथ उसमें conditionals, functions, argument parsing और parallel processing जुड़ते जाते हैं
  • 3 महीने बाद स्थिति यह हो सकती है कि 800 लाइन की bash wait और PID files के साथ job parallelization को फिर से implement कर रही हो, और अपनी retry logic तथा output parsing logic भी रखती हो
  • नतीजा यह होता है कि CI system से बाहर निकलने के बजाय बिना test framework वाला और ऐसा उससे भी खराब CI system bash में खुद बना लिया जाता है जिसे कोई ठीक से समझ न सके
  • Bash glue के रूप में ठीक है, लेकिन build system या test harness के रूप में इस्तेमाल करने पर यह complexity को guardrails वाली जगह से बिना guardrails वाली जगह पर ले जाता है

Buildkite का वैकल्पिक दृष्टिकोण

  • स्थिर log viewer

    • Buildkite का log viewer browser crash किए बिना logs को सही ढंग से दिखाता है, और ANSI colors तथा test framework formatting वैसे के वैसे render होते हैं
    • Annotation feature के जरिए build steps test failure summary, coverage report, deployment links आदि को सीधे build page पर Markdown में output कर सकते हैं
    • क्योंकि agents अपनी infrastructure पर चलते हैं, इसलिए SSH के जरिए build machine में लॉग इन करके सीधे debugging की जा सकती है
  • सरल YAML संरचना

    • Buildkite का YAML pipeline को वर्णित करने वाली शुद्ध data structure है, जिसमें सिर्फ steps, commands और plugins घोषित किए जाते हैं
    • अगर वास्तविक logic चाहिए, तो ऐसी वास्तविक programming language में scripts लिखी जाती हैं जिन्हें local पर चलाया जा सके
    • यह "orchestration configuration में, logic code में" जैसी सीमा को स्पष्ट बनाए रखता है — वही सीमा जिसे GitHub Actions धुंधला कर देता है
  • Compute environment पर पूरा नियंत्रण

    • Buildkite agent एक single binary है, जिसे अपने cloud, on-premises या custom hardware कहीं भी चलाया जा सकता है
    • Instance type, caching, local storage और network पर पूरी तरह नियंत्रण संभव है, और NVMe drives व 20GB Docker layer cache वाले बड़े EC2 instances से लेकर Raspberry Pi तक समर्थित हैं
    • "Buildkite, लेकिन और तेज़" जैसी कोई third-party industry मौजूद नहीं है; बस और बड़ी machine चला दीजिए
    • छोटे open source libraries संभालने वाले individual maintainers के लिए GitHub Actions का public repo free tier अब भी मूल्यवान है
    • इस लेख का मुख्य लक्ष्य वे teams हैं जो production systems चलाती हैं, जहाँ CI time को प्रति सप्ताह engineering time loss के रूप में मापा जाता है, और 45 मिनट की builds compute cost और labor cost दोनों पैदा करती हैं
    • ऐसे environments में Buildkite agents चलाने का overhead बहुत जल्दी अपनी लागत वसूल कर लेता है
  • Dynamic pipelines का समर्थन

    • Buildkite में pipeline steps data होते हैं, और scripts runtime पर dynamically अतिरिक्त steps generate करके upload कर सकती हैं
    • Monorepo में बदली गई files के आधार पर केवल ज़रूरी build और test steps को सटीक रूप से generate किया जा सकता है, जिससे hardcoded matrix या if: contains(...) spaghetti की ज़रूरत नहीं रहती
    • GitHub Actions का matrix, if conditions और reusable workflows इसे approximate करने की कोशिश करते हैं, लेकिन अंत में कम अभिव्यक्तिशील declarative language में Rube Goldberg machine बन जाती है
  • Plugin structure की सरलता

    • संरचनात्मक रूप से यह GitHub Actions Marketplace की तरह third-party repos से code लाने का तरीका है
    • अंतर यह है कि Buildkite plugins आम तौर पर Docker images के बजाय thin shell hooks होते हैं, इसलिए उनका surface area छोटा होता है और उन्हें कुछ ही मिनटों में पूरा पढ़ा जा सकता है
    • चूँकि यह अपनी infrastructure पर चलता है, इसलिए blast radius पर user का नियंत्रण रहता है
  • User experience पर केंद्रित छोटे features

    • Buildkite custom emoji (:parrot:, :docker: आदि) को pipeline steps के साथ दिखा सकता है; यह भले छोटा feature लगे, लेकिन product use experience के प्रति सूक्ष्म ध्यान दिखाता है
    • GitHub Actions ऐसा लगता है मानो उसने कभी यह सवाल ही नहीं पूछा: "क्या यह इस्तेमाल करने में आनंददायक है?" — जैसे किसी committee-design का उत्पाद हो

निष्कर्ष: CI system चुनने के मानदंड

  • GitHub Actions ने default होने के लाभ से बाज़ार पर कब्ज़ा किया है: public repos के लिए free, उसी platform में built-in जिसे सभी पहले से इस्तेमाल करते हैं, और "Good Enough" स्तर का
    • यह CI का Internet Explorer जैसा है; switching cost वास्तविक है और समय सीमित है, इसलिए इसका उपयोग जारी रहता है
  • Buildkite लगातार उपयोगिता और developer experience के मामले में बेहतर है
  • साधारण open source projects के लिए GitHub Actions पर्याप्त है, लेकिन बड़े production environments के लिए Buildkite अधिक उपयुक्त है
  • CI systems के इतिहास में market share अक्सर सबसे श्रेष्ठ system नहीं, बल्कि वह system लेता है जिससे शुरुआत करना सबसे आसान हो
  • GitHub Actions वह CI है जिससे शुरू करना सबसे आसान है, जबकि Buildkite वह CI है जिसे लंबे समय तक इस्तेमाल करना सबसे अच्छा है — और लंबी अवधि में यही ज़्यादा महत्वपूर्ण है
  • अगर CI tool की संरचना डेवलपर का समय खाती है, तो समस्या डेवलपर नहीं, tool खुद है

3 टिप्पणियां

 
kimjoin2 2026-02-07

मुझे लगता है कि असली समस्या CI का खुद बहुत जटिल हो जाना है।

 
tujuc 2026-02-07

लगता है कि एक ही पोस्ट दो बार चढ़ गई है। लेकिन आजकल AI के लिए सेटअप करने पर यह काफ़ी ठीक-ठाक कॉम्बिनेशन जैसा लगता है..

 
GN⁺ 2026-02-07
Hacker News की राय
  • मैंने कई CI systems इस्तेमाल किए हैं। CircleCI और GitHub Actions का बहुत उपयोग किया, लेकिन लेखक से मेरा निष्कर्ष अलग है
    पहले Jenkins लगभग Java-विशेष था, Travis लगभग Rails-विशेष, लेकिन ऐसे specialized CI आखिरकार बंद गली साबित हुए। अब CI सिर्फ़ workflow orchestrator के रूप में विकसित हो चुका है
    मैं CircleCI 2 से GitHub Actions पर इसलिए आया क्योंकि CircleCI यह बदलाव ठीक से नहीं कर पाया। GHA काफ़ी expressive था
    log browser या YAML syntax जैसी चीज़ें मामूली समस्याएँ हैं। असली बात है computing resources का ownership और dynamic pipelines; पहली चीज़ हर CI में संभव है, और दूसरी Buildkite की ताकत है
    मेरा निष्कर्ष यह है कि Actions व्यवहार में काफ़ी ठीक है, और अगर मैं नई कंपनी शुरू करूँ तो Buildkite, जबकि open source के लिए Actions इस्तेमाल करूँगा

    • मैं असहमत हूँ। game development में build system ही सबसे अहम होता है, और सामान्य CI approach बहुत धीमी है
      अगर build graph की समझ नहीं हो, तो incremental build state बनाए रखनी पड़ती है, और वही intermittent bugs पैदा करती है। इसलिए UnrealEngine Horde या UBA जैसे, build structure को गहराई से समझने वाले systems चाहिए
      generalized CI इस्तेमाल करने पर build में एक दिन से भी ज़्यादा लग सकता है
    • Actions एक event dispatcher भी है, orchestrator भी, execution engine भी, cache system भी, marketplace भी, secret manager भी — यानी बहु-कार्यात्मक platform
      मैं GHA के सिर्फ़ अच्छे हिस्से इस्तेमाल करता हूँ। उदाहरण के लिए GitHub event dispatcher के रूप में शानदार है, लेकिन workflow orchestrator के रूप में कमज़ोर, इसलिए वह हिस्सा मैं दूसरे system को सौंप देता हूँ
    • मैं इससे सहमत नहीं कि log browser महत्वहीन है। ANSI colors और formatting के साथ logs पढ़ने का अनुभव महत्वपूर्ण है
      अगर दिन में दर्जनों बार देखे जाने वाले logs असुविधाजनक हों, तो productivity गिरती है। raw logs में escape codes को नज़रअंदाज़ करते हुए पढ़ना सचमुच पीड़ादायक है
    • कहा गया कि “computing resources का ownership” महत्वपूर्ण है, लेकिन GitHub अपने hardware पर CI चलाने पर भी शुल्क लेता है
    • मैं Buildkite का शुरुआती ग्राहक था, और यह ergonomic और high-control system होने के कारण मुझे बहुत पसंद आया
  • मैं चीज़ों को सरल रखता हूँ। सारी orchestration deploy.sh script में डालता हूँ, और उसे local Mac या AWS CodeBuild पर चलाता हूँ
    YAML बस bash deploy.sh की एक पंक्ति है। Docker container हो तो Azure, GitHub Actions आदि कहीं भी वही चीज़ समान रूप से चलती है

  • हर CI environment की मूल रणनीति यह होनी चाहिए कि local जैसा ही build system हो
    मैं हमेशा Makefile से शुरू करता हूँ। Docker, CI builds, linting — सब कुछ Makefile चलाता है। project बड़ा हो जाए तो किसी दूसरे tool पर जाया जा सकता है, लेकिन आधार एक ही trigger tool होना चाहिए

    • इसी सोच से मैंने mkincl बनाया। यह Makefile को modular और reusable बनाता है। कई वर्षों से कंपनी में इसका उपयोग कर रहा हूँ; यह सहज और लचीला है
    • CI provider plugins पर निर्भर रहने के बजाय, उच्च-स्तरीय language पर जाना बेहतर है
      मैं mobile में Fastlane बहुत उपयोग करता हूँ; यह boilerplate कम करता है और structure देता है। आखिरकार यह Ruby ही है, इसलिए ज़रूरत पड़े तो बाहर निकलना भी संभव है
    • Make सचमुच अजीब system है। इसकी default rules में से एक version control system से files निकालना है
      (GNU Make docs link)
      आखिर में बात “बस Bash scripts लिखो” तक ही पहुँचती है, यानी अनावश्यक complexity जुड़ जाती है
    • यह approach आदर्श है, लेकिन मध्यम से बड़े projects में अव्यावहारिक है
      मेरी मौजूदा कंपनी में भी local पर पूरा pipeline चलाना संभव नहीं रहा, और नतीजे में एक MR टेस्ट करने के लिए 10 बार build चलाने वाली विशाल CI infrastructure बन गई
  • मुझे यह लेख Nix/Buildkite के विज्ञापन जैसा लगा
    CI को बस scripts या build targets चलाने तक सीमित होना चाहिए। CI सिर्फ़ environment और configuration दे, और logic code में रहना चाहिए
    इससे CI independence मिलती है और systems के बीच migration आसान होता है

    • “CI को simple रखो” कहना व्यवहार में असंभव है। scale बढ़ने पर conditional triggers, branch strategy, permissions, load balancing जैसी complexity अनिवार्य हो जाती है
      GitLab CI इस complexity को काफ़ी अच्छी तरह संभालता है। templates और job composition features शानदार हैं, लेकिन debugging कठिन है और conditional logic अक्सर अप्रत्याशित रूप से fail हो जाती है
    • यह विज्ञापन नहीं था। Buildkite team के नज़रिए से भी यह pleasant surprise था
    • मैं भी सहमत हूँ। पहले जब CI system migrate करना पड़ा, तो जिन teams ने सारा logic .sh files में रखा था, उनका migration बहुत आसान था
      इसके उलट, जिन teams ने चीज़ों को UI में बारीकी से बाँट रखा था, उन्हें काफ़ी परेशानी हुई
    • कम से कम यह प्रतिक्रिया तो नहीं आई कि “यह AI ने लिखा है”, यही राहत की बात है
  • समस्या CI/CD खुद नहीं है, बल्कि configuration files में programming करने की संस्कृति है
    git commit -m "try fix" के बाद 10 मिनट इंतज़ार करने वाला loop बहुत आम है। local में reproducible CI environment अभी भी कम हैं

    • यह tool की समस्या नहीं, बल्कि policy failure का नतीजा है। build, release और debug builds को स्पष्ट रूप से अलग होना चाहिए
      अगर environment isolation को policy के रूप में तय किया जाए, तो कोई भी tool इस्तेमाल करो, समस्या नहीं होगी। आखिरकार tool और methodology का तालमेल ही असली चीज़ है
    • सही कहा, मेरे हिसाब से लेख का 80% सार इसी हिस्से में है
    • act जैसे tools local में CI reproduce करने में बहुत मदद करते हैं
  • “engineering team को मार रहा है” जैसा शीर्षक अतिशयोक्तिपूर्ण है। GitHub Actions काफ़ी ठीक-ठाक है
    मैं इसे Bitbucket या GitLab से ज़्यादा पसंद करता हूँ

    • मैंने भी पहले सोचा “Microsoft लोगों को मार रहा है?” और उसी वजह से क्लिक किया, फिर निराशा हुई
    • मुझे भी लगा था कि बात GitLab की होगी। खासकर slow feedback loop की समस्या GitLab पर भी बिल्कुल लागू होती है
  • हाल में GitHub की reliability में गिरावट गंभीर रही है
    actions/checkout बिना वजह fail हो जाता है, release jobs दो बार चल जाती हैं, या कभी 40 मिनट तक बस इंतज़ार ही होता रहता है
    मैं इसे कई वर्षों से इस्तेमाल कर रहा हूँ, लेकिन इसकी बुनियादी stability गिरती दिख रही है। अफ़सोस है कि Buildkite को नहीं चुना

    • सही है, GHA के cron jobs अविश्वसनीय हैं। docs में भी कहा गया है कि उन पर भरोसा नहीं किया जा सकता
  • GitHub Actions मेरे इस्तेमाल किए गए सबसे खराब CI tools में से एक है (Jenkins के बराबर)
    दूसरी तरफ़ Buildkite बेहतरीन है। dynamic pipelines की वजह से test fail होने पर अपने-आप retry steps बनाए जा सकते हैं, या code changes के आधार पर parallel tests समायोजित किए जा सकते हैं
    हर CI job के लिए अलग machine configuration इस्तेमाल कर पाना भी बड़ा फ़ायदा है। ज़ोरदार सिफारिश है

    • Jenkins में बहुत समस्याएँ थीं, लेकिन Groovy-आधारित pipeline definitions अच्छी थीं। मेरे हिसाब से यह YAML से कहीं बेहतर है
    • Jenkins एक battle-tested और stable system है। यह हज़ारों jobs बिना समस्या संभाल लेता है, और install करते ही काम करने लगता है। पिछले 25 वर्षों के सर्वश्रेष्ठ open source projects में से एक, मेरी राय में
  • जो लोग “simple script-based CI” की वकालत करते हैं, शायद उनके पास बड़े पैमाने के वास्तविक projects का अनुभव नहीं है