deniz.in

Piyasalar

Hava durumu

Hava durumu yükleniyor

· kaynak dev.to (home feed)

bol'un Yarn'dan pnpm'e Backstage migrasyonu CI cache ve worktree tuzaklarını ortaya çıkardı

Beş yıldır süren bol'un Backstage platformu Yarn 4'ten pnpm'e geçti ve bozuk CI cache'leri, 1,42 GB'lık bir arşiv ve kaldırılması gereken 350 satırlık özel worktree symlink koduyla karşılaştı.

bol'un Yarn'dan pnpm'e Backstage migrasyonu CI cache ve worktree tuzaklarını ortaya çıkardı

Yalnızca bitmiş gibi görünen bir migrasyon

dev.to'da yazan bol geliştiricisi Bogdan Nechyporenko, şirketin dahili Backstage platformunu Yarn 4'ten pnpm'e taşıma sürecini anlatıyor. Platform beş yılı aşkın süredir çalışıyor ve etrafında kendi kuralları birikmiş: CI kurulumu, yerel başlatma araçları, container imajları ve Git worktree'ler etrafında kurulmuş yardımcı araçlar.

Worktree'ler bol'un çalışma şeklinin merkezinde. Ekip paralel kodlama ajanları çalıştırıyor, her biri kendi worktree'sinde; böylece bir ajan bir hatayı düzeltirken bir diğeri başka bir yerde iyileştirme yapabiliyor ve dallar tek bir çalışma dizini için kavga etmiyor. Bu iş akışı paket yöneticisini mimarinin bir parçası hale getirdi ve pnpm'in vaadi — checkout'lar arasında güvenli yeniden kullanımla paylaşılan içerik adresli bir store — daha iyi bir uyum gibi görünüyordu.

Görünürdeki geçiş hızlı oldu: pnpm 12.3.0'ı sabitlemek, lockfile'ı commit etmek, Yarn komutlarını değiştirmek, katkıcı rehberlerini güncellemek. Sonra CI çalıştı.

CI her çalışmada 4.226 paket indiriyordu

İlk pipeline sıfırdan 4.226 paket indirdi. Sonraki da öyle. İndirmeler kabaca 18 saniye sürüyordu ama yerel node-gyp derlemeleri birkaç dakika ekledi ve pipeline sanki hiç cache yokmuş gibi davrandı.

Bir cache vardı — sadece yanlış yere bakıyordu. Gönderiye göre container imajı, store'u /builds/.pnpm-store'a yönlendiren global bir pnpm yapılandırması taşıyordu; GitLab ise proje checkout'u içindeki .pnpm-store'u arşivlemeye çalışıyordu. pnpm arşivlenen dizinin dışına yazıyordu, dolayısıyla sonraki her iş soğuk başlıyordu.

Çözüm, CI'da store dizinini açıkça ayarlamak ve iş kaydının bunu kanıtlaması için geçerli değeri yazdırmak oldu. Daha genel ders: bir paket yöneticisinin cache'ini yalnızca yapılandırma dosyalarından yola çıkarak yorumlamayın; çalışan işe store'unun gerçekte nerede olduğunu sorun. Ekip ayrıca script hatalarını otomatik yeniden denemeyi bıraktı, çünkü frozen-lockfile uyuşmazlığı altı kez aynı şekilde başarısız oluyor ve bu sırada altı runner'a fatura kesiyor.

Çalışan cache darboğaz oldu

Store cache'lendiğinde yeni bir sorun ortaya çıktı. Arşiv artık pnpm store'unu ve her node_modules ağacını içeriyordu: dört işin çektiği kabaca 601.000 dosyada 1,42 GB. Cache'lenen node_modules beklenen zamanı da kazandırmıyordu, çünkü kurulumlar bağımlılık düzenini ve yerel modülleri her durumda yeniden inşa ediyordu.

