Yazılım ve Teknoloji

Semantik Versiyonlama: 1.2.3 Sayıları Aslında Ne Söylüyor?

Rıfat Akarca 👁️ 9 okunma 📅 12/09/2026

Bir ödeme kütüphanesini güncelliyorsunuz. Fonksiyon isimleri aynı, TypeScript derlemesi başarılı, testler yeşil. Ancak üretimde bazı işlemler başarısız oluyor: Önceden null dönen bir fonksiyon artık hata fırlatıyor.

Değişiklik birkaç satırdan oluşabilir. Entegrasyon üzerindeki etkisi ise çok daha büyüktür.

Semantik versiyonlama 1.2.3 sayıları aslında ne söylüyor? Bu sayılar, bir güncellemenin mevcut kullanıcılarla uyumluluğu hakkında ne vaat ettiğini anlatır. Bu yazıda sürüm kararlarını, kurgusal bir ödeme SDK’sının geliştirme süreci üzerinden inceleyeceğiz.

Semantik versiyonlama nedir?

Semantik versiyonlama, sürümleri MAJOR.MINOR.PATCH biçiminde ifade eder:

BölümAnlamıÖrnek geçiş
MAJOR — Büyük sürümGeriye uyumsuz API değişikliği1.2.3 → 2.0.0
MINOR — Küçük sürümGeriye uyumlu yeni işlev1.2.3 → 1.3.0
PATCH — Yama sürümüGeriye uyumlu hata düzeltmesi1.2.3 → 1.2.4

Minor artırıldığında patch; major artırıldığında diğer iki bölüm sıfırlanır. Sistemin temeli, açıkça tanımlanmış bir public API sözleşmesidir. SemVer 2.0.0 şartnamesi

1.2.3 içindeki sayılar özellik veya hata adedini göstermez. Hangi işlemlerin değiştiğini öğrenmek için sürüm notlarını incelemek gerekir.

Vaka: Ödeme SDK’sında sürüm kararı vermek

Aşağıdaki senaryo öğretici amaçla oluşturulmuştur; gerçek bir şirketin olay raporu değildir.

Üç farklı uygulamanın kullandığı payment-client adlı bir TypeScript SDK’sı düşünelim. Mevcut sürüm 1.2.3 olsun.

SDK’nın belgelenmiş sözleşmesi şöyle:

type Payment = {
  id: string;
  amount: number; // Kuruş cinsinden tam sayı
  status: "pending" | "paid";
};

declare function getPayment(
  id: string
): Promise<Payment | null>;

Belgelerde ayrıca şu davranışlar tanımlanmış:

  • Ödeme bulunamazsa fonksiyon null döndürür.
  • Tutar, kuruş cinsinden ifade edilir.
  • Ağ hatalarında NetworkError fırlatılır.

Ekibin önünde üç ayrı değişiklik var. Aşağıdaki kararların her biri, başlangıç sürümü 1.2.3 kabul edilerek değerlendiriliyor.

Değişiklik 1: Belgelenmiş davranışı düzeltmek

SDK, bazı 404 yanıtlarında yanlışlıkla NetworkError fırlatıyor. Oysa sözleşme, ödeme bulunamadığında null döneceğini belirtiyor.

Düzeltme sonrasında:

if (response.status === 404) {
  return null;
}

Bu senaryoda 1.2.4 uygun bir sürüm kararıdır. Değişiklik, tanımlanan davranışı sağlıyor ve desteklenen kullanım biçimlerini koruyor.

Yine de sürüm öncesi şu soruyu araştırmak gerekir: Tüketici uygulamalar hatalı davranışı fark edip etrafına özel bir çözüm geliştirmiş mi?

Böyle bir kullanım varsa düzeltmenin duyurusu ve geçiş planı ayrıca ele alınmalıdır. “Bug fix” etiketi tek başına kullanıcı etkisini açıklamaz.

Değişiklik 2: İsteğe bağlı özellik eklemek

