Jenkins ile Proje Derlemek

  

       Evden Buluta serisinin bu bölümünde Jenkins ile build ve deploy işlemlerine başlamadan önce yeni bir proje oluşturup Github'a gizli bir proje (private repository) olarak göndereceğiz. Ardından projemize jenkins üzerinden erişebilmemiz için ssh key'i oluşturup github ve jenkins üzerinden tanımlamalarını yapacağız. Gerekli bağlantıları sağladıktan sonra da jenkins'i çalıştırdığımız Ubuntu sunucu üzerine projeyi derleyip, deploy yapabilmemiz için .Net Core SDK'sını kuracağız. Son olarak da Jenkins'e buildimizi alıp bu makaleyi sonlandıracağız. 

       Eğer sizin elinizde mevcut bir API varsa doğrudan Jenkins üzerinden Github'a erişimi sağladığımız kısıma geçebilirsiniz. Ayrıca farklı bir dilde veya framework'te geliştirmiş olduğunuz bir proje varsa Jenkins'i kurduğunuz ortama ilgili SDK'ları kurduktan sonra benzer işlemleri uygulayabilirsiniz.

Ön Hazırlık

       Geliştirdiğimiz projeleri hızlı bir şekilde deploy yapmak, yazdığımız testleri kontrol etmek ve kod kalitesini sağlamak adına yaygın kullanılan CI/CD aralarından biri olan Jenkins'in kurulumuna geçmeden önce CI/CD nedir diye merak ediyorsanız bu makaleyi okuyabilirsiniz.

       Kurulum yapacağınız Ubuntu sunucu yoksa veya test için yeni bir sunucu oluşturacaksanız bu makaledeki adımları takip edebilirsiniz.

       Jenkins'i henüz kurmadıysanız da bu makaledeki adımları uygulayarak kurabilirsiniz.

 

.Net Core API Oluşturmak

       Yapacağımız basit bir API, appsettings içerisinde yer alan versiyon değerini alıp kullanıcıya dönen bir endpoint içerecek. Bu sayede yaptığımız yeni değişikliklerin Jenkins ile build alınıp deploy edildiğini kolayca görmüş olacağız. Bunun için bilgisayarınıza güncel SDK'yı kurduğunuzdan emin olun. Makale yazıldığı tarihte en güncel sürüm .Net 5.0 kullanılmıştır.

 

       Proje türünü seçtikten sonra bir isim belirleyip aşağıdaki gibi "ASP.NET Core Empty" şablonunu da seçip ilerleyelim.

       Proje oluştuktan sonra ana dizine "Controllers" isminde bir klasör oluşturup, içerisine yeni bir API Controller ekleyelim. 

       Boş bir controller seçip isim olarak "VersionController.cs" verebiliriz.

       Aşağıdaki gibi boş bir API Controller'ının oluşmasını bekliyoruz. 

       Controller içerisine aşağıdaki gibi eklemeleri yapalım. Burada öncelikle bir constructor tanımlayıp appsettings'ten okuma yapacağımız IConfiguration'ı ekliyoruz. Ardından bir GET metodu oluşturup appsettings içerisinde tanımlayacağımız versiyon bilgisini dönüyoruz.

    [Route("api/[controller]")]
    [ApiController]
    public class VersionController : ControllerBase
    {
        public IConfiguration Configuration { get; }

        public VersionController(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        [HttpGet]
        public IActionResult GetVersion()
        {
            return Ok($"Api Version: {Configuration.GetSection("ApiVersion").Value}");
        }
    }

       Ardından appsettings.json içerisine girip versiyon değerini "ApiVersion" :  "1.1.0"  olarak aşağıdaki gibi ekliyoruz. Son halinin aşağıdaki gibi olmasını bekliyoruz.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ApiVersion" :  "1.1.0" 
}

       Oluşturduğumuz .Net projesinin bir API gibi davranabilmesi için Startup.cs içerisine de aşağıdaki eklemeleri yapmamız gerekmekte.

       Bunun için öncelikle "ConfigureServices" içerisine aşağıdaki kodu ekleyelim. Bu eklemeyi yaparak projenin "Controller" içeren class'larını tanımasını sağlarız. 

    public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
        }

       Ardından yine Startup.cs içerisinde "Configure" altında aşağıdaki kod bloğunu yenisiyle güncelleyelim.

       Eskisi:

 app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });

       Olması gereken:

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });

       Bu işlemi yaparak controller içerisine eklediğimiz metotların endpointleri üzerinden erişebilmemizi sağladık.

       Tüm bu işlemlerin ardından Startup.cs  dosyamızın son halinin aşağıdaki gibi olmasını bekliyoruz.

 public class Startup
    {
       public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

             app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }

 

       Şimdi deneme amacıyla projemizi çalıştırıp IIS üzerinden host ettiyseniz "http://localhost:58317/api/version", kestrel üzerinden host ettiyseniz de "http://localhost:5000/api/version" adresine gidip istek yapalım. Aşağıdaki gibi çalıştığını görebilirsiniz.

 

