Git Transport-Bash Script

Umut Boz
KoçSistem
Published in
6 min readMar 17, 2021

Sayıca çok olan projelerinizi tüm geçmiş bilgileriyle birlikte(commits, branches, tags) başka bir git platformuna dinamik bir şekilde taşımak istiyorsanız, bu yazıda paylaşacağım script ve çalışma işinizi kolaylaştıracaktır. Bu gibi script’leri nasıl geliştirebiliriz? Nasıl kendi ortamlarınıza uyarlayabiliriz? Ya da tekrarlı operasyonel işleri script yazarak nasıl kolaylaştırabiliriz? Gibi soruların cevaplarını bu çalışmada bulabilirsiniz.

Script’in Hikayesi

Bu script’in geliştirme sebebi, projelerin tüm kodlarıyla birlikte başka bir git destekli platforma taşınmasıdır. Git destekli bir platform üzerinde onlarca projeniz var ve bu projelerin tüm geçmiş hikayelerini kaybetmeden başka bir git destekli ortama taşımak istiyoruz. Hikaye tamda burada başlıyor. Bu geçmişleri saklı tutmak için git mirror işlemi yapmalısınız. Sonra hedef olan ortamınıza mirror’ladığınız kaynağınızı göndermeniz gerekmektedir. Peki bu projelerin sayısı onlarca ise ne yapacağız? Bileğe kuvvet olarak bu operasyonu tekrarlamak durumunda kaldığımız esnada 2. projeden itibaren acaba hangi projeyi aldım? hangisini gönderdim? projelerin isimleri ne oldu? proje kodları birbirine mi karıştı? gibi sorularla tam da boğuşurken sıralı işlemlerinizi bash script adım adım tamamlayabilirsiniz. Bash Script yazarken Python dilini tercih ediyorum. Böylelikle daha önce yazmış olduğum Python kütüphanelerinden kullanabiliyorum hemde daha esnek olduğu için script dünyamızı birazda olsa modern hale getirip OOP ve Python nimetlerinden faydalanabiliyorum. Bu yazıda Python ile bash script nasıl yazılır konusuna değinmeyeceğim lakin daha evvel ki yazılarımı buraya referans vereceğim.

Python ile nasıl bash script yazılabilir konusunu aşağıya bırakıyorum. Geçmiş bir yazımdan daha detaylı inceleyebilirsiniz.

DevOps için Semantik Versiyon Üreten Script-Medium

Script Yazmak

Script’ler yukarıdan aşağı doğru bir akışla komutlardan oluşan genelde betik dillerin kullanıldığı bir süreci gerçekleştirmek üzere bir araya gelmiş kod bloklarıdır. Benzer bir operasyonu kendi süreçlerinize uyarlamak için önce yapılacak işlemleri adım adım yazarak ana başlıkları çıkarabilirsiniz. Daha sonra her bir başlıktaki süreci gerçekleştiren kod parçalarını yazdıktan sonra süreçlerini birleştirip, çalıştıracağını uygun ortamda uyarlamanız gerçekmektedir. Her ne kadar çalıştığınız ortam, entegre olduğunuz ortam ve bağımlılıklar bazı zorluklar çıkarsada bu şekilde çalışarak süreç daha basit hale gelecektir. Bu işlemleri parçalar halinde belirleyelim.

Git Repo’ları Taşıma Adımları

1. Kaynak Repo’lardan proje isimlerini dinamik olarak al.

2. Her bir proje için bir dizin oluştur ve o projeye ait git geçmişini ilgili dizine clone -mirror işlemini gerçekleştir.

3. Her bir proje için hedef ortamda ilgili proje ismiyle dinamik bir şekilde proje oluştur ve git remote url’i oluştur.

4. Her bir proje için oluşturulan proje ismiyle bir remote origin oluştur.

5. Her bir projeyi hedef ortama push -mirror işlemini gerçekleştir.

6. Yukarıdaki adımları kendi için unit test süreciyle test işlemine tabi tut.

7. Her bir parçadan emin olduğunda tüm scripti birlikte çalıştır.

Git Repo’ları Taşıma işlemleri

Taşıma işlemini gerçekleştireceğimiz kaynak proje ve repolar Azure DevOps üzerinde bulunuyor. Azure DevOps Service REST Api’ları sayesinde dinamik olarak proje içinde bulunan repo isimlerini alabiliriz. Böylelikle hedef ortama taşınacak repo’nun ismine ve git url’ini bir array içinde tutmamız bizim için yeterli olacak. Bu kaynak repo’lar yazmış olduğum script’te Azure DevOps üzerinden besleniyor. Kendi örneğinizde bu Github ya da başka bir ortam olabilir. Eğer kaynak projeleriniz GitHub’da bulunuyorsa github’un Api’larını kullanarak taşınacak kaynağı değiştirebilirsiniz.

Yukarıdaki bıraktığım kaynak ile script içerisinde kullanıcı adı ve token key ile bu bu listeyi elde edebilirsiniz. Bu işlem için script içinde tercih etmiş olduğunuz programlama dili ile kullanmış olduğunuz kütüphane ve yöntemlerde farklılık olacaktır. Bu bash script’i Scala programlama dili ile de yazabilirsiniz. Bu durumda Java .jar paketlerinden faydalanabilirsiniz.

