Continues Integration etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Continues Integration etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

15 Nisan 2014 Salı

Apache Tomcat & Jenkins

CI server olarak kullanacağımızı belirttiğimiz Jenkins aracı java dilinde geliştirilmiş ve sitesinde hem kurulum şeklinde bir paketle hem de war (Web Archive) dosyası olarak yayınlanmaktadır. Biz sürecin tamamına hakim olmak her istediğimizi tune edebilmek istiyoruz bu sebeple war paketi ile çalışacağız. Web arşivi ile çalışacaksak bu web arşivini deploy edebileceğimiz bir sunucu yazılıma ihtiyacımız bulunmaktadır. Burada en kısa yoldan bize çözüm sunacak Apache Tomcat i tercih ediyoruz.

Ön gereksinim olarak Java run time ihtiyacımız olacak onu da bu linkten indirebilirsiniz. Linkte server jre paketleri bulunmakta. Bu paket hem jre içermekte, hem de Java uygulamalarınızı takip edebileceğiniz monitör uygulamaları gibi bazı araçları da içermektedir. En önemlisi production ortamlardaki can sıkıcı Java update özelliği gelmiyor bu pakette. 

1. Java Run Time Kurulumu:
  1. Daha önce indirme linkini verdiğimiz dosyanın uzantısı tar.gz'dir. Winrar ile açıldığında direk olarak karşınıza jdk1.8.0 dizini çıkacaktır. 7.zip ile açtığınızda içerisinde .tar uzantılı bir dosya görünecektir, onu da 7zip içerisinde iken çift tıklarsanız jdk1.8.0 dizinini göreceksiniz.
  2. Bu dizini CI_Working_Engine klasörü altına aynen koyalım.
  3. Ardından Windows'da Control Panel --> System and security --> System --> Advanced System Settings altında Environment Variables dialogunda yeni bir sistem değişkeni tanımlayalım. Girilecek değerleri aşağıdaki şekildeki gibi uygun olacak şekilde girelim.
  4. Tamam deyip çıktığımızda artık Java uygulamalarının Java kurulumu nerede diye aradığı JAVA_HOME değişkeni set edilmiş olacak.
Java uygulamalarımız için Java kurulum dizinini bir sistem değişkeniyle belirtiyoruz
Notlar:
  1. Aşağıdaki komut satırı işlemlerini admin hakları ile yapmanız gerekmektedir. Servis kurma kaldırma gibi işlemler nedeni ile bu şart. Bu sebeple komut satırını "Yönetici olarak aç (Run as admin)" seçeneği ile açmalısınız. Aksi takdirde ya işlemleriniz olmayacak ya da oldu gibi görünen işlemler hata vererek başınızı ağartacaktır.
  2. Kurulumlara başlamadan önce rahatça log ve konfigürasyon dosyalarını incelemek-karşılaştırmak için Notepad++ ve ardından compare plug-in ini kurmanız sizi rahatlatacak ve de size zaman kazandıracaktır. Zira bu tip text dosyaları ile artık çokça haşir neşir olacaksınız. Plug-in dosyasını manuel kuracaksanız sadece dll dosyasını Notepad++ kurulum dizinindeki plugins klasörüne atmanız yeterli. Build makineniz internete açıksa zaten online olarak notepad++ plugin manager menüsünden istediğiniz eklentiyi kurabilirsiniz.

2. Apache Tomcat Kurulumu:
  1. Adresinden 64 bit Windows zip olan sürümü indirelim.
  2. CI sunucusu olarak belirlediğiniz bilgisayarda bu dizini açalım. Mesela bu dizin E altında CI_Working _Engine dizini olsun. (Anlaşılabilir olsun diye kendi dizin yapımı örnek olarak alacağım)
  3. Komut satırında E:\CI_Working_Engine\apache-tomcat-8.0.5\bin\ adresinde iken startup.bat dosyasını çalıştırdığımızda JAVA_HOME veya JRE_HOME adreslerine sahip olmadığımızı belirten bir hata alabiliriz. Java run-time kurulumunu bir önceki adımda yapmıştık.
  4. Java kurulumundan sonra tekrar denediğimizde (yeni komut satırı penceresi gerekli) aşağıdaki ilk pencerenin Tomcat i çağırıp ikinci bir komut satırında çalıştırdığı görülür. (Çalıştığını görmek için, ilerleyen bölümlerde bulunan chrome ekranındaki gibi, tarayıcı ile de 8080 port kontrolü yapılabilir, tabii sağ tarafta log bilgileri ile birlikte görünen Tomcat konsol sürekli açık olmak zorunda)