Projenin Github'a Gönderilmesi

       Öncelikle Github üzerinde bir hesabınız yoksa oluşturmanız gerekmekte. Eğer farklı bir IDE veya komut satırı üzerinden ilerlemek isterseniz kendiniz projeyi Github'a push'layabilirsiniz. Visual Studio üzerinden yapmak istiyorsanız aşağıdaki adımları takip edebilirsiniz.

       "Git Changes" sekmesini açıp "Create Git Repository" diyelim.

       Açılan ekranda mevcut github hesabınızı ekleyip aşağıdaki gibi "Private" kutusunu işaretleyip "Create and Push" diyebilirsiniz.

       Oluşturduğumuz proje Github hesabımız altında da yer alacaktır.

 

Kamu Spotu :) 

       Eğer diğer yazılımcılar tarafından da erişilmesinde bir sakınca görmüyorsanız, open-source topluluğuna katkıda bulunmak ve projenizin diğer yazılımcılar tarafından da desteklenmesi için Public olarak paylaşabilirsiniz. Private olarak oluşturduğunuz projeler sadece siz ve projeye eklediğiniz kullanıcılar tarafından görülebilir ve geliştirilebilir. 

 

 

       Public bir projeniz varsa aşağıdaki adımı geçip doğrudan paket kurulumları başlığından devam edebilirsiniz.

 

Jenkins'e Github Private Repository Eklemek

       Eğer Github üzerinde Public bir projeniz varsa doğrudan linki eklemek yeterli oluyor fakat projeniz gizli bir projeyse bunun için Jenkins sunucumuz üzerinden bağlanırken kullanacağız key'i Github üzerinde tanımlayıp yetkilendirmemiz gerekiyor.

       Öncelike Jenkins panelimize girip sol menüde üstte yer alan "New Item" 'ı seçtikten sonra açılan ekranda build setimize bir isim verelim ve "Freestyle project"'i seçelim.

 

Açılan ekranda "Source Code Management" alanıda "Git" seçeneğini seçip Github'da yer alan projenizin SSH linkini yapıştırın.

       Projemiz gizli olduğu için Jenkins erişemediğine dair hata verdi. Eğer herkese açık(public) bir proje ise bu alanda hata almadan devam edebilirsiniz. 

       Erişimi sağlamak için "Add" butonu ile çıkan ilgili yere tıklayalım.

 

       Açılan sekmeyi kenarda tutalım ve bize lazım olan key dosyasını oluşturalım. Bunun için Jenkins'i kurduğumuz sunucuya SSH ile bağlanalım ve aşağıdaki komutu çalıştıralım.

ssh-keygen

       Komutu yazdıktan sonra bizden istediği alanlarda bir değişiklik yapmayıp enter tuşuna basarak ilerleyelim. ssh keyimiz oluştuğunda aşağıdaki gibi bir çıktı almanız gerekmekte.

       Bu işlemin ardından ".ssh" dizininde bizim için önemli iki key oluşacaktır. Bunlardan "id_rsa.pub" kurulan haberleşmede encryption amaçlı kullanılan public key'i içerir, "id_rsa" içe alınan cevabın decryption'ı için sunucu içerisinde private olarak kullanılır.

       Şimdi oluşan key'lerden ilk adım olarak Jenkins içerisine tanımlayacağımız private key dosyasına gidelim.

sudo cat .ssh/id_rsa

       Ekranda gözüken key'de üst yorum satırından alt yorum satırına kadar seçip kopyalayalım.

       Kopyaladığımız key'i jenkins'te açık bıraktığımız ekrana ilgili alanları aşağıdaki gibi seçip girebilirsiniz.

       Burada ID alanına gireceğiniz isim bu key'i temsil eder ve seçim yaparken kullanırsın��z.

       Description alanı, ek açıklama yazmak isterseniz girebilirsiniz.

       Username alanına ise Github kullanıcı adınız olarak girmelisiniz.

       Son olarak kopyaladığınız key'i Private Key alanında "enter directly" kutusunu işaretleyip "add" butonuna tıkladıktan sonra yapıştırıp kaydedin.

 

 

       Keylerle yapacağımız ikinci adım olarak da tekrar sunucu üzerinden aşağıdaki komutu çalıştıralım.

 sudo cat .ssh/id_rsa.pub

       Konsol ekranında gözüken key'in tamamını kopyalayıp github üzerinden projenin içerisinde "Settings" sekmesine gelip "Deploy Keys" sekmesine gelelim ve sağ üstte bulunan "Add deploy key" butonuna tıklayalım.

       Bir isim verip, key'imizi yapıştıralım. Jenkins üzerinde bir committe bulunmayacağımız için write yetkisi vermemize bu proje özelinde gerek yok. Projeyi build yapabilmemiz için read yetkisi yeterli bizim için. O yüzden o alanda bir işaretleme yapmıyoruz ve "Add key" ile kaydedip devam edelim.

       Butona tıkladıktan sonra github bizden şifremizi girmemizi isteyecektir. Ardından aşağıdaki gibi key'imizi görebiliriz. 

       Jenkins ekranına geri dönüp Credentials altında oluşturduğumuz key'i seçtiğimizde herhangi bir hatayla karşılaşmadığımızı göreceksiniz. Eğer halen hata gözüküyor ise Credentials'ı "-none-" yapıp tekrar hesabınızı seçin.

       Projemizi bağladıktan bazı tanımlamalar da yapmamız gerekmekte. 

       Öncelikle Jenkins'in hangi branch üzerinden build alacağını aşağıdaki alandan belirliyoruz. Biz master branch'ini kullanacağımız için bu şekilde bırakıyoruz.

 

       Alınan buildlerin sunucu üzerinde birikmemesi için aşağıdaki kutuyu da işaretleyip her build alınırken mevcut dosyaların silinmesini sağlayalım.

 

       Build adımında ise aşağıdaki gibi "Add build step" altında "Execute shell" seçip aşağıdaki komutu ekleyelim.

 

