Semantic Versioning: Sürüm Numaralarının Gizli Dili

Bir paketin 2.4.1 sürümünü gördüğünüzde bunun sadece üç rastgele sayı olduğunu düşünmek kolaydır. Oysa doğru kullanıldığında bu numara, güncellemenin projenizi bozup bozmayacağına dair güçlü bir sözleşmedir. Semantic Versioning (SemVer), geliştiriciler, paket yöneticileri ve kullanıcılar arasında ortak bir dil kurar: Yeni özellik mi geldi, hata mı düzeldi, yoksa mevcut entegrasyonlar tehlikede mi? `` SemVer’in temel biçimi MAJOR.MINOR.PATCH şeklindedir. Matematiksel olarak bir sürümü $V=(M,m,p)$ üçlüsüyle ifade edebiliriz. Burada $M$ ana sürüm, $m$ küçük sürüm ve $p$ yama sürümüdür. Sürüm karşılaştırması soldan sağa yapılır: Önce ana sürüme, eşitse küçük sürüme, o da eşitse yamaya bakılır. Bu nedenle $2.10.0 > 2.9.9$ olur; sayılar metin değil, sayısal değerlerdir.

En önemli kavram geriye uyumluluktur. Bir kütüphanenin eski kullanıcı kodlarını çalıştırmaya devam etmesi, geriye uyumlu olduğu anlamına gelir. Örneğin calculateTotal() fonksiyonuna isteğe bağlı bir parametre eklemek çoğunlukla uyumludur. Buna karşılık fonksiyonun adını değiştirmek veya dönüş tipini tamamen farklılaştırmak, kullanıcıların kodunu kırabilir.

Bölüm Ne zaman artar? Örnek değişiklik Kullanıcı için anlamı
MAJOR Geriye uyumsuz değişiklikte Bir API metodunun kaldırılması Kod güncellemesi gerekebilir
MINOR Uyumlu yeni özellikte Yeni, isteğe bağlı endpoint Güvenle yeni yetenek kullanılabilir
PATCH Uyumlu hata düzeltmesinde Hatalı doğrulamanın düzeltilmesi Güncellemek genellikle güvenlidir

Örneğin 1.3.5 sürümünde çalışan bir API düşünelim. Sadece ödeme hesaplamasındaki yuvarlama hatasını düzeltiyorsanız sürüm 1.3.6 olmalıdır. Yeni bir refundPayment() endpoint’i eklediyseniz 1.4.0 mantıklıdır. Ancak createPayment() metodunun parametrelerini zorunlu biçimde değiştiriyorsanız 2.0.0 yayınlamalısınız. Kuralı kısa bir karar ağacı gibi düşünebilirsiniz:

Geriye uyumsuz değişiklik var mı?
├─ Evet: MAJOR artır, MINOR ve PATCH sıfırla
└─ Hayır: Yeni uyumlu özellik var mı?
   ├─ Evet: MINOR artır, PATCH sıfırla
   └─ Hayır: PATCH artır

Bu yapı özellikle npm, Composer, pip ve Maven gibi paket ekosistemlerinde hayat kurtarır. Bağımlılık aralıkları, hangi güncellemelerin otomatik alınabileceğini sürüm numarasına göre belirler. JavaScript dünyasında örneğin şu ifade yaygındır:

{
  "dependencies": {
    "example-lib": "^1.4.2"
  }
}

Buradaki ^1.4.2, çoğu araçta >=1.4.2 ve <2.0.0 anlamına gelir. Yani hata düzeltmeleri ve uyumlu özellikler alınabilir; olası kırıcı 2.0.0 güncellemesi otomatik gelmez. Bu, teoride güzel görünen SemVer’in pratikte neden kritik olduğunu gösterir: Paket yöneticisi, sizin verdiğiniz sözlere göre risk hesabı yapar.

Ön sürümler de bu dilin parçasıdır. 2.0.0-alpha.1, 2.0.0-beta.2 ve 2.0.0-rc.1 gibi ekler, sürümün henüz üretim için tam kararlı olmayabileceğini söyler. Genel akış şöyledir:

Ek Amaç Kararlılık
alpha Erken geliştirme ve deney Düşük
beta Özellikleri büyük ölçüde tamamlanmış test Orta
rc Yayın adayı, son kontroller Yüksek
Ek yok Kararlı üretim sürümü En yüksek

SemVer kullanırken iki disiplin şarttır. Birincisi, herkese açık API’nin ne olduğunu açıkça belgelemektir; belgelenmemiş davranışların kullanıcı tarafından kullanılmayacağını varsaymak risklidir. İkincisi ise değişiklik kayıtlarını (CHANGELOG) sürüm numaralarıyla birlikte tutmaktır. İnsanlar 3.1.0 gördüğünde ne kazanacaklarını, 4.0.0 gördüğünde ise neyi değiştirmeleri gerektiğini hızla anlayabilmelidir.

Sonuçta Semantic Versioning, sayıları büyütme ritüeli değil; güven inşa etme mekanizmasıdır. Sürüm numaranız ne kadar dürüstse, kullanıcılarınızın güncelleme tuşuna basması da o kadar cesur olur.

semantic-versioning-surum-95

Yorumlar