Tomcat uygulama sunucumuz konsoldan da olsa çalışıyor
Pratik Notlar:
Gerçekten bir CI sistem kuruyor isek yapmışken düzgün yapmalıyız. Öyleyse Tomcat bu şekilde elle manuel değil, Windows servisi olarak otomatik ayağa kalkabilmelidir. Tomcat penceresinde iken ctrl + c yapıp sunucu uygulamamızı kapatalım ve yine komut satırında bin klasörünün altındaki "service.bat" şeklindeki bat dosyasını aşağıdaki resimdeki gibi install seçeneği ile çalıştıralım.
Tomcat uygulama sunucusunu servis olarak kurma

Anlayacağınız üzere Tomcat i servis haline getiren komutlar service.bat dosyası içerisinde saklı. Biraz vakit ayırıp kurcalarsanız servis adı, install, uninstall gibi çalıştırma şekillerini dosya içerisinde bulabilirsiniz. Yukarıdaki işlemin ardından Windows servis listesini kontrol ederseniz ("services.msc"), görünür ismi "Apache Tomcat 8 Tomcat 8", servis adı "Tomcat 8" olan servisimizi görebilirsiniz.

İp ucu 1: Windows'da bir servis silmek için komut satırında "Sc delete servis_adı" komutunu kullanabilirsiniz. Servis adını da, Windows'da ara menüsüne "services.msc" komutunu yazarak çalıştırıp, ilgili servise çift tıkladığınızda erişebilirsiniz.

İp ucu 2: Yeri burası diye söylemiş olalım. Oluşturduğunuz bu Tomcat 8 servis altında deploy edeceğimiz herhangi bir uygulama (Biz jenkins deploy edeceğiz) network üzerinde her hangi bir makineye erişmesi gerekirse, bir yere bir dosya yazması gerekirse otantikasyon olarak, servisi çalıştıran login bilgilerine göre otantikasyon yapacaktır. Yani bir domainde iseniz ve bir kullanıcının bu yazacağınız adres veya erişeceğiniz makineye erişim yetkisi varsa, erişimi sağlamak adına servisi bu kişinin login bilgileri ile başlatmanız gerekir. Aksi takdirde servis çalışır fakat Tomcat log dosyalarında "Access Denied", "No permission" vs. yetki hataları aldığınızı görürsünüz. Servisi erişime yetkili kılmak için "services.msc" açıldıktan sonra "Apache Tomcat 8 Tomcat 8" servisimize çift tıklayın ve log on sekmesindeki "This account" kısmına yetkili kişinin (domain kullanıcıları da dahil) giriş bilgilerini girin. Varsayılan olarak lokal makinenin sistem hesabı çalışıyor, fark etmişsinizdir. Bu anlattığım erişim bilgisi şu an için gereksiz gibi dursa da; ileri de CI sisteminiz ayağa kalktıkça bu gereksinim karşınıza eninde sonunda çıkacaktır. Zira tüm kaynaklarınızın build makinesinde lokal olarak bulunabileceğini sanmıyorum. Mesela kendi örneğimizde, Jenkins ağda farklı bir yerlere erişmeye kalktığında (kuracağınız farklı eklentiler bunu yapmak isteyebilir) eğer Tomcat servisimiz yetkisiz bir kişi ile başlatılmışsa hata almamız kaçınılmazdır. Erişim mevzusu ile alakalı Jenkins için yazacağınız ANT scriptleri için de "SSH" bağlantı kurma konusu var ileride yeri gelince onu da anlatacağım. Kısacası SSH size iki makine arasında güvenli ve yetkilendirilmiş bir bağlantı kurmanıza yarar, böylece SSH destekli script kodlarınız ile farklı makinelerde yetki gerektiren işlemleri yapabilirsiniz. Diğer bir husus da servisi çift tıkladığınızda "Startup-type" olarak görünen kısmı da otomatiğe çekerseniz build makineniz kapanıp açılsa dahi servis otomatik çalışacaktır ki zaten böyle olmasını istiyoruz. Bunlar pratikte gerçek bir CI sistem için ufak ama karşınıza çıkacak önemli noktalardı.

