Pazar, Şubat 18, 2007

Sürüm Yönetimi Pratikleri - I

İster kurumsal bir firmanın yazılım departmanı olsun, isterse küçük bir yazılım evi olsun. Yazılım geliştiren her organizasyonun mutlaka bir Sürüm Yönetimi (Release Management) olmalı. Maalesef çoğu kişi tarafından Sürüm Yönetimi deyince akla sadece, program kaynak kodlarının CVS, ClearCase gibi Versiyon Kontrol Sistemlerinde (SCM) saklanması geliyor. Halbuki Sürüm Yönetimi Müşteriyi, Analizi, Tasarımı, Kodlamayı, Test'i ve Deploymentı da içine alan daha kompleks ve uzun bir süreç.

Bu yüzden birkaç blog ile Sürüm Yönetimini anlatmamız mümkün değil. Bunun yerine niyeim işin teoriğine pek girmeden, büyüklüğü ve türü ne olursa olsun her türlü yazılım projelerinde kullanabileceğiniz Süreç Yönetiminin pratiklerinden ve püf noktalarında bahsetmek. Birazdan bahsedeceğim konular daha evvel uyguladığımız ve büyük faydasını gördüğümüz pratiklerdir. Vereceğim örnekler her ne kadar Java uygulamalarına ait olsa da benzer mantıkla diğer tüm programlama dillerine de uyarlanabilir.

Bu konuyla ilk defa haşır-neşir olacakların, birazdan çok bahsi geçecek bazı araçlar ve metodolojiler hakkında altyapı oluşturmaları gerekiyor ki Süreç Yönetimi pratiklerini anlamaları ve kendi projelerinde uygulamaları kolay olsun. Bu yüzden lütfen öncelikle aşağıdaki linklere bir göz atalım:
Sürüm Numarası
Sürüm Yönetiminin temel yapı taşı Sürüm Numarasıdır. Bu yüzden bir projeye başlamadan evvel Sürüm Numarası'nın hangi formatta olacağını, bu numarayı nasıl (manual/automatic) üreteceğimizi, farklı ortamlar (Development, Test, Production, vs.) için nasıl farklılaştıracağımız belirlememiz gerekiyor.
Eğer çok sık (2-3 günde bir) sürüm/deployment yapılan bir projenin Sürüm Yönetimini yapacaksanız Sürüm Numarası'nı olabildiğince detaylı bilgi içerecek şekilde tasarlayın. Eğer sürümleriniz arasında uzun süreler var ise Sürüm Numarasının çok detaylı olmasına gerek yok.
Ben genelde kendime Açık Kaynak dünyasını örnek aldığım için bu konuda da yaklaşık 2-3 ayda bir sürüm çıkaran JBoss'u örnek vereceğim:

Product versions follow this format X.YY.ZZ.Q* (i.e. 1.2.3.GA, 1.2.3.CR1, 1.2.3.Alpha1-20060205091502)

X signifies major version related to production release. This is a number.
YY signifies minor version with minor feature changes or additions (use of even numbers is preferred...3.0, 3.2, 3.4, etc.). This is a number.
ZZ signifies patches and bug fixes. Minor features that do not introduce backward compatibility issues are ok. This is a number.
Q* is an alpha-numeric qualifier. The prefix of the qualifier needs to match the qualifier conventions listed below to ensure that versions can be compared consistently in terms of version ordering.
Major versions are usually developed in multiple iterations. Each iteration concludes with an intermediate version release. Intermediate versions are annotated with appropriate suffixes. This shows the progression of release versions. A given release may not have all stages of releases shown here.

Yukarıdaki örnekte görüldüğü gibi genelde Sürüm Numaralarında 3 veya 4 basamaklı "." işareti ile biribirinden ayrılmış numaralar kullanılır. Bu numaralar her zaman, atlama yapmadan sırayla arttırılır. X genelde projeniz büyük yapısal veya fonksiyonel değişiklik var ise arttırılır. YY ise genelde production ortamına planlı yeni özelliklerin alındığı sürümlerde arttırılır. ZZ genelde test veya prod ortamlarında alınan bugfix ve improvement'lar için arttırılır. Q ise Build Number diye tabir edilen özellikle development ortamları gibi çok sık çıkarılan sürümleri biribirinden ayırmak için kullanılan bir numaradır.
Bu bilgiler ışığında projelerinizin büyüklüğüne ve sürüm çıkarma sıklığına göre kullanabileceğiniz bazı numaralandırma formatları şunlar:
  • [Project_Name]_X.YY.ZZ --> TestProject_2.1.2
  • [Project_Name]_X.YY.ZZ_[Date] --> TestProject_2.1.2_15022006
  • [Project_Name]_X.YY.ZZ_[Date]_[Time] --> TestProject_2.1.2_15022006_1300
  • [Project_Name]_X.YY.ZZ_[Date]_[Time]_[Build Number] --> TestProject_2.1.2_15022006_1300_[114]
  • [Project_Name]_X.YY.ZZ_[Date]_[Time]_[Environment]_[Build Number] --> TestProject_2.1.2_[Test]_15022006_1300_[114]