Bash Script yazarken tercih etmiş olduğum dil Python dili olduğundan REST Api çağrımları için Python http ve yardımcı kütüphanelerini kullanmaktayım.

import urllib2import sslimport jsonimport base64
  1. Kaynak Repo’lardan proje isimlerini dinamik olarak al

Rest Api Http Request — Python

Yukarıda API’dan aldığımız bir çok bilgi vardı fakat bizim için gerekli olan iki değeri bir dictionary objenin içerisinde saklayarak dizi içinde saklıyoruz. Yine elde ettiğimiz size bilgisi ile de içerisinde veri olan repo’ları taşıma işlemine alarak ek bir kontrolle sağlık bir taşıma işlemini yürütebiliriz.

for val in jsonData["value"]:    val_json_dumps = json.dumps(val)    val_json_object = json.loads(val_json_dumps)    repos_size = val_json_object.get('size')    if repos_size == None or repos_size == 0:    continue    repositories.append({'name' : val_json_object.get('name'), 'url' : val_json_object.get('remoteUrl')})

2. Her bir proje için bir dizin oluştur ve o projeye ait git geçmişini ilgili dizine clone -mirror işlemini gerçekleştir.

3. Her bir proje için hedef ortamda ilgili proje ismiyle dinamik bir şekilde proje oluştur ve git remote url’i oluştur.

Hedef olarak taşıyacağım git platformu dev.azure (Azure DevOps Cloud) olduğundan yine bir Api çağrısı ile bu işlem gerçekleştirilebilir. Fakat script içerisindeki bu adımın daha kısa ve sağlıklı yürütülmesi için Azure CLI’ı tercih ettim. Kullanmış olduğum işletim sistemi MacOS olduğu için Azure CLI için terminal üzerinden çalışabilmek için bazı kurulumlar gerçekleştirilmesi gerekmektedir. Bu işlemler için bazı özet bilgileri ve kaynakları buraya bırakıyorum.

Azure CLI kurulum işlemlerinden sonra aşağıdaki gibi CLI üzerinde Azure DevOps platformuna login olmanız gerekmektedir. Bu işlem için uzun çabalar sonucunda bu kodu çalıştırdığımda login işlemini gerçekleştirebildim.

az login --use-device-code --allow-no-subscriptions

Yukarıdaki bu işlemler tamamlandıktan sonra artık hedef git ortamımız olan Azure DevOps Cloud üzerinde aşağıdaki tek bir satırlık işlemle proje repo’larımızı dinamik olarak oluşturabileceğiz.

az repos create --name repo_name --project parent_project_name

Dinamik olarak çekmiş olduğumuz repo’ların içerisinde döngüde bir proje için aşağıdaki CLI kodunu çalıştırabiliriz.

#create repo on target repo (azure cloud) with azure clitarget_project_name = "target_project_name"az_create_repo_cli_cmd = "az repos create --name " + repo.get("name") + " --project " + target_project_nameos.system(az_create_repo_cli_cmd)

4. Her bir proje için oluşturulan proje ismiyle bir remote origin oluştur.

Yine bu adımda terminal üzerinde koşacak bu kodlarımızı daha temiz bir şekilde çalıştırabilmek adına ssh key oluşturmayı ve oturumu ve erişmi bu şekilde ilerletmeyi tercih ettim.

#git remote add new-origin <url_of_new_repo>target_git_new_repo_url = "git@ssh.dev.azure.com:v3/{organization}/{project}/" + repo.get("name")git_remote_add_new_origin_cmd = "git -C " + repo_folder + "/" +  repo.get("name") + ".git " + " remote add azuredevops " + target_git_new_repo_urlos.system(git_remote_add_new_origin_cmd)

https://docs.microsoft.com/en-us/azure/devops/repos/git/use-ssh-keys-to-authenticate?view=azure-devops

5. Her bir projeyi hedef ortama push -mirror işlemini gerçekleştir.

Ve son adım olarak push -mirror işlemini gerçekleştiriyoruz. Bu git işlemlerinde bash script’i çalıştıracağınız dizin komutları çalıştıracağınız dizin olarak varsayılır. Çalıştırdığımız işlemlerde her bir süreç için bir dizin açtığımız ve bu dizinler içerisinde clone işlemini o dizin altına oluşturmak daha sonrasında, bu dizin altında push işlemi yapabilmek adına git deyiminden sonra -C keyword kullanarak, komutu çalıştıracağımız dizini dinamik olarak belirterek ilgili dizin altında süreci gerçekleştirebiliriz.

os.system("git -C " + repo_folder + "/" +  repo.get("name") + ".git" + " push azuredevops --mirror")os.system("cd ..")

Kod kalitesi İyileştirme

Her ne kadar bir script’de yazıyor olsak bile yazmış olduğumuz kodları daha düzenli olması adına kod tekrarlarından temizlemek için bazı dokunuşlarla iş süreç adımlarımızı method’lara ayıralım. Evet şimdi daha okunaklı oldu :)

Son olarak Python kullanarak git repolarımızı taşımasını gerçekleştiren bash script’i aşağıdaki gibi sh komutu ile çalıştırıp, arkamıza yaslanabiliriz. 😎

sh git-transport.sh

--

--