Servisler penceresinde iken sağ tuş start dediğinizde Tomcat servisimiz başlayacaktır. Kontrol için bir web tarayıcı ile 8080 (Tomcat default port) portunu kontrol edebilirsiniz.

Tomcat uygulama sunucumuz çalışıyor hem de Windows servisi olarak !


Tomcat çalışırken oluşan log dosyalarını Tomcat çalışma dizinindeki logs klasöründe bulabilirsiniz. Buradaki "Catalina_tarih.log" dosyasını inceleyebilirsiniz, genelde incelenen temel log dosyası kendileri oluyor.

Tomcat Yetkilendirme Mekanizmasını Kurma
Gerçekten bir CI sistemi ayağa kaldırmayı hedeflediğimize göre uygulama sunucumuzun yetkilendirme mekanizmasını kurmamız gerekli. Tomcat varsayılan olarak yönetim ekranlarına erişimi kapalı olarak gelmektedir. Örnek vermek gerekirse yukarıda chrome ile görüntülenen Tomcat ana ekranında sağ tarafta bulunan Manager App butonunu tıkladığınızda sizden login bilgisi isteyecektir. Fakat ne yaparsanız yapın ne girerseniz girin kaçınılmaz olarak aşağıdaki ekran ile karşılaşacaksınız.

Tomcat yetkilendirme mekanizması henüz kurulmamış
Bu ekran bize aslında ilk defa kurulum yapanların Tomcat'de credential bilgilerini nasıl konfigüre edeceğimizi yazılı olarak belirtiyor. Biz de aynen yazılanlar gibi Tomcat çalıştırma dizininde conf klasörü altında bulunan "tomcat-users.xml" dosyasını Notepad++ ile açalım ve eklemelere başlayalım. Tüm yorum satırları aynen kalsın, tomcat-users etiketleri arasına aşağıdaki aşağıdaki eklemeleri yapalım:

<role rolename="manager-gui"/>
<user username="admin" password="admin" roles="manager-gui"/>

Bu şekilde bir kullanıcı adı ve şifre belirlemiş olduk ve bu kullanıcıya Tomcat için tanımlı rollerden birini atamış olduk. İstediğiniz kullanıcı adı ve şifreyi belirlemek size kalmış.

Artık Manager App butonuna tıkladığımızda karşımıza çıkan login ekranında admin / admin bilgilerini girdiğimizde karşımıza aşağıdaki ekran çıkacaktır. Bu da Tomcat'de yetkilendirme kısmını temel de olsa çözdük demektir.

Tomcat Manager App ekranı







3. Jenkins Kurulumu:
  1. Adresinden Latest and greatest yazan war paketi versiyonu indirelim. (Şu anki güncel versiyon 1558)
  2. Tomcat servsimizi durdurup, bu war dosyasını Tomcat klasöründe bulunan webapps klasörüne koyalım, Tomcat servisimizi başlatalım hepsi bu :)
  3. Web tarayıcımızda localhost:8080/jenkins adresine bakarak Jenkins aracımızın çalıştığını görelim.
Jenkins ana ekranı

Bir sonraki yazımızda Jenkins sürekli entegrasyon sunucumuzu inceleyip konfigüre edeceğiz.





3 Nisan 2014 Perşembe

Sürekli Entegrasyon


CI sistemlerde işleyiş mantığı,
Tıkır tıkır çalışmak
Orta ve büyük yazılım projelerinin kaçınılmaz ögelerinden biridir sürekli entegrasyon. Ayrıca agile süreçler içerisinde de olmazsa olmaz bir kavram olarak göze çarpmaktadır. Bu yazı dizisinde Sürekli entegrasyon detaylarına, teorisine çok derinlemesine girmeyeceğim daha çok neden gerekli olduğunu ortaya koyup pratik olarak nasıl hayata geçirebiliriz gibi konuları ele almayı düşünüyorum. Şimdiye kadar nette bulduğum bilgileri sizinle paylaşayım ki vakit kazanalım: Oğuz Dağ kendi bloğunda iki yazı dizisi halinde (Bir ve iki) konuyu ele almış. Özcan Acar Bey zamanında sitesinde yeterince anlatmış öyle ki kitap bile hazırlamış bunun için biraz eskimiş ama olsun temeller aynı. Kodcu.com'dan Rahman Usta'nın da bu videosu diğer güzel bir kaynak. Güncel bir kaynak olarak Berat Doğan'ın bloğundan bu yazı da enterasan. Böyle online bir hizmeti yeni görüyorum. Bu da Cem Güler'in görüşlerini içeren bir yazı. İşin iyice temellerine ineceğim derseniz Martin Fowler ile sizi baş başa bırakabilirim.

