GitHub Actions ve JavaScript ile Dinamik README Dosyası Oluşturmak
Motivasyon
Pandemiyle birlikte evde daha fazla zaman geçirmeye başlayınca ayda en az iki yazı yazmayı şiar edinmiştim kendime. Zaman zaman aksattığım olsa da bir seneden fazladır ekseriyetle uydum buna.
Burada yazdığım blog yazılarının son on tanesini tugsanunlu.com’da, tamamını da GitHub’daki repoda listeliyorum. Önceleri problem olmuyordu fakat yazı yazma sıklığım artınca her yeni yazıdan sonra repo güncellemeye üşendim. O nedenle GitHub’daki profil README dosyama Blog Post Workflow ile buradaki son on yazıyı listeledim.
Blog Post Workflow, popüler blog platformlarını destekleyen bir GitHub aksiyonu. Oldukça basit bir kullanımı var. Neredeyse blog adresinizin URL’ini vermeniz yetiyor çalışması için. Sadece blog yazıları listelemek için gayet yeterli ve marifetli.
Ben bu yazıda en basit hâliyle Blog Post Workflow’un bu işi nasıl yaptığından, kaynaklardan aldığımız verilerle GitHub Actions ve JavaScript kullanarak nasıl dinamik README dosyaları oluşturabileceğimizden bahsedeceğim.
Veri Kaynağı
Blog Post Workflow’un yaptığını kendimiz yapalım. İlk olarak Medium profilindeki yazıları almak için bir kaynağa ihtiyacımız var. Medium, varsayılan olarak aşağıdaki adreste XML formatında bir RSS beslemesi sunuyor.
https://kullaniciadi.medium.com/feed
Bu XML kaynağını daha kolay işleyebilmek adına JSON’a dönüştürelim. Bunun için rss2json.com’un sunduğu bir API’dan faydalanacağız. Aşağıdaki gibi bir API ucu, Medium’daki son yazılarımızı bize JSON formatında verecek.
https://api.rss2json.com/v1/api.json?rss_url=https://kullaniciadi.medium.com/feed/
README Dosyasını Güncellemek
Projenin ana dizininde README.md
dosyası oluşturalım ve aşağıdaki gibi başlık ve yer tutucu etiketlerini içerisine ekleyelim. DATA
etiketlerini neden eklediğimize hemen aşağıda değineceğim.
Daha sonra src
dizini altına readme.js
dosyamızı oluşturalım. Bu dosya içerisinde kaynağımızdan asenkron olarak blog yazılarını alacak ve README.md
dosyasını güncelleyecek operasyonlar yer alacak.
Yukarıdaki işlemleri kısaca özetlemek gerekirse;
- Axios HTTP istemcisi aracılığıyla kaynağımıza GET isteğinde bulunarak yazılarımızı aldık.
- Yazılarımızın yalnızca başlık ve link alanları bize gerektiğinden
reduce
metodu yardımıyla sadece bu alanlardan oluşan bir metin oluşturduk. Yazılarımıza link verdik ve nizami gözükmeleri için liste hâline getirdik. - Daha sonra
README.md
dosyasını Node.js’in dosya sistemi üzerinde işlemler yapabilmemizi sağlayan fs (file system) API’ı ile açtık. - Açılan dosyada
DATA
etiketlerini ve içerisindekileri bir RegExp yardımıyla bulup az evvel oluşturduğumuz, içerisinde yazılarımızın olduğu liste ile değiştirerekREADME.md
dosyasına yeniden yazdık. - Bu yazma sırasında listemizin başına ve sonuna
DATA
etiketlerini yine ekledik ki, sonraki liste güncelleme isteklerinde de mevcut listeyi yakalayıp üzerine listenin yeni hâlini yazabilelim.
node src/readme.js
komutuyla JavaScript dosyasını çalıştırabiliriz fakat daha pratik olması açısından bunu package.json
dosyası içerisinde bir script olarak tanımlayalım.
Artık aşağıdaki komutu verdiğimizde yazdığımız operasyonlar çalışacak.
npm run start
Akabinde görüleceği üzere README.md
dosyasının içeriği aşağıdaki şekilde güncellenmiş olacak.
Github Actions için Workflow Oluşturmak
Bu işlemi bir defaya mahsus elle yaptık fakat asıl ihtiyacımız olan otomatize etmek. Bunun için GitHub Actions kullanacağız.
Projenin ana dizininde .github
ve onun içerisinde workflows
isimli dizinler oluşturalım. GitHub, workflow dosyalarını burada arayacağı için bu isimlendirme konvansiyonuna uymak mühim. dynamic-readme.yml
dosyasında workflow tanımlarımızı yapalım.
Yine yaptıklarımızı kısaca açıklamak gerekirse;
schedule
alanında hazırladığımız workflow’un otomatik olarak çalıştırılacağı zamanlanmış görevi (cron) tanımlıyoruz.0 0 * * 0
ile her cumartesiyi pazara bağlayan gece 00.00'da çalışmasını sağladık.workflow_dispatch
tanımıyla zamalanmış görev haricinde workflow’un elle de tetiklenebileceğini belirttik.- Ortam olarak işletim sistemi ve Node.js sürüm tercihlerimizi yapıp bağımlılıklarımızı (bu örnek özelinde yalnızca Axios HTTP istemcisi) kurduk.
- Script olarak tanımladığımız komutla yukarıdaki asenkron operasyonumuzu çalıştırdık.
- Bu işlemler sonrasında
git diff
ile repo içerisinde, yaniREADME.md
dosyamızda bir değişiklik olup olmadığını kontrol ettik. Eğer varsa Git tarihçemizde görünecek olan kullanıcı bilgilerini tanımlayıpREADME.md
dosyasının güncel hâlini yine tanımladığımız commit mesajı ile push’ladık.
Bu işlemlerden sonra workflow’un çalışabilmesi için tanımladığımız zamanlanmış görevi bekleyebilir veya “Run workflow” seçeneği ile derhâl çalıştırabiliriz. Her şey yolunda gittiği takdirde aşağıdaki gibi ekran bizi karşılayacak.
Sonrasında README.md
dosyamızın güncellendiğini görebiliriz.
Git tarihçesi de tanımladığımız şekilde görünmekte.
Sonuç
Örnekteki GitHub reposuna buradan erişilebilir. Spesifik olarak bir problemi çözmesinden ziyade yöntem olarak yazmak istedim bu defa. Jira, Trello vs. gibi proje yönetimi yapılan ve dışarıya API veren birçok araç var. Oralardan alınacak verileri bir repoyla ilişkilendirerek changelog takibi yapmak ilk aklıma gelen pratik oldu. Düşündükçe farklı kullanım alanları da çıkacaktır muhakkak.
Daha önce Netlify, Heroku, Bitbucket Pipelines gibi farklı CI/CD platform ve araçlarını kullanmıştım. Bir kısmını hâlâ kullanmaya devam ediyorum. Bu vesileyle GitHub Actions’a da bir ucundan dokunmuş oldum. Temiz ve anlaşılır bir arayüzü var. Özellikle workflow tarafında ciddi bir topluluk desteği mevcut. Temel olarak ihtiyaç olabilecek çoğu workflow ve aksiyona kolayca ulaşılabiliyor. Önümüzdeki dönemde sıklıkla başvuracağım gibi gözüküyor GitHub Actions’a.