Ürün ekibi, ödeme sorgusunda makbuz bilgisinin de alınmasını istiyor:

type GetPaymentOptions = {
  includeReceipt?: boolean;
};

declare function getPayment(
  id: string,
  options?: GetPaymentOptions
): Promise<Payment | null>;

Mevcut çağrı geçerliliğini koruyor:

await getPayment("pay_123");

Yeni özellik isteyen tüketici ise ikinci parametreyi kullanıyor:

await getPayment("pay_123", {
  includeReceipt: true
});

Eski çağrıların davranışı korunduğu varsayımıyla 1.3.0 uygun seçimdir.

Buradaki kritik kontrol, parametrenin gerçekten isteğe bağlı kalmasıdır. Yeni seçenek verilmediğinde ek ağ isteği yapılıyor veya farklı hata koşulları oluşuyorsa uyumluluk değerlendirmesi genişletilmelidir.

Değişiklik 3: Tutarın birimini değiştirmek

Ekip, geliştiricilerin işini kolaylaştırmak için amount alanını kuruş yerine TL olarak döndürmek istiyor:

// Önce
{ amount: 12500 }

// Sonra
{ amount: 125 }

Alan adı ve veri tipi aynı kaldığından derleme başarılı olabilir. Fakat mevcut tüketici şu işlemi yapıyorsa:

const displayAmount = payment.amount / 100;

Ekranda 125 TL yerine 1,25 TL gösterilir.

Bu değişiklik için 2.0.0 gerekir. Sözleşmede belirtilen ölçü birimi değişmiştir. Statik tip kontrolü, bu örnekteki anlam değişikliğini yakalayamaz.

İleri seviye mesele: Uyumluluğun kapsamı

Bu vakada yalnızca fonksiyon imzasını karşılaştırmak yeterli değildir. İnceleme sırasında tüketicinin gözlemlediği davranışları da değerlendirmek gerekir:

DeğişiklikBu SDK’da incelenecek etki
null yerine hata fırlatılmasıTüketicinin kontrol akışı değişir
Kuruş yerine TL döndürülmesiHesaplamalar yanlış sonuç üretir
Yeni durum değeri eklenmesiTüm durumları ele alan tüketici kodu etkilenebilir
Desteklenen çalışma ortamının daraltılmasıBazı tüketiciler paketi çalıştıramayabilir
Varsayılan yeniden deneme davranışının değişmesiİstek sayısı ve işlem süresi değişebilir

Örneğin status alanına "refunded" eklemek ilk bakışta yalnızca genişletme gibi görünür. Ancak tüketici, olası değerleri eksiksiz ele alan bir kontrol yazmış olabilir:

function assertNever(value: never): never {
  throw new Error(`Beklenmeyen durum: ${value}`);
}

function label(status: Payment["status"]): string {
  switch (status) {
    case "pending":
      return "Bekliyor";
    case "paid":
      return "Ödendi";
    default:
      return assertNever(status);
  }
}

Tip birleşimi genişletildiğinde bu kod derleme hatası verebilir. Bu SDK için durum kümesinin kapalı mı, genişletilebilir mi olduğu baştan belgelenmelidir.

Kırıcı değişikliği aşamalı uygulamak

Tutar birimini değiştirmek için doğrudan mevcut alanın anlamını değiştirmek yerine şu geçiş tasarlanabilir:

  1. 1.3.0 sürümünde amountTRY alanını ekleyin; amount davranışını koruyun.
  2. Belgelerde eski alanı kullanımdan kaldırılacak olarak işaretleyin.
  3. Tüketici uygulamaları yeni alana taşıyın.
  4. Eski alanı 2.0.0 sürümünde kaldırın.

Public API’de kullanımdan kaldırma bildirimi minor artış gerektirir; uyumsuz kaldırma major değişikliktir. SemVer sürüm artırma kuralları