Temel kavramları hemen bu sayfada anlayabilmek adına acm-software den bir alıntı yapalım, güzel özetlemişler:
"Continuous Integration (Sürekli Entegrasyon), bir yazılım takımının ürettiği kodun sürekli ve sorunsuz olarak sisteme entegre edilmesini amaçlayan bir sistemdir. Bu entegrasyon süreci, çeşitli araçlar ile otomatik hale getirilmekte ve belirlenen sürelerde çeşitli scriptler ve işlemler çalıştırılarak kodun sürüme uygunluğu sürekli olarak test edilmektedir. Böylece entegrasyon hataları mümkün olan en kısa sürede bulanabilmektedir. Ayrıca, repository de bulunan kodların belirli aralıklarla test senaryolarının koşturulması ile sistem tutarlılığı sağlanmakta, geliştirilen deployment otomasyonu ile deployment süreçlerinde, insan faktöründen kaynaklanabilecek hatalar en aza indirgenmektedir.
Sürekli Entegrasyonun bazı yararları şu şekilde de sıralanabilir: 
  • Hatalar hızlı bir şekilde bulunur ve çözüm süreci başlar, 
  • Yazılım ürününün durumunun metriklerle ölçülmesi kolaylaşır, 
  • Varsayımlar üzerinden değil, somut yazılım üzerinden test yapılması sağlanır,
  • Kişilerce tekrarlanmak zorunda olan süreçleri kısaltır ve otomatik hale getirir, 
  • Her an deploy edilebilen yazılım çıkarılabilinmesine olanak verir, 
  • Projelerde saydamlık artar, 
  • Yazılımcılara ve ürüne güven aşılanmış olur."
Bir diğer alıntıyı da prime teknolojinin bu sayfasından yapalım:
"Sürekli entegrasyon ekip üyelerinin birbirlerinin ayaklarına basmamaları için kullanılır. Projelerde fark edilmesi ve düzeltilmesi en zahmetli problemler entegrasyon problemleridir. Sürekli entegrasyon sunucusu ekibin yaptığı kod değişikliklerini versiyon kontrol sunucusu (örn Subversion) vasıtasıyla izler. Herhangi bir değişikliği gördüğünde entegrasyon kurulumunu başlatır. Bu kurulum projenin özelliklerine göre şekillenir fakat basitçe tüm kodlar derlenir, testler çalıştırılır ve sonuçlar yayınlanır. Eğer bir hata varsa kurulum kırılır. Bu durumda ekibin önceliği entegrasyon problemini çözmektir. Kurulumun kırılması üretim hattında problemin ortaya çıkması gibidir, şalter indirilir ve bozukluk tamir edilir ve üretim hattı devam eder. Kurulum kırılması ekibin verimliliğini negatif etkiler. Geliştiriciler bunu önlemek için yaptıkları değişikleri versiyon kontrole eklemeden önce son değişikleri alırlar, yerel bir kurulum yapıp sonuç başarılı ise kendi değişikliklerini versiyon kontrole eklerler. Kurulumlar tamamen otomatiktir ve kurulum süresinin 10 dk nın altında olmasına özen gösterilir. Büyük projelerde kurulumlar sürekli, gecelik gibi aşamalara bölünür. Sürekli entegrasyon kodların hatasız, her an kullanıma hazır tutulmasını mümkün kılar. Bir noktalı virgül dahi değiştiğinde kapsamlı testler değişikliğin etkilerini inceler ve problemler çıkar çıkmaz ekip tarafından düzeltilir. Sürekli entegrasyon ‘Benim makinemde çalışıyordu burada niye çalışmıyor’ problemini çözer."
Son bir alıntıyı da ekşi sözlükte gördüğüm whisky adlı kullanıcıdan yapalım:
"Yazılım geliştirirken geliştirmenin her aşamasında projeyi çalışabilir halde tutmak için geliştirilmiş disiplindir. örneğin her commit sonrası unit test, 4 saatte bir integration test, gecelik olarak functional testler bir ci server üzerinde çalıştırılır. Bu build lerden herhangi birisini bozan işini gücünü bırakır ilgili sorunu fixler, fixlemezse product owner developerı bi güzel fixler. Bu şekilde saldım çayıra mevlam kayıra metodolojisinden uzak durulur."
Kendi cümlelerimle özetlemek gerekirse, aşağıdakilerin olmasını istiyorsanız CI sistem kurmanız gerekmekte:
  • Entegrasyon problemlerini minimize etmek, 
  • Sürekli olarak build edilebilir, güncellenen, sürümlendirmesi yapılan kodlarınızı tutmak,
  • Geliştirdiğiniz yazılım ürününü sürekli çalışabilir halde tutmak,
  • Düzenli olarak birim testleri, kod gözden geçirmeleri, kodlama standartlarını, bug tespitini yapmak,
  • Projenizin gidişatını görsel olarak raporlamak, istatistik almak,
  • Tüm bu işlemler sırasında geliştiriciler arasında projenin gidişatı ile ilgili otomatik haberleşmeyi (sms, mail) sağlamak, ("Gönderdiğin kod güncellemeleri projenin şurasını bozdu, bir an önce şu şu yerleri kontrol edip düzeltilmesini sağlar mısın?" tarzında mesajlar)
  • Ekibe projenin her an ilerlediğini ve entegrasyon hatası olursa sistemin kendisini otomatik uyaracağını, kendisine işin doğrusunu yapmakta katkısı olduğunu ve tüm ekibin bu şekilde çalıştığını hissettirmek, böylece ona güven vermek,
  • Çıkaracağınız ürünü yazılım mühendisliği açısından kaliteli kılmak, dolayısı ile ürünü kaliteli kılmak,
  • ... ve belki de şu an aklıma gelmeyen bir çok fayda...
