Elle build almak, ekip iki kişi olduğunda uzun süre "şimdilik yeter" kategorisinde kalır. Bu yazıda o eşiği geçtiğimizde neyi betiğe, neyi CI'a taşıdığımızı; hangi adımların otomatikleştikten sonra daha fazla bakım istediğini anlatıyoruz. Sonunda cevap arayacağımız soru şu: iki kişilik bir ekip ne kadar altyapı taşımalı?
Elle build alma sürecinin gerçek maliyeti
Elle build almanın maliyeti geçen süre değil, dikkat. Editörde build almak arka planda dururken başka bir işe geçemezsiniz; geçerseniz de kontrol listesindeki bir adımı atlarsınız. Bizim listemiz kabaca şuydu:
- Doğru dalda olduğunu doğrula, çalışma alanını temizle.
- Sürüm adını ve
versionCode'u elle artır. - Build hedefini ve build profilini kontrol et (bir önceki iş WebGL'de kaldıysa Android'e geri al).
- Keystore'u seç, parolayı gir.
- Build al, çıktıyı bir yere kopyala, adını anlamlı yap.
- Test cihazına at veya test kanalına yükle.
- Neyin değiştiğini yaz.
Yedi adımın altısı mekanik. Hata çıkan yer neredeyse hep aynıydı: sürüm numarası ve imzalama. İkisi de build bitmeden fark edilmiyor, ikisinde de hata mağazaya yükleme anında ortaya çıkıyor. Yani en pahalı hatalar en sıkıcı adımlarda.
İlk adım CI değil, tek komutluk bir betik
Doğrudan CI kurmak yerine ilk olarak süreci tek komuta indirdik. Unity'yi editörsüz çalıştırıp kendi statik metodunuzu tetiklemek belgelenmiş bir yol: -batchmode -quit -projectPath -executeMethod ve build hedefi argümanları Unity el kitabında komut satırından build alma bölümünde tanımlı.
#!/usr/bin/env bash
set -euo pipefail
PROJECT_PATH="$(pwd)"
UNITY_BIN="${UNITY_BIN:?Unity yolu tanimli degil}"
export BUILD_VERSION="${BUILD_VERSION:-0.1.0}"
export BUILD_NUMBER="$(git rev-list --count HEAD)"
export BUILD_OUTPUT="build/android/game-${BUILD_VERSION}-${BUILD_NUMBER}.aab"
mkdir -p "$(dirname "$BUILD_OUTPUT")"
"$UNITY_BIN" \
-batchmode -quit \
-projectPath "$PROJECT_PATH" \
-buildTarget Android \
-executeMethod BuildEntry.Android \
-logFile build/unity-android.log
echo "cikti: $BUILD_OUTPUT"
Editör tarafındaki karşılığı da kısa. Önemli olan, ayarların betikten gelmesi ve hatanın sıfır olmayan çıkış koduna dönüşmesi:
using System;
using UnityEditor;
using UnityEditor.Build.Reporting;
public static class BuildEntry
{
public static void Android()
{
PlayerSettings.bundleVersion = Env("BUILD_VERSION");
PlayerSettings.Android.bundleVersionCode = int.Parse(Env("BUILD_NUMBER"));
PlayerSettings.Android.useCustomKeystore = true;
PlayerSettings.keystoreName = Env("KEYSTORE_PATH");
PlayerSettings.keystorePass = Env("KEYSTORE_PASS");
PlayerSettings.keyaliasName = Env("KEY_ALIAS");
PlayerSettings.keyaliasPass = Env("KEY_PASS");
var options = new BuildPlayerOptions
{
scenes = EditorBuildSettingsScene.GetActiveSceneList(EditorBuildSettings.scenes),
target = BuildTarget.Android,
locationPathName = Env("BUILD_OUTPUT"),
options = BuildOptions.None
};
var report = BuildPipeline.BuildPlayer(options);
if (report.summary.result != BuildResult.Succeeded)
{
Console.Error.WriteLine($"build basarisiz: {report.summary.totalErrors} hata");
EditorApplication.Exit(1);
}
}
static string Env(string key) =>
Environment.GetEnvironmentVariable(key)
?? throw new Exception($"eksik ortam degiskeni: {key}");
}
Bu aşamada hiçbir sunucu, hiçbir runner yok. Kazanç şu: build alma kararı hâlâ insanda, ama build'in içeriği artık kimin aldığına bağlı değil. Küçük ekipte otomasyonun en yüksek getirili kısmı burası ve tek bir betik dosyasıyla geliyor.
Sürüm numaralama: iki alan, iki farklı iş
Sürüm numarası iki ayrı ihtiyaca hizmet ediyor ve bunları karıştırmak en sık gördüğümüz karışıklık. bundleVersion insana bakar: sürüm notlarında, hata raporlarında, oyuncu geri bildiriminde bu görünür. bundleVersionCode mağazaya bakar: yalnızca artması gerekir.
Burada somut bir tuzak var. Tarih tabanlı bir sayaç cazip görünüyor — date +%Y%m%d%H hem sıralı hem okunur. Ama on haneli bir sayı üretir; örneğin 2025101512. Google Play'in kabul ettiği en büyük versionCode değeri ise 2100000000, yani tarih tabanlı şema 2021'den itibaren bu sınırı aşıyor. Aynı sınır Play Console yardım belgelerinde de yazılı.
Biz sayacı depodaki commit sayısına bağladık: git rev-list --count HEAD. Monoton artıyor, herkesin makinesinde aynı sonucu veriyor, ayrı bir dosyada durum tutmuyor. Tek koşulu, sürüm dalı geçmişinin doğrusal kalması; rebase ile ilerleyen bir akışta sorun çıkarmadı.
Sürüm adını ise otomatikleştirmedik. Etiketi elle koyuyoruz, çünkü "bu 0.4.0 mı, 0.3.2 mi?" sorusu teknik değil ürün kararı. Otomatik semantik sürümleme, commit mesajlarını sözleşmeye dönüştürmenizi ister; iki kişilik bir ekipte bu sözleşmeyi denetleyecek kimse yok. Özellik kesme yazısında anlattığımız mantık burada da geçerli: karar gerektiren bir adımı otomatikleştirmek kararı yok etmez, sadece görünmez kılar.
İmzalama: sırları makineden çıkarmak
İmzalama otomasyona en çok değen ikinci adım oldu, ama sadece parolaları makinede tutmayı bıraktığımızda. Kurallarımız kısa:
- Keystore ve parolalar depoda durmaz; CI'da şifreli değişken, yerelde ortam değişkeni olarak gelir.
- Betik eksik değişkeni build'den önce reddeder. İmzasız çıktı üretip yükleme anında öğrenmek en pahalı senaryo.
- Debug ve release imzası aynı betikten, farklı profil adıyla çıkar. Yanlış imzalı bir yapı test cihazında "neden güncellenmiyor?" saatleri doğurur.
Anahtar dosyasının kendisi için otomasyon yok: yedeği çevrimdışı, kimin eriştiği belli. Anahtar rotasyonunu betiğe gömmeye çalışmak, yılda bir kez yapılacak bir işi her gün kırılabilecek bir koda çevirir.
Otomatikleştirince kırılganlaşan adımlar
Her adım betiğe uygun değil. Bizde geri aldığımız veya sınırladığımız üç şey oldu:
Her push'ta build
Kulağa doğru geliyor, pratikte gürültü üretiyor. Mobil build'ler dakikalar sürer, sıraya girer ve iki kişilik ekipte sıradaki iş genelde "bir önceki build'in aynısı". Tetikleyiciyi etikete ve elle çalıştırmaya bağladık; kod kalitesi kontrolü (derleme + testler) her push'ta, tam build talep üzerine.
Mağaza kanalına otomatik yükleme
Yükleme adımını otomatikleştirmek teknik olarak kolay, geri alması zor. Bir sürüm notu boş kaldığında veya yanlış kanal seçildiğinde düzeltme mağaza tarafında bekleme demek. Biz artefaktı CI'da üretip orada bırakıyoruz; yüklemeyi insan yapıyor. Test dağıtımı için Play'in dahili test kanalı, 100 davetli test kullanıcısına kadar dağıtıma izin veriyor; küçük bir test grubu için bu sınır zaten fazlasıyla yeterli.
Otomatik sürüm notu üretimi
Commit başlıklarından üretilen notlar, oyuncuya bir şey anlatmıyor. "fix null ref in card drag" satırının sürüm notunda karşılığı yok. Notu elle yazmak beş dakika; otomatik üretilmiş notu düzeltmek daha uzun sürüyordu.
Bir de altyapı tarafında sürpriz var: derleme ortamının kendisi bakım ister. Unity sürümü, Android SDK/NDK, lisans aktivasyonu, kütüphane önbelleği. Temiz bir makinede her seferinde sıfırdan import etmek build'i uzatır; önbelleği taşımak ise "benim makinemde geçiyor" sınıfı hataları CI'a taşır. Bu, cihaz parçalanmasıyla uğraşırken öğrendiğimiz şeyin başka bir yüzü: ortam farkı, kodun kendisi kadar hata kaynağı.
İki kişilik ekip ne kadar altyapı taşımalı?
Bize işleyen sınır şu oldu: tekrarlanabilirlik otomasyona değer, karar vermek değmez. Uygulamaya çevirirsek:
- Betik yaz, sunucu kurma. Tek komutla build alabiliyorsanız kazancın büyük kısmı elinizde. CI bunun üstüne sadece "başka bir makinede de çalışıyor" garantisi ekler.
- Sessiz hataya yol açan adımları otomatikleştir. İmzalama,
versionCode, çıktı adlandırma. Bunlar yanlış yapıldığında geç fark edilir. - Karar içeren adımları insanda tut. Sürüm adı, sürüm notu, yayına alma.
- Bakım maliyetini baştan hesapla. Bir otomasyon parçası, kazandırdığı süreden fazla bakım istiyorsa hattan çıkar. Bunu ölçmenin basit yolu: son üç sürümde o adımı kaç kez elle düzelttiniz?
Aynı hattı birden fazla oyun için kullanıyorsanız, paylaşımın da bir sınırı var: platform ve mağaza ayarları oyuna özgüdür, ortak kısım build'i tetikleyen kabuk. İki oyun bir kod tabanı yazısında anlattığımız denge burada da geçerli — Thornguard gibi bir strateji oyunuyla Kart Üçlüsü gibi bir kart oyununun ortak ihtiyacı build'i almak; ne paketlediğiniz ayrı iş.
Özetle taşınması gereken altyapı, ekibin büyüklüğüyle değil, hata yapma biçimlerinizle ölçülür. Elle yaptığınız işlerden hangisi son üç sürümde sizi yaktıysa, otomasyon listesinin başına o girer.
Yorumlar
İlk yorumu siz yapın.