Sürüm Numarası formatına karar verdiğimize göre bu sürüm numarasını nerelerde kullanacağımıza da karar vermemiz gerekiyor. Edindiğim tecrübeler ışığında söyleyebilirim ki "Biz Sürüm Yönetimi yapıyoruz" diyebilmeniz için aşağıdaki 3 ortama Sürüm Numaralarını senkronize bir şekilde girmeniz gerekiyor.

  • Runtime (Version.class)
  • Version Control Tool (Label, Version, Tag, etc.)
  • Issue & Bug Tracking Tool (Version)
Runtime (Version.class)
Sürüm Yönetimi yaptığını düşünen organizasyonların yaptığı en büyük hatalardan biri de, versiyon bilgisini deploy ettirdikleri kodların içine bir yere kaydetmemeleridir. İster bir class içerisinde, isterse bir property dosyası içerisinde olsun Sürüm Numarası mutlaka derlediğiniz paketin içinde bulunmalıdır. Peki bunun bize ne yararı olur:
  • Deployment hatalarının önceden tespiti. Eğer derlediğiniz uygulamaları adminler tarafından manual olarak yapılıyorsa, yanlış paketin kopyalanması, cache'in temizlenmemesi, vs. gibi hataları paketinizin içindeki Sürüm Bilgisi sayesinde hemen farkedebilirsiniz.
  • Tespit edilen bugların sürüm bazında raporlanması. Test elemanları buldukları hataları Issue Tracking Tool 'unuza girerken, hatanın ortaya çıktığı sürüm numarasını bu bilgi sayesinde tespit edeceklerdir. Hangi sürümde ne kadar hatanın yakalandığı bilgisi Sürüm Yöneteminin en önemli çıktılarından birisidir.
Sürüm Bilgisi genelde ya jar dosyaları içerisindeki MANIFEST dosyalarında, ya property dosyalarında ya da sembolik bir java dosyası içerisinde saklanır. Ben genelde Version.class isminde bir java dosyasında saklamayı tercih ediyorum. Sürüm bilgisini uygulamaların içerisine 2 yöntemden biri kullanarak yerleştirilebilir.

a) Manuel olarak Konfigürasyon Yöneticinizden veya bir developer'dan her sürüm çıkışı öncesi, önceden yayınladığınız Sürüm Numarasını formatını sizin belirlediğiniz bir Version.class'ı içerisine güncellemesini isteyebilirsiniz. Bu yöntem hataya, unutkanlığa çok açık olduğu için benim çok tercih ettiğim bir yöntem değildir. Fakat 2-3 haftada bir gibi uzun aralıklarla sürüm çıkartıyorsanız bu işi manual yapmakta hiç bir sakınca yok.

Örnek bir Version.class
package com.blogspot.mustafatan.testproject;
public class Version {
private static String version = "TestProject_2.1.2_15022006";
public static String getVersion() {
return version;
}
}

b) Otomatik olarak Apache Ant 'ı kullanarak hem uygulamanızı derleyip, hem de bu sırada sürüm numarası oluşturup derlediğiniz paket içerisine yerleştirebilirsiniz. Bu sayede kullanıcı hatalarından kaynaklanabilecek versiyonlama hatalarını engelleyebilir, hem de çok daha detaylı bilgi içeren bir sürüm numarası üretebilirsiniz. Bu işlem için Ant'ın Copy, Javac, BuildNumber, Replace gibi meşhur task'larından bol bol yararlanabilirsiniz.
Örnek Ant Task'ları:

<buildnumber file="buildNumbers/TestProject.number"/>

<tstamp>
<format property="BUILD_TIME" pattern="ddMMyyyy-HHmm" locale="en"/>
</tstamp>

<property name="build.version" value="TestProject_${release.number}_${BUILD_TIME}_Development_${build.number}"/>

Sürüm numaralarını bir şekilde oluşturduğumuza göre geriye bir tek bu numaranın son kullanıcının kolayca ulaşabileceği veya görebileceği şekilde ekranlarda gösterilmesi kalıyor. Örneğin Internet Explorer menüsünde Help -> About Internet Explorer sekmesine tıkladığınızda Browser' ınızın hangi versiyonda olduğunu rahatlıkla görebilirsiniz. Benzer şekilde siz de uygulamanızın sürüm numarasını, ana menüde kullanıcılarınızın rahatça görebileceği bir yerde gösterebilirsiniz.



Etiketler: , ,

4 Yorum:

Blogger Lance dedi ki...

yazidaki linklerde sorun var sanirim. bilginize.

11:06 ÖÖ  
Blogger Mustafa Tan dedi ki...

Uyarınız için teşekkürler. Gerekli düzeltmeleri yaptım.

1:54 ÖS  
Anonymous Adsız dedi ki...

mustafa, güzel bilgiler, tebrikler. nazlı

4:52 ÖS  
Anonymous Yusuf OZKAN dedi ki...

bu güzel bilgiler için teşekkürler.

4:59 ÖS  

Yorum Gönder

Kaydol: Kayıt Yorumları [Atom]

<< Ana Sayfa