Aslında bu saydıklarım, herhangi bir entegrasyon sürecinde olması gereken adımlar. Sürekli entegrasyon deyince bu adımların tamamının bir kere ayarlanması ondan sonra sadece küçük müdahaleler ile, saat gibi tıkır tıkır her şeyin vaktinde otomatik olarak araçlar ile çalıştırılması ve seyredilmesi akla gelmelidir. Sürecin neredeyse tamamını araçlar işletir, CI yöneticisine sadece sistemdeki bir hata veya yeni bir özellik eklenmesi durumunda ihtiyaç duyulur. (Burada da aslında harcanacak vakit çok azımsanacak bir vakit değil ama ortaya çıkan iş açısından feda olsun deneceğinden eminim)
Eski yaklaşımlar yukarıdaki adımların tamamının belirli dönemlerle entegre edilmesi fikrine dayanmaktadır. Yeni yaklaşımımız ise bu sürecin her saat veya her gün sürekli tekrar edilmesi şeklindedir ki artık orta boy ve üzeri yazılım projelerinde bazı riskleri minimize etme adına bu vazgeçilemez bir hal almıştır.
Sürekli Entegrasyon Süreci
Olayın anlaşılması için bir de şekil üzerinden bakalım duruma. Yukarıda bir java web projesi tecrübesinden hareketle sürekli entegrasyon sürecini anlatan bir şekil çizmeye çalıştım. Diğer tipteki projeler içinde örnek kabul edilebilir. Görüldüğü üzere süreç geliştiriciler ile başlamakta. Geliştiricinin yapmış olduğu bir commit çelik kasa gibi görünen repoya gelmekte (Svn). Sürekli entegrasyon sunucumuz (kısaca SES diyelim, yani Jenkin aracımız) ise svn deki güncel kodları alıp, derleyip, birim testlerini yapıp, kod kalitesinden geçirip, tag leyip vs (bir çok işlem yaptırılabilir), oluşan derlenmiş projemizi web portallerine gönderir (Deploy eder). Burada bir kaç konuyu açalım. SES her commit geldiğinde de bu işi yapabilir, her gün belli saatlerde de yapabilir, bir başka projeyi çalıştırıp bitirdikten sonra otomatik tetiklenerek de yapabilir. Bu gibi daha bir çok konfigürasyon seçeneğine sahiptir. Bu takvimleme sıklığı, SES yöneticisinin tercihlerine bağlı bir durumdur. Tabii SES yöneticisi de keyfine göre değil, proje ihtiyaçlarına uygun bir konfigürasyon belirlemeye çalışacaktır. Projelerde genel kabul en azından iki ayrı sürüm çıkarmaktır.
  • Bir geliştirici sürümü çıkarılır ki bu her commit de veya 2 saatte bir gibi sıklıkla çalışan bir Jenkins job u demektir. Bu sürüm daha çok geliştirici hatasını bir an önce görsün diye çıkarılır. 
  • Bir de test sürümü çıkartılır ki bu 3 günlük veya haftalık olabilir. Bu proje ekibinin geliştirme hızına, test ekibinin büyüklüğüne vs bağlıdır.
