36-წუთიანი სამუშაო სესია იმ ინსტრუმენტებზე, რომლებსაც სწრაფი გუნდები თავისთავად აღიქვამენ: Git-ის მოდელი და ვორქფლოუები, CI/CD პაიპლაინები, ბილდისა & დამოკიდებულებების მართვა და დებაგინგის/პროფილირების ნაკრები, რომელიც გამოცნობას გაზომვად აქცევს.
ნელ და სწრაფ გუნდებს შორის სხვაობა იშვიათად არის ნიჭი. ეს არის უკუკავშირის შეყოვნება: რამდენი გადის „რაღაც შევცვალე“-დან „ვიცი, იმუშავა თუ არა“-მდე. ყველა ინსტრუმენტი, რომელიც წინ გელოდებათ, არსებობს იმისთვის, რომ ეს ციკლი შემცირდეს და გახდეს ავტომატური, გამეორებადი და საერთო.
მაგიდასთან დაჭერილი ბაგის გამოსწორება პროდაქშენში დაჭერილთან შედარებით ორი რიგით იაფი შეიძლება იყოს.
"ჩემს მანქანაზე მუშაობს" — გაუმართაობა, რომლის აღმოსაფხვრელადაც შექმნილია აქ ჩამოთვლილი ყველა ინსტრუმენტი.
ბრძანება, რომ დაკლონოთ, ააგოთ, გატესტოთ და გაუშვათ. რიცხვი, რომელსაც ჯანსაღი რეპოზიტორია ესწრაფვის.
მწვანე პაიპლაინს, რომელიც წუთებში სრულდება, ხალხი მართლა ელოდება. ნელ CI-ს კი გვერდს უვლიან.
რაღაცას ცვლით, აგებთ, ტესტავთ და იგებთ, იმუშავა თუ არა — მერე ისევ თავიდან. ყველა ინსტრუმენტი, რომელიც წინ გელოდებათ, არსებობს იმისთვის, რომ ამ ციკლის ერთმა შემობრუნებამ დღეების ნაცვლად წუთები წაიღოს.
ეს არის ლოდინი „კოდი შევცვალე“-სა და „ვიცი, რამე გავაფუჭე თუ არა“-ს შორის. ნელი გუნდი ამ პასუხს შეიძლება მთელი დღე ელოდოს; სწრაფი გუნდი მას რამდენიმე წუთში იღებს.
ეს ორი აითვისეთ და დანარჩენი ინჟინერიის კარგად კეთება მკვეთრად იაფი გახდება.
Git-თან დაკავშირებული დაბნეულობის უმეტესობა ქრება იმ წამს, როცა მონაცემთა მოდელს დაინახავთ. Git დიფებს კი არ ინახავს — ის ინახავს უცვლელ სნეპშოტებს, გრაფად დაკავშირებულს. ბრენჩები და თეგები ამ გრაფზე მიწებებულ ფურცლებზე მეტი არაფერია. ისწავლეთ მოდელი და ბრძანებები ჯადოქრობას აღარ დაემსგავსება.
a1c9f2. შექმნის შემდეგ კომიტი აღარასდროს იცვლება. თითოეული უკან, წინა კომიტზე მიუთითებს, ამიტომ თქვენი ისტორია ჯაჭვია (რომელიც შეიძლება განშტოვდეს, მაგრამ არასდროს იკვრება წრედ). ბრენჩი უბრალოდ მიწებებული ფურცელია, რომელიც ერთ კომიტზე მიუთითებს; HEAD კი ფურცელია იმისთვის, თუ "სად ხართ ახლა".main და feature არის ბრენჩები — კომიტზე მიწებებული იარლიყები. კომიტის გაკეთება უბრალოდ იარლიყს წინ წაწევს.HEAD აღნიშნავს თქვენს მიმდინარე ბრენჩს. განშტოება იაფია, რადგან ის ერთ მაჩვენებელს ქმნის და არა ასლს.კომიტები მშობლებზეა მიბმული; ბრენჩები (main, feature) და HEAD უბრალოდ მაჩვენებლებია გრაფში.
ნამდვილი ფაილები დისკზე. სადაც არედაქტირებთ. არაფერი აღირიცხება, სანამ სტეიჯინგში არ დაამატებთ და არ დააკომიტებთ.
აშკარა შუალედური შრე. git add ზუსტად არჩევს, რომელი ცვლილებები მოხვდება შემდეგ სნეპშოტში — ასე კომიტები ფოკუსირებული რჩება.
უცვლელი. იდენტიფიცირდება ჰეშით. ატარებს მშობლის ბმულს, შეტყობინებას, ავტორსა და დროის ნიშნულს. ისტორიის ერთეული.
სხვა რეპოზიტორია (მაგ. origin). push და fetch კომიტებს თქვენსა და მას შორის ასინქრონებს.
revert-ს, cherry-pick-სა და bisect-ს თეორიულის ნაცვლად ძლიერს ხდის.reflog-ში — Git უსაფრთხოების ბადეა, როგორც კი მოდელს ენდობით.მოდელი მარტივია; დისციპლინა კი ვორქფლოუა. მიზანია ინტეგრაცია ხშირად და პატარა ნაწილებად, რომ მერჯები ტრივიალური დარჩეს და რევიუ — ადამიანის ზომის. შემდეგ შეგნებული არჩევანი — რებეისი თუ მერჯი — წყვეტს, როგორ გამოიყურება თქვენი ისტორია.
B-ზე ფორკავთ, იზოლირებულად აკეთებთ ფოკუსირებულ სამუშაოს (f1, f2), შემდეგ უკან მერჯავთ M-ზე — main მთელი ამ დროის განმავლობაში გასაშვებად მზადაა.
git switch -c feature main-იდან პირად ხაზს გამოჰყოფს; რასაც არ უნდა აკეთებდეთ, ჯერ ვერაფერს გატეხავთ.main დამოუკიდებლად აგრძელებს მოძრაობას.git rebase main (ან ჩაამერჯეთ), რომ კონფლიქტები თითო-ოროლად იპოვოთ და არა ერთბაშად.მერჯ-კომიტს M ორი მშობელი ჰყავს — ბრენჩები ხილული რჩება. ისტორიის ერთგულია, მაგრამ გრაფი განშტოვდება.
რებეისი f1, f2-ს გადაწერს როგორც f1', f2'-ს main-ის თავზე — ხაზოვანი ისტორია, მაგრამ ახალი ჰეშები.
main-ს, შეინარჩუნეთ ხანმოკლედ, ადრევე გახსენით PR.git rebase main (ან pull --rebase), რომ ბრენჩი აქტუალური და მოწესრიგებული იყოს, სანამ ის ჯერ კიდევ თქვენია.main-ში PR-ის გავლით — squash თუ merge-commit, აირჩიეთ ერთი და თანმიმდევრული იყავით.main: სავალდებულო შემოწმებები და რევიუ, პირდაპირი push-ის გარეშე. ბრენჩი, რომელზეც ყველა დამოკიდებულია, არასდროსაა გატეხილი.პაიპლაინი არის გუნდის განმარტება იმისა, თუ რას ნიშნავს "მუშაობს" — კოდად დაწერილი და ყოველ ცვლილებაზე იძულებით შესრულებული. ის შლის პროგრამირების ორ ყველაზე ცუდ სიტყვას — "უნდა მუშაობდეს" — და მათ მწვანე ნიშნით ან წითელი X-ით ცვლის.
ერთი ცვლილება იდენტურ ეტაპებში გაივლის. დეპლოი კარიბჭესთანაა — ერთი წითელი ეტაპიც კი აჩერებს ხაზს.
როგორც საკონვეიერო ხაზი ხარისხის კარიბჭით — არაფერი გადადის შემდეგ სადგურზე, სანამ მიმდინარე არ გაივლის.
GitHub-ში ჩაშენებული CI. ნულოვანი ინფრასტრუქტურა, მრავალჯერადი გამოყენების ექშენების უზარმაზარი მარკეტპლეისი და კონფიგურაცია, რომელიც კოდის გვერდით ცხოვრობს (.github/workflows).
ერთი აპლიკაცია რეპოზიტორიისთვის, CI-სთვის, რეესტრისა და ისუებისთვის. ძლიერი პაიპლაინები (ეტაპები, needs, გარემოები) და რანერები, რომლებსაც თავად ჰოსტავთ, რომ აკონტროლოთ, სად სრულდება ბილდები.
ვეტერანი — ღია კოდი, ეშვება ყველგან, ~1,800 პლაგინი, უსასრულოდ კონფიგურირებადი. მეორე მხარე: თქვენ ოპერირებთ — სერვერები, აგენტები, პლაგინების განახლებები და ყველაფერი.
მარტივი წესი: უკვე GitHub/GitLab-ზე ხართ? გამოიყენეთ მათი მშობლიური CI — ის ყველაზე ნაკლებ სამართავს ითხოვს. Jenkins-ს მიმართეთ მაშინ, როცა გჭირდებათ თვითჰოსტინგის მოქნილობა, რომელსაც SaaS რანერი ვერ მოგცემთ.
ბილდის ინსტრუმენტი წყაროს გაშვებად არტეფაქტად აქცევს; პაკეტების მენეჯერი კი იმ ბიბლიოთეკებს აგვარებს, რომლებზეც დამოკიდებული ხართ. მთელი თამაში გამეორებადობაზეა — თქვენმა მანქანამ, თანაგუნდელისამ და CI-მ ერთი და იგივე შედეგი უნდა მოგცეთ, თორემ „ჩემს მანქანაზე მუშაობს“ კვლავ დაგიბრუნდებათ.
package.json); ის კი წერს lockfile-ს, რომელიც ზუსტად აღრიცხავს, რა მიიღეთ — ყოველი ბიბლიოთეკის ზუსტ ვერსიას და ჩექსუმს (ანაბეჭდს, რომელიც ადასტურებს, რომ ჩამოტვირთული ფაილი არ შეცვლილა და არ დაზიანებულა).აყენებთ A-სა და B-ს; ამასთან იღებთ C-საც — ტრანზიტულ დამოკიდებულებას. lockfile კი წყვეტს, ზუსტად რომელი C.
მრღვევი ცვლილება
ახალი ფუნქციონალი
შესწორება
^1.4.2 ნიშნავს „1.x, ნებისმიერი ≥ 1.4.2“ — თანხმდებით მომავალ minor და patch ვერსიებზე.^1.4.2); lockfile აღრიცხავს რეალობას (1.6.0 + ჩექსუმი).დაჰეშეთ შემავალი მონაცემები; თუ არაფერი შეცვლილა, ხელახლა გამოიყენეთ შედეგი. სხვაობა 20-წამიან და 20-წუთიან ბილდს შორის.
აკონტროლეთ დავალებების დამოკიდებულებების გრაფი და ხელახლა გამოთვალეთ მხოლოდ ის ნაწილი, რომელსაც ცვლილება შეეხო — სწრაფი ლოკალური ციკლების გული.
„დალუქული“ ბილდი, რომელიც მხოლოდ იმ შემავალ მონაცემებს იყენებს, რაც ცხადად ჩამოთვალეთ — და არა შემთხვევით ინსტრუმენტს, რომელიც უბრალოდ თქვენს ლეპტოპზეა დაყენებული. სწორედ ეს ხდის, რომ შედეგი ყველგან ერთნაირი გამოვიდეს.
გააერთიანეთ თქვენი კოდი და მისი ბიბლიოთეკები ერთ გასაშვებ ფაილში და გადააგდეთ ის კოდი, რომელსაც სინამდვილეში არავინ იყენებს (ამას tree-shaking ჰქვია). ერთი შედეგი, გაშვებადი ყველგან.
სამივე ერთსა და იმავე ძირითად საქმეს აკეთებს JavaScript-ის სამყაროსთვის — აყენებს თქვენს ბიბლიოთეკებს და წერს lockfile-ს. ისინი ძირითადად სიჩქარითა და დისკის მოხმარებით განსხვავდებიან.
მოყვება Node.js-ს, ამიტომ უკვე ყველა მანქანაზეა.
თითოეული ბიბლიოთეკის ერთ საერთო ასლს ინახავს და პროექტებს მასზე აბამს დუბლირების ნაცვლად.
ინსტრუმენტი, რომელმაც lockfile-ები და workspace-ები გაავრცელა; თანამედროვე ვერსიები სწრაფი და კონფიგურირებადია.
როგორ ავირჩიოთ: ნაგულისხმევად აიღეთ npm — ის უკვე იქაა და პროექტების უმეტესობისთვის სავსებით საკმარისი. გადადით pnpm-ზე, როცა დიდ რეპოზიტორიაში ინსტალაციის სიჩქარე და დისკი დაგტკივდებათ. yarn გამოიყენეთ, თუ თქვენი გუნდი უკვე მას იყენებს.
ბილდის რანერი არის ინსტრუმენტი, რომელიც რეალურად ასრულებს ბილდის ნაბიჯებს თანმიმდევრობით (კომპილაცია, ტესტი, შეფუთვა). სპექტრის ორი ბოლო:
ათწლეულების წინანდელი ინსტრუმენტი, რომელიც თქვენ მიერ ჩაწერილ ბრძანებათა სიას ასრულებს და გამოტოვებს იმ ნაბიჯებს, რომელთა შემავალი მონაცემებიც არ შეცვლილა.
Google-ის ბილდის სისტემა: დალუქული, ქეშირებული, ინკრემენტული ბილდები, შექმნილი უზარმაზარი, მრავალენოვანი კოდის ბაზებისთვის.
როგორ ავირჩიოთ: მცირე პროექტებისთვის მიმართეთ Make-ს (ან თქვენი ენის ჩაშენებულ ინსტრუმენტს); Bazel-ს კი მხოლოდ მაშინ, როცა გიგანტური, მრავალენოვანი მონორეპო მის სირთულეს ამართლებს.
დებაგინგი სისწორეზეა — რატომ არის არასწორი? პროფილირება წარმადობაზეა — რატომ არის ნელი? ორივე მოსაზრებას მტკიცებულებით ცვლის. სენიორის ნაბიჯი პასუხის ცოდნა კი არაა; ის იმის ცოდნაა, როგორ იპოვო პასუხი სწრაფად.
function total(items: Item[]) { let sum = 0 console.log("here 1") // edit, rerun, for (const i of items) { console.log("i =", i) // edit, rerun, sum += i.price // edit, rerun... } console.log("sum =", sum) // one variable at a time return sum }
function total(items: Item[]) { let sum = 0 for (const i of items) { sum += i.price // ⏸ breakpoint here } return sum } // pause → inspect items, i, sum, the call // stack & every scope. step / continue. no rerun.
flame graph: ყველაზე განიერი ზოლები იქაა, სადაც დრო მიდის. deepClone 45%-ს ჭამს — სწორედ ეს არის თქვენი ერთი ცვლილება.
როგორც ექიმი, რომელიც ოპერაციამდე სკანირებას ნიშნავს — არ ჭრით იქ, სადაც არ სტკივა.
გააჩერეთ, დაათვალიერეთ, გადადგით ნაბიჯი, დააკვირდით. პირობითი და logpoint ბრეიკპოინტები იშვიათ შემთხვევას იჭერენ გამონატანის დატბორვის გარეშე.
ორობითი ძებნა ისტორიაში: მონიშნეთ კარგი და ცუდი კომიტი და Git ზუსტად იმასთან მიგიყვანთ, რომელმაც გატეხა — log₂(n) ნაბიჯში.
პროდაქშენში პროგრამას დებაგერით ვერ გააჩერებთ. ამის ნაცვლად ეყრდნობით ლოგებს (რა მოხდა), მეტრიკებს (რიცხვები დროში) და ტრეისებს (გზა, რომელიც ერთმა მოთხოვნამ გაიარა), რომ გაარკვიოთ, რა წავიდა ცუდად.
თქვენი რედაქტორი (ან IDE — Integrated Development Environment, რედაქტორი ჩაშენებული დებაგერით, ძებნითა და ინსტრუმენტებით) არის ადგილი, სადაც ამ საქმის უმეტესობა ხდება. სამი, რომელსაც ყველაზე ხშირად შეხვდებით:
უფასო, მსუბუქი რედაქტორი Microsoft-ისგან, დანამატების უზარმაზარი ბიბლიოთეკით თითქმის ყველა ენისთვის.
სრულფასოვანი IDE-ების ოჯახი (IntelliJ, PyCharm, WebStorm…) ჩაშენებული, ღრმა ენობრივი გაგებით.
კლავიატურაზე აგებული რედაქტორი, რომელიც პირდაპირ ტერმინალში მუშაობს და მთლიანად თქვენ მიერ კონფიგურირდება.
როგორ ავირჩიოთ: VS Code უსაფრთხო ნაგულისხმევია ხალხის უმეტესობისთვის. JetBrains აირჩიეთ, როცა ერთი ძირითადი ენისთვის მაქსიმალური ჩაშენებული სიმძლავრე გინდათ, ხოლო Neovim — თუ ტერმინალში ცხოვრობთ და სუფთა სიჩქარეს აფასებთ.
main.„გახადეთ ციკლი მოკლე და ბილდი მოსაწყენი — მაშინ სიჩქარე უბრალოდ ნაგულისხმევი გახდება.“
— მთელი მოხსენება, შეკუმშული
ხუთი სწრაფი კითხვა Git-ის მოდელზე, ვორქფლოუებზე, CI/CD-ზე, ბილდებსა და დებაგინგზე — მყისიერი უკუკავშირი, ავტორიზაციის გარეშე.
ნავიგაცია ← → ღილაკებით ან სქროლით · უკან ბიბლიოთეკაში