Bu geçişte kabul ölçütü somuttur: Eski tüketiciler kuruş hesabını sürdürebilmeli, yeni tüketiciler TL alanını kullanabilmelidir. İki alanın dönüşüm tutarlılığı da test edilmelidir.

^1.2.3 kullanmak güncellemeyi güvenli kılar mı?

npm ekosisteminde sürüm aralıkları, hangi sürümlerin seçilebileceğini belirler. Kararlı sürümler açısından:

Tanımİzin verilen aralık
1.2.3Yalnızca bu sürüm
~1.2.31.2.3 ve üzeri, 1.3.0 altı
^1.2.31.2.3 ve üzeri, 2.0.0 altı
^0.2.30.2.3 ve üzeri, 0.3.0 altı
^0.0.3Yalnızca 0.0.3

Ön sürümlerin aralığa dahil edilmesi ayrıca kurallara bağlıdır. ^ ve ~, npm’in aralık yorumlama davranışlarıdır. node-semver belgeleri

Vakamızda ekip, tutar birimini yanlışlıkla 1.2.4 altında yayımlarsa ^1.2.3 bu hatalı sınıflandırmayı anlayamaz. Aralık denetimi paketin iş mantığını incelemez.

package-lock.json, çözümlenen bağımlılık ağacını kaydederek aynı ağacın yeniden kurulabilmesini sağlar. Uyumluluğu ise uygulama testleriyle değerlendirmek gerekir. npm package-lock.json belgeleri

Sürüm kararını CI sürecine taşımak

Bu SDK için yayın kontrolünü üç parçaya ayırabiliriz.

API kontrolü: Dışa aktarılan tipleri karşılaştırın. Kaldırılan alanları ve zorunlu hâle gelen parametreleri görünür kılın.

Davranış kontrolü: 404 → null, tutarın kuruş olması ve ağ hatasının türü gibi vaatleri test edin.

Tüketici kontrolü: SDK’nın aday sürümünü kullanan örnek uygulamalarda derleme ve entegrasyon testleri çalıştırın.

Örneğin tutarın anlamını koruyan bir sözleşme testi şöyle olabilir:

it("125 TL tutarını 12500 kuruş olarak döndürür", async () => {
  // Test sunucusundaki kayıt: 125 TL
  const payment = await client.getPayment("pay_125_try");

  expect(payment?.amount).toBe(12500);
});

Bu test, veri tipi değişmeden yapılan birim değişikliğini yakalar. Yayın kontrolünde sorulacak soru da nettir: Değişiklik hangi tüketici beklentisini etkiliyor ve seçilen sürüm bunu doğru anlatıyor mu?

Ön sürüm ve derleme bilgisi nasıl okunur?

2.0.0-rc.1+build.482 örneğinde rc.1 ön sürümü, build.482 derleme üstverisini belirtir. Ön sürüm, aynı numaralı normal sürümden önce sıralanır; derleme üstverisi önceliği değiştirmez. Yayımlanmış sürümün içeriği değiştirilmemelidir. SemVer şartnamesi

Vakamızda rc.1, tüketici uygulamaların yeni tutar modelini deneyeceği bir aday olarak kullanılabilir. Yayın kararı, yalnızca SDK testlerine değil, bu uygulamaların geçiş sonuçlarına da bağlanabilir.

Vakanın sonucu: Sürüm numarası bir mühendislik kararıdır

Ödeme SDK’sındaki üç değişiklik, farklı kontroller gerektirdi: Hata düzeltmesinde belgelenmiş davranış, yeni özellikte eski çağrıların korunması, birim değişikliğinde tüketicinin hesaplamaları incelendi.

Ekibinizin bir sonraki sürüm incelemesinde şu soruyla başlayın:

“Mevcut kullanıcı bu güncellemeyi aldığında hangi varsayımları geçerliliğini koruyacak?”

Bu soruya kod, belge ve testlerle cevap verebildiğinizde, 1.2.3 anlamlı bir uyumluluk iletişimine dönüşür.