Cache'ten node_modules yollarını çıkarmak arşivi kabaca 400 MB ve 244.000 dosyaya indirdi — boyutta yaklaşık %72, dosya sayısında %59 azalma — pipeline başına tahmini altı dakika kazandırıyor. Ekip ayrıca kurulumları --frozen-lockfile --prefer-offline ile yapmaya başladı, aktarım ilerlemesini kayıtlarda görünür kıldı ve daha hızlı cache sıkıştırması seçti. Nechyporenko, pnpm'in kendi CI belgelerinin store'u cache'lemenin kurulumu hızlandıracağının garanti olmadığı uyarısı yaptığını belirtiyor; doğru politika runner'a, ağa ve iş yüküne bağlı.

pnpm, 350 satırlık özel symlink mantığıyla karşılaştı

Yerel geliştirme en zor sürprizi barındırıyordu. Worktree bootstrap'i, Yarn'ın node_modules yapısı etrafında kurulmuş kabaca 350 satırlık özel symlink-çiftliği mantığı içeriyordu; üçüncü taraf bağımlılıkları ana checkout'tan yansıtıyor ve workspace paketlerini her worktree'nin kendi kaynağına yönlendiriyordu. pnpm paketleri sanal bir store üzerinden bağlıyor ve yansıtma kodunun sıradan dizinler beklediği yerde ekip ENOTDIR hataları görmeye başladı.

Symlink çiftliğine pnpm'in düzenini öğretmek yerine onu sildiler. Merkezi yardımcı araç 370 satırdan 31'e indi ve tüm bootstrap tek bir pnpm install --frozen-lockfile komutu oldu. Her checkout pnpm yönetiminde bir kuruluma kavuşuyor; içerik yine paylaşılan store üzerinden yeniden kullanılıyor.

Bir taviz var: yerine geçen doğrulayıcı çok daha hafif, her workspace paketinin doğru çözüldüğünü kanıtlamak yerine node_modules/.pnpm varlığını kontrol ediyor. Nechyporenko hâlâ ikincil bir worktree'de bir plugin'i düzenleyip çalışan uygulamanın o kaynağı kullandığını doğrulayan bir entegrasyon kontrolü istiyor.

Eski makineler eski dünyayı hatırlıyordu

Temiz checkout'lar çalıştı. Bazı mevcut geliştirici makineleri çalışmadı, çünkü hâlâ önceki kurulumdan proje yerel bir .pnpm-store taşıyorlardı. Yerel geliştirme global store'a taşındıktan sonra pnpm art arda başlatmalarda kabaca 4.800 paketi yeniden bağladı — hiç kurulüm gerektirmemesi gereken bir şey için yaklaşık dört dakika.

Çözüm tek seferlik bir başlangıç migrasyonu oldu: artık kullanılmayan yerel store'u tespit etmek, kök node_modules ve bağımlılık hash'i ile birlikte kaldırmak, sonra tek bir temiz kurulüm çalıştırmak. Sonraki başlatmalar kuruluma neredeyse tamamen sıra vermiyor. Nechyporenko bu konuda net: pnpm 4.800 paketi sıfır saniyede kurmadı; başlangıç kodu ne zaman kurulüm gerekmediğini öğrendi. Temizlik de ortama özgü olmak zorundaydı, çünkü CI GitLab'ın arşivlemesi için kasıtlı olarak proje yerel bir store tutarken yerel geliştirme aynı dizini bayat sayıyor.

Neden önemli

Olgun monorepo'larda paket yöneticisi migrasyonları nadiren yalnızca lockfile ve komutlarla ilgili. Bu, container imajlarına, CI cache'lemesine ve yılların özel araçlarına gömülü örtük varsayımları ortaya çıkardı. Ayrıca paket yöneticisi taşıyıcı altyapı hale gelmiş ekipler için erken bir harita görevi görüyor: Git worktree'ler arasında paralel kodlama ajanları verimi artırıyor ama bağımlılık düzenini, cache yerleşimini ve store hijyenini platform mimarisinin bir parçası yapıyor — ve migrasyonlar yalnızca temiz klonlar için değil, mevcut makinelerdeki dağınık durum için de plan yapmak zorunda.

  • #pnpm
  • #yarn
  • #backstage
  • #ci-cd
  • #monorepo
  • #developer-experience

İlgili yazılar