मुझे GitHub Actions सच में नापसंद है
(xlii.space)- GitHub Actions के धीमे feedback loop और जटिल debugging प्रक्रिया को लेकर एक डेवलपर की निराशा भरी कहानी
- tmplr प्रोजेक्ट में
build.rsके ज़रिए CUE से दस्तावेज़ generate किए गए, लेकिन CI build fail होने के साथ ही समस्या शुरू हुई - 4 प्लेटफ़ॉर्म में से सिर्फ Linux ARM पर build fail हुआ; वजह थी cross build के दौरान GitHub Actions का x86_64 binary को arm64 runner पर छिपा देना
- एक ही बदलाव को test करने में 2–3 मिनट लगने वाला अक्षम feedback loop बार-बार दोहराया गया
- समाधान के रूप में
build.rsहटाकर GNU Makefile पर स्विच किया गया, ताकि CI logic को सीधे नियंत्रित करके समस्या हल की जा सके
समस्या कैसे शुरू हुई
- tmplr एक file/project scaffolding tool है, जो ऐसे template files का उपयोग करता है जिन्हें इंसान आसानी से पढ़ और लिख सके
build.rsमें CUE का उपयोग करकेREADME.md,CHANGELOG.md, version/help files generate किए जाते थे, ताकि consistency बनी रहे- यह काम खुद लगभग 1.5 घंटे में पूरा हो गया था, और इस पर एक संबंधित लेख भी लिखा जा चुका था
- लोकल पर सब ठीक चल रहा था, लेकिन GitHub Actions के CI environment में CUE binary इंस्टॉल न होने के कारण build fail हो गया
build fail होने की वजह
- 4 प्लेटफ़ॉर्म (Linux ARM, macOS ARM, Linux x86_64, macOS x86_64) में से सिर्फ Linux ARM पर “command not found” error आया
- कारण: matrix cross build बहुत कड़ी तरह से isolated था, इसलिए CUE सिर्फ x86_64 Linux host और macOS ARM host पर इंस्टॉल था
- macOS पर x86_64 binary चलाने में कोई समस्या नहीं थी
- Linux x86_64 पर भी x86_64 binary ठीक चल रहा था
- लेकिन GitHub Actions arm64 runner पर x86_64 binary को छिपा देता है, जिससे उसे चलाया नहीं जा सकता
अक्षम feedback loop
- समस्या सुलझाने के लिए बार-बार यह प्रक्रिया दोहराई गई:
1. संभावित fixes खोजो
2.ci.ymlबदलो
3. commit और push करो (jj squash --ignore-immutable && jj git push)
4. "Actions" टैब खोलो
5. सबसे नया run खोलो
6. Linux ARM run खोलो
7. कुछ सेकंड इंतज़ार करो
8. निराश हो जाओ
9. फिर से दोहराओ - हर एक बदलाव पर 2–3 मिनट लगते थे
- आदर्श स्थिति में GitHub या तो पूरी तरह सक्षम local runner देता, या push के बाद प्रगति जल्दी देखने की कोई सुविधा देता
- "scratch commit" जैसी सुविधा: Git history और Action run history को गंदा किए बिना अलग-अलग runs test करने का तरीका
- लेकिन फिलहाल ऐसी कोई सुविधा मौजूद नहीं है
समाधान
- 30 मिनट तक यह loop दोहराने के बाद इसे रोका गया
- इंटरनेट पर सुझाया गया तरीका अपनाया गया: "GitHub Actions को logic manage न करने दें; script को खुद नियंत्रित करें और Actions सिर्फ उस script को call करे"
build.rsहटा दिया गया (अफसोस था, लेकिन यह कुर्बानी ज़रूरी थी)- सारे generation tasks को GNU Makefile में शिफ्ट कर दिया गया
- generated files को repository में commit किया गया और CI changes वापस ले लिए गए
- समस्या पूरी तरह हल हो गई
निष्कर्ष
- GitHub Actions ऐसी चीज़ है जो कुछ अच्छे approaches अपनाने से रोक देती है
- runner debugging और build process optimization में बहुत समय बर्बाद होता है
- फिर भी इससे macOS builds जैसे कुछ ऐसे फ़ायदे मिलते हैं जिन्हें दूसरे तरीकों से पाना आसान नहीं है
- और बेशक, GitHub Actions से आसान setup वाला कोई दूसरा system व्यापक रूप से जाना-पहचाना नहीं है
We are all doomed to GitHub Actions. …but at least I dodged the bullet early.
3 टिप्पणियां
लगता है कि यह उस संरचना की वजह से होने वाली एक अपरिहार्य समस्या है, जिसमें लॉजिक को
yamlके अंदर ही डालना पड़ता है.ऊपर की पोस्ट ने शायद मोटे तौर पर नीचे जैसा जवाब दिया है, लेकिन अगर स्क्रिप्ट वाले हिस्से को Dagger से बदल दिया जाए, तो शायद यही सही जवाब होगा.
"GitHub Actions को लॉजिक मैनेज करने मत दो; स्क्रिप्ट को सीधे कंट्रोल करो, और Actions से बस उस स्क्रिप्ट को कॉल करवाओ"
GitHub Actions को सिर्फ environment setup (OS, build toolchain, …) और scripts (shell, Python, bat, ps1…) चलाने तक सीमित होना चाहिए। GitHub down हो जाए तब भी, अगर environment तैयार है, तो कहीं से भी build कर पाना चाहिए। आजकल GitHub Actions workflows को देखकर लगता है कि क्या सच में ऐसी चीज़ों तक भी ढूंढकर इस्तेमाल करना ज़रूरी है। बहुत पुराने समय में(?) ansible ने भी ऐसा ही किया था और बर्बाद हो गया।
Hacker News की राय
GitHub Actions की मुख्य समस्या यह है कि feedback loop बहुत धीमा है
सिर्फ एक साधारण failure चेक करने के लिए push करने के बाद इंतज़ार करना सच में बेहद झुंझलाने वाला है
मेरा मानना है कि CI tasks को ऐसे scripts में अलग करना बेहतर है जिन्हें local में चलाया जा सके, और Actions की features को सिर्फ incremental enhancement की तरह इस्तेमाल करना चाहिए
workflow_dispatchऔरgh workflow runका संयोजन भी ठीक है, लेकिन यह असुविधाजनक है कि दूसरा कमांड चलाए गए workflow का URL तुरंत नहीं देतातेज feedback पाने में यह काफ़ी सफल रहा
अगर कोई समस्या आती है, तो GitHub Actions environment के लगभग समान स्थिति में debug किया जा सकता है
यह हर CI system की मूल आवश्यकता होनी चाहिए
आख़िरकार जो चीज़ें महत्वपूर्ण हैं वे queuing, output analysis, और build history telemetry जैसी features हैं
gh workflow runइस्तेमाल करते समय URL पाने के लिए मुझे GitHub API से workflow run list फिर से fetch करनी पड़ीअगर एक साथ कई runs हों तो गड़बड़ हो सकती है, लेकिन अभी के लिए यह ठीक-ठाक काम कर रहा है
CI design के कुछ tips मैंने संकलित किए
simple shell काफ़ी होना चाहिए
Makefileमें CI targets define करना, औरmake ci-testकी तरह सरल तरीके से call करना अच्छा हैउसके बाद से मैं सारी CI को
make buildजैसे simple wrappers से manage करता हूँBeginStep("Step Name")जैसे markers से उन्हें अलग किया जा सके तो अच्छा होगासमस्या GitHub Actions से ज़्यादा, उसके ऊपर बेतरतीब तरीके से चढ़ाई गई automation है
logic को Python जैसी language में script करना चाहिए ताकि उसे local में भी चलाया जा सके
हर बार workflow बदलो, push करो, और इंतज़ार करो
मैं सारी CI container के अंदर करता हूँ
CI platform सिर्फ उस container को चलाता है, इसलिए local में भी वही चीज़ चलाई जा सकती है
platforms को यह तरीका पसंद नहीं आता, क्योंकि इससे vendor lock-in टूट जाता है
failure होने पर SSH से सीधे login करके debug किया जा सकता है, और branch push किए बिना manifest बदलकर rerun भी संभव है
हालाँकि इसके लिए self-hosting चाहिए
standardization आसान हो जाती है, लेकिन image maintenance का trade-off आता है
practically lock-in है ही नहीं, लेकिन लोग CI/CD cargo cult में फँसे हुए हैं
मुझे GitHub Actions पसंद है
पहले इस्तेमाल किए गए Travis से यह बेहतर है, और OSS projects के लिए free resources के रूप में बहुत उपयोगी है
Nix अपनाने के बाद environment reproducibility बढ़ गई है, इसलिए Actions के साथ इसकी compatibility बहुत बेहतर हो गई है
flake से बना container Actions में ज्यों का त्यों चलाया जा सकता है
example project
मेरा मानना है कि GitHub Actions बस bash या python scripts को call करने वाली structure होनी चाहिए
bash की सीमाएँ बहुत हैं, Python अधिक flexible है, और local execution भी आसान है
इस लेख की तरह uv को अपने आप install करके dependencies manage करने का तरीका आदर्श है
bash की तुलना में यह अधिक जटिल है, लेकिन Actions environment में performance issue बड़ा नहीं होता
Actions की सबसे बड़ी समस्या इसका “workflow को compose करो” वाला प्रचार तरीका है
debugging लगभग असंभव है, और cache configuration पेचीदा होने से builds धीमे हो जाते हैं
इसी वजह से persistent VM पर सीधे execution वाला तरीका आकर्षक लगता है
मैं Depot का संस्थापक हूँ
मैं ऐसी service चला रहा हूँ जो GitHub Actions runners को ज़्यादा तेज़ और सस्ता बनाती है
बहुत से लोगों की जो असंतुष्टि है, वही वास्तव में बहुमत की राय है
Actions system संरचनात्मक रूप से अक्षम है, और हम हर हफ़्ते नए bottlenecks खोजते हैं
मुझे यक़ीन है कि इससे बेहतर तरीका है, और हम उस पर प्रयोग कर रहे हैं
अधिक जानकारी depot.dev पर देखी जा सकती है
पिछले weekend मैंने
gg watch actionनाम का एक tool बनायायह current branch की latest या running action खोजने वाला tool है
GitHub लिंक
ghCLI में होना चाहिए था”हालाँकि
gg tuicommand में repository न दिखने वाला bug थामैं सोच रहा था कि क्या
actजैसा tool मददगार हो सकता हैnektos/act
architecture differences की वजह से local और online execution अलग हो सकते हैं, लेकिन फिर भी यह उपयोगी लगता है
लगभग 80% compatibility थी
SourceHut यह support करता है, इसलिए यह वास्तव में सुविधाजनक है