dotnet build {proje dosyanız}.sln -c Release  -o {deploy dosyalarını çıkartacağınız dizin}

       Örneğin ben build dosyalarını doğrudan ana dizin altına çıkartmak için aşağıdaki komutu ekledim.

dotnet build JenkinsDemoApi.sln -c Release  -o /home/ubuntu/jenkins-demo-api

 

       Ardından işlemlerimizi kaydedelim.

 

Jenkins Build için .Net SDK kurulması

       Projemizi sunucu üzerinde derleyebilmemiz için gerekli SDK'nın sunucu üzerinde de yüklü olması gerekmektedir. Sunucu üzerinde .net sdk olup olmadığını kontrol etmek için aşağıdaki komutu çalıştırabilirsiniz.

dotnet --version

       Yukarıdaki gibi bir ekranla karşılaştırysanız sunucunuz üzerinde .net sdk kurulumu yapmak için önce aşağıdaki komutu çalıştırın:

wget https://packages.microsoft.com/config/ubuntu/20.10/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb

       Ardından da aşağıdaki komutu çalıştırın:

sudo apt-get update; \
  sudo apt-get install -y apt-transport-https && \
  sudo apt-get update && \
  sudo apt-get install -y dotnet-sdk-5.0

       İşlem tamamlandıktan sonra tekrardan kontrol için kullandığımız "dotnet --version" komutu ile kurulum sonucu yüklenen versiyonu görebilirsiniz.

        Dikkat: Zaman zaman yaptığım kurulumlarda "Unable to locate package dotnet-sdk-x"  benzeri bir hatayla karşılaşılabiliyor. Bunun için Microsoft tarafından tavsiye edilen buradaki kurulumu uygulamanız sorunu çözecektir.

 

       SDK kurulumumuz da tamalandığına göre Jenkins üzerinden projemizi build alacak tanımı çalıştıralım. Bunun için açılan ekranda sol menüde yer alan "Build Now"'a tıklamanız yeterlidir. Tıkladıktan sonra aşağıda yer alan "Build History" alanında işlemin başladığını göreceksiniz.

 

       Jenkins üzerinde başlattığınız işlemlemin detayına gitmek için "Build Histoy" altında yer alan işlemlere tıklayabilir veya doğrudan orta ekranda yer alan hızlı yönlendirmelere tıklayabilirsiniz. Ayrıca buildlerin yanındaki kutulardaki renklendirmelerde başarılıysa mavi, hata aldıysa kırmızı olduğunu göreceksiniz.

 

       Başlattığımız işlemin durumunu görmek için detaya girip sol menüdeki  "Console Output"'a tıklayın.

 

 

Jenkins Path Access Denied Hatası

       Eğer siz de benim gibi dosyaları ana dizinde bir klasöre çıkartmak istediyseniz aşağıdaki hatayla karşılaşacaksınız. Jenkins sunucu üzerinde kendi kullanıcısı ile çalıştığı için bazı yetkileri önceden tanımlamamız gerekiyor. 

       Bunun için aşağıdaki komutlarla sunucu üzerinde klasörü oluşturup Jenkins kullanıcı için erişim ve işlem izni vermemiz gerekiyor.  "jenkins-demo-api" benim çıkartmak istediğim klasör için komuta onu ekledim. Siz farklı bir klasör veya dizin kullandıysanız kendinize göre değiştirin.

sudo mkdir jenkins-demo-api
sudo chown -R jenkins:root jenkins-demo-api/


       Komutları çalıştırdıktan sonra Jenkins üzerinden tekrar "Build Now" ile tetikliyoruz. Yeni build'in detayına gidip loglara baktığımızda projenin başarıyla build alındığını görüyoruz.

       Sunucu üzerinden de ilgili klasöre baktığımızda build dosyalarını görebilirsiniz.

 

       Yeni bir proje oluşturup Jenkins ile sunucuda build aldığımız bu makalenin şimdilik sonuna geldik. Bir sonraki makalede nasıl deploy alacağımızı ve API'ı yayına alacağınızı anlatacağım.

 

      Evden Buluta - DevOps Serisindeki bir sonraki makaleye geçmek için tıklayın.

       Evden Buluta - DevOps Serisi içerisinde yer alan diğer yazılara ulaşmak için tıklayın.

 

 

 

 

 

Add comment