Eğer sistemde veri tabanı kullanılıyorsa test ve geliştirici sürümleri farklı veri tabanlarına bağlı, değiştirilebilir ortak bir dosya havuzu kullanılıyorsa yine test ve geliştirici sürümleri farklı havuzları kullanmalıdır. İki sürümün ortak olabileceği örnek bir unsur, mesela Ldap otantikasyonu gibi sürümlerin birbirlerine müdahale etmeyeceği bağımsız testlerinin yapılabileceği unsurlar olmalıdır. Aksi takdirde mesela veri tabanı ortak olsa, tutulan bir değerin geliştirici sürüm tarafında silinmesi, değiştirilmesi, test sürümünü test eden test ekibini çalışamaz hale getirecektir.
Sistemde hata olduğu an SES tarafından ilgili geliştiriciye (Geçerli build'deki commit sahipleri) anında mail atılır ve patlamayla (yukarıdaki alıntılarda daha formal olsun diye kırılma olarak yazılmış) ilgili bilgi verilebilir. Neyin patlama sebebi olacağı da yine SES yöneticisine kalmıştır. Build hatası zaten varsayılan patlama sebebi sayılacaktır. Ama mesela kodların yedeğinin bir başka bilgisayara atılması bir alt iş olabilir (Scriptler ile basitçe yapılabilir) ve attığınız makineye erişim sıkıntısı veya diskin dolu olması gibi bir hatayı dahi patlama sebebi sayıp bu durumda sürümün kırıldığını kabul edebilirsiniz. Tabii bu durumda gelecek mail geliştiriciden ziyade SES yöneticisini ilgilendirecektir.

Evet CI anlamak ve biraz olsun sindirmek için bu kadar ön bilgi yeterli, gelelim temel amacımıza.
Bu yazı dizisinde, gerekli araştırmayı yapmış, "iyi ama nereden başlayacağız bu işe" diyenler için pratik bilgilerle birlikte bir yol haritası sunmaya çalışacağım, faydalı olmasını diliyorum...

İlk iş olarak, kullanacağımız araçlardan biraz bahsedelim.
1. Apache Tomcat (Jenkins aracımızı deploy etme amacıyla)
2. Jenkins (Eski adı ile Hudson ki hala farklı adlarla (Eclipse Hudson) devam ettirilmeye çalışılmakta)
3. Ant (Jenkins'te koşacak build scriptlerimiz için)
4. Sonar (Kod gözden geçirme, kod kalitesi ve çeşitli programlama metriklerin hesaplanması için)

"Her şey güzel de bu kadar yazı okuduk, araçları da gördük ama projemizde kullandığımız programlama diline dair bir şey görmedik henüz" der gibisiniz  muhtemelen :) Kullanacağımız tüm araçlar neredeyse dilden bağımsız (adını duymadığım bazı diller var, sonar aracının onlara herhangi bir plug-in i olmayabilir, onun için neredeyse diyorum) bir şekilde size sürekli entegrasyon ortamını sağlayacaklar emin olabilirsiniz. Ben Java ile sürekli entegrasyon süreci atlatmış biri olarak Java dan başlayacağım örneklerime, yeni projemde aynı işlemleri c++ için de oturtmam gerekecek, vakit olur da sıra gelirse c++ için de bu yazı dizisine devam etmeyi düşünüyorum. Baştan söyleyeyim bazı ufak tefek değişiklikler haricinde dil olayı çok fazla bir uğraş verdirmeyecektir diye düşünüyorum. Yalnız şöyle bir sonuç kaçınılmaz olacak, yukarıdaki araçlar Java-merkezli olduğundan Java projeleri için daha fazla plug-in e sahipler bunu baştan söylemek lazım. Dolayısı ile Java projelerinizde c++ projelerine göre daha çok plug-in, daha fazla esneklik, daha fazla görsellik vs. demek olacak bunu kabul etmek lazım.

Bir sonraki yazımızda Jenkins ve Hudson arasında kalanlar için "Jenkins mi Hudson mı ?" adlı bir yazı kaleme aldım, okuyabilirsiniz.