GitLab ile Temel SDLC Pratiği
Yazılım geliştirme süreci sadece kod yazmaktan ibaret değildir. Bir değişikliğin neden yapıldığı, hangi branch üzerinde geliştirildiği, nasıl test edildiği, ne zaman commit edildiği, hangi Merge Request ile main branch’e alındığı ve pipeline sonucunun ne olduğu da en az kodun kendisi kadar önemlidir.
Bu çalışmada çok küçük bir Python örneği üzerinden GitLab’in temel SDLC akışını uçtan uca deneyimledim. Örneğimiz basitti: bir ürün fiyatı ve KDV oranı alıp KDV tutarını ve KDV dahil toplam fiyatı hesaplayan bir fonksiyon yazmak. Ancak küçük bir fonksiyon bile doğru akışla ele alındığında; requirement, development, testing, documentation, CI/CD, review ve merge adımlarını görmek için oldukça güçlü bir öğrenme alanı sunuyor.
Başlangıç noktamız temiz bir main branch idi. Local repository, GitLab üzerindeki origin/main ile senkron durumdaydı ve çalışma alanında commit edilmemiş hiçbir değişiklik yoktu. Bu temiz noktadan sonra doğrudan main üzerinde çalışmak yerine yeni bir feature branch açtım. Böylece yapılacak değişiklikleri izole ederek gerçek ekip çalışmalarında kullanılan pratiklere uygun bir akış kurmuş oldum.
Küçük bir Python uygulaması, gerçek bir SDLC provası
Örnek uygulama için repository içinde ayrı bir klasör yapısı oluşturdum. Kaynak kodu `src` klasöründe, testleri `tests` klasöründe, proje açıklamasını ise `README.md` içinde tuttum. Bu ayrım basit görünse de sürdürülebilirlik için önemlidir: kod, test ve dokümantasyon birbirinden ayrılır; yeni gelen biri projeyi daha kolay okur.
Python tarafında `calculate_vat()` adlı küçük bir fonksiyon yazdım. Fonksiyon fiyat ve KDV oranını alıyor, KDV tutarını ve toplam fiyatı hesaplıyor. Ayrıca negatif fiyat veya negatif KDV oranı girildiğinde hata üretecek basit kontroller içeriyor. Böylece yalnızca “çalışan” değil, beklenmeyen girdilere karşı davranışı tanımlanmış bir fonksiyon elde edilmiş oldu.
Kodun çalıştığını manuel olarak görmek ilk adımdı. Ancak SDLC açısından asıl önemli olan, bu davranışı otomatik testlerle doğrulamaktı. Bu nedenle Python standard library içindeki `unittest` modülü ile dört basit test yazdım: iki başarılı hesaplama senaryosu ve iki hata kontrolü. Testler local ortamda başarıyla geçti.
CI/CD ile testleri GitLab’e taşıma
Local testin başarılı olması değerliydi; fakat ekip standartlarında bunun GitLab üzerinde otomatik doğrulanması gerekir. Bu nedenle repository köküne `.gitlab-ci.yml` dosyası ekledim. Pipeline tek bir `test` stage içeriyordu ve `python:3.12` image üzerinde unit testleri çalıştıracak şekilde tanımlandı.
Bu noktada GitLab artık sadece kodu saklayan bir platform olmaktan çıktı; değişikliğin kalitesini doğrulayan bir CI/CD mekanizmasının parçası haline geldi. Feature branch GitLab’e push edildiğinde pipeline otomatik çalıştı ve testler geçti. Ardından Merge Request oluşturuldu.
Merge Request ekranında source branch `feature/01-basic-vat-calculator`, target branch ise `main` idi. MR açıklamasına yapılan değişiklikler, SDLC eşleştirmesi ve local test kanıtı eklendi. Bu sayede MR yalnızca teknik bir merge talebi değil, aynı zamanda okunabilir bir değişiklik kaydı haline geldi.
Merge sonrası temiz kapanış
Feature branch pipeline’ı başarılı olduktan sonra Merge Request main branch’e alındı. Merge sonrasında GitLab main branch için de pipeline çalıştırdı ve bu pipeline da başarıyla tamamlandı. Böylece yalnızca feature branch üzerinde değil, main üzerinde de testlerin geçtiği doğrulanmış oldu.
Son adımda local bilgisayarımdaki main branch’i GitLab’deki güncel main ile eşitledim, eski feature branch’i local’den sildim ve remote-tracking referanslarını `git fetch –prune` ile temizledim. Böylece bir sonraki çalışma için repository yeniden temiz bir başlangıç noktasına geldi.
Bu küçük çalışmanın en büyük çıktısı şuydu: SDLC mantığını anlamak için büyük bir uygulama yazmak zorunda değiliz. Doğru branch stratejisi, anlaşılır commit, test, README, pipeline, Merge Request ve merge sonrası temizlik ile küçük bir Python fonksiyonu bile gerçekçi bir yazılım yaşam döngüsü pratiğine dönüşebilir.
Çalışmanın Teknik Zemini
| SDLC kavramı | Bu çalışmadaki karşılığı |
| Requirement | KDV tutarı ve KDV dahil toplam fiyat hesaplama ihtiyacının tanımlanması |
| Development | `vat_calculator.py` dosyasının yazılması |
| Testing | `unittest` ile dört test senaryosunun çalıştırılması |
| Documentation | Proje klasörüne `README.md` eklenmesi |
| CI/CD | GitLab pipeline ile testlerin otomatik çalıştırılması |
| Review | Merge Request açılması ve değişikliklerin görünür hale getirilmesi |
| Merge | Feature branch değişikliklerinin `main` branch’e alınması |
| Cleanup | Local branch ve remote-tracking referanslarının temizlenmesi |
Başlangıç durumu
Çalışma başlamadan önce local repository’nin GitLab remote repository ile bağlı olduğu ve main branch’in temiz olduğu doğrulandı.
| PS E:\ASIYE_DEVELOPMENT\python-training> git remote -v origin https://gitlab.com/asiyeyigit/python-gitlab-workflow-demo.git (fetch) origin https://gitlab.com/asiyeyigit/python-gitlab-workflow-demo.git (push)PS E:\ASIYE_DEVELOPMENT\python-training> git status On branch main Your branch is up to date with ‘origin/main’. nothing to commit, working tree clean |
| Yorum: Bu çıktı, çalışmaya güvenli bir noktadan başlandığını gösterir: main branch temizdir ve local çalışma alanında commit edilmemiş değişiklik yoktur. |
Uygulama Adımları ve Gerçek Çıktılar
Feature branch oluşturma
| PS E:\ASIYE_DEVELOPMENT\python-training> git checkout -b feature/01-basic-vat-calculator Switched to a new branch ‘feature/01-basic-vat-calculator’PS E:\ASIYE_DEVELOPMENT\python-training> git branch * feature/01-basic-vat-calculator main |
Bu adımda geliştirme main branch’ten ayrılmış, izole bir feature branch üzerinde başlatılmıştır. Bu pratik, Merge Request akışının temelidir.
Proje klasör yapısını hazırlama
| New-Item -ItemType Directory -Force -Path “docs” New-Item -ItemType Directory -Force -Path “projects\01-gitlab-sdlc-basic-python” New-Item -ItemType Directory -Force -Path “projects\01-gitlab-sdlc-basic-python\src” New-Item -ItemType Directory -Force -Path “projects\01-gitlab-sdlc-basic-python\tests” |

Şekil 1 – `tree /F` çıktısı ile oluşturulan proje klasör yapısı
Oluşturulan yapı aşağıdaki sorumluluk ayrımını sağlar:
- `src/`: Python kaynak kodu
- `tests/`: unit test dosyaları
- `README.md`: proje açıklaması ve çalışma komutları
- `.gitlab-ci.yml`: GitLab pipeline tanımı
Python fonksiyonunu yazma
Kod özeti
| def calculate_vat(price: float, vat_rate: float) -> dict: “””Calculate VAT amount and total price.”””if price < 0: raise ValueError(“Price cannot be negative.”) if vat_rate < 0: vat_amount = price * vat_rate / 100 return { |
Uygulama çalıştırma çıktısı
| PS E:\ASIYE_DEVELOPMENT\python-training> python projects\01-gitlab-sdlc-basic-python\src\vat_calculator.py VAT Calculation Result ———————- Price: 100 VAT Rate: 20% VAT Amount: 20.0 Total Price: 120.0 |
Unit testleri ekleme
Test senaryoları
| class TestVatCalculator(unittest.TestCase): def test_calculate_vat_with_20_percent(self): result = calculate_vat(100, 20) self.assertEqual(result[“vat_amount”], 20) self.assertEqual(result[“total_price”], 120)def test_calculate_vat_with_10_percent(self): result = calculate_vat(200, 10) self.assertEqual(result[“vat_amount”], 20) self.assertEqual(result[“total_price”], 220) def test_negative_price_raises_error(self): def test_negative_vat_rate_raises_error(self): |
Local test çıktısı
| PS E:\ASIYE_DEVELOPMENT\python-training> python -m unittest discover -s projects\01-gitlab-sdlc-basic-python\tests …. ———————————————————————- Ran 4 tests in 0.000sOK |
| Yorum: Bu çıktı, fonksiyonun hem başarılı hesaplama senaryolarında hem de negatif giriş kontrollerinde beklendiği gibi çalıştığını gösterir. |
README ve pipeline ekleme
README dosyası ile projenin amacı, dosya yapısı, çalıştırma komutları ve SDLC karşılığı yazılı hale getirildi. Ardından repository köküne `.gitlab-ci.yml` dosyası eklendi.
.gitlab-ci.yml
| stages: – testpython_unit_tests: stage: test image: python:3.12 script: – python –version – python -m unittest discover -s projects/01-gitlab-sdlc-basic-python/tests |
Staging alanı, `__pycache__` temizliği ve `.gitignore`
Testleri çalıştırdıktan sonra Python otomatik olarak `__pycache__` klasörleri ve `.pyc` dosyaları oluşturdu. İlk `git add` sonrasında bu dosyaların staging area içine girdiği görüldü. Bu, gerçek projelerde çok sık yaşanan ve iyi öğrenilmesi gereken bir durumdur.
Düzeltilmesi gereken staging çıktısı
| Changes to be committed: new file: .gitlab-ci.yml new file: projects/01-gitlab-sdlc-basic-python/README.md new file: projects/01-gitlab-sdlc-basic-python/src/__pycache__/vat_calculator.cpython-38.pyc new file: projects/01-gitlab-sdlc-basic-python/src/vat_calculator.py new file: projects/01-gitlab-sdlc-basic-python/tests/__pycache__/test_vat_calculator.cpython-38.pyc new file: projects/01-gitlab-sdlc-basic-python/tests/test_vat_calculator.py |
.gitignore içeriği
| __pycache__/ *.py[cod] *$py.class.venv/ venv/ .env |
| Önemli ders: Git’e kaynak kod, testler, pipeline ve dokümantasyon alınır. Python’un otomatik ürettiği `__pycache__` ve `.pyc` dosyaları repository’ye alınmaz. |
Commit alma
Commit çıktısı
| PS E:\ASIYE_DEVELOPMENT\python-training> git commit -m “Add basic VAT calculator SDLC example” [feature/01-basic-vat-calculator 06ed300] Add basic VAT calculator SDLC example 5 files changed, 147 insertions(+) create mode 100644 .gitignore create mode 100644 .gitlab-ci.yml create mode 100644 projects/01-gitlab-sdlc-basic-python/README.md create mode 100644 projects/01-gitlab-sdlc-basic-python/src/vat_calculator.py create mode 100644 projects/01-gitlab-sdlc-basic-python/tests/test_vat_calculator.py |
Commit ID kısa hali `06ed300` olarak oluştu. Bu commit; kod, test, README, `.gitignore` ve GitLab CI/CD pipeline dosyasını kapsayan tek anlamlı değişiklik paketi oldu.
Feature branch’i GitLab’e push etme
Push çıktısı
| PS E:\ASIYE_DEVELOPMENT\python-training> git push -u origin feature/01-basic-vat-calculator Enumerating objects: 12, done. Counting objects: 100% (12/12), done. Writing objects: 100% (11/11), 2.12 KiB | 722.00 KiB/s, done. remote: remote: To create a merge request for feature/01-basic-vat-calculator, visit: remote: https://gitlab.com/asiyeyigit/python-gitlab-workflow-demo/-/merge_requests/new?merge_request%5Bsource_branch%5D=feature%2F01-basic-vat-calculator remote: To https://gitlab.com/asiyeyigit/python-gitlab-workflow-demo.git * [new branch] feature/01-basic-vat-calculator -> feature/01-basic-vat-calculator branch ‘feature/01-basic-vat-calculator’ set up to track ‘origin/feature/01-basic-vat-calculator’. |
Merge Request oluşturma ve pipeline sonuçları
GitLab üzerinde yeni Merge Request ekranında source branch `feature/01-basic-vat-calculator`, target branch ise `main` olarak doğrulandı. MR başlığı `Add basic VAT calculator SDLC example` olarak belirlendi.

Şekil 2 – GitLab New Merge Request ekranı: feature branch’ten main branch’e geçiş
Merge Request açıklaması özeti
| ## Summary This merge request adds a beginner-friendly Python VAT calculator example to demonstrate a basic GitLab-based SDLC workflow.## Changes – Added a simple Python VAT calculator function – Added unit tests using Python standard library – Added project-level README documentation – Added `.gitignore` for Python-generated files – Added a basic GitLab CI/CD pipeline to run unit tests ## Test Evidence Ran 4 tests |

Şekil 3 – Feature branch ve main branch pipeline sonuçları: passed
GitLab pipeline sonuçları
| Pipeline #2647749968 passed Pipeline passed for 06ed300 on feature/01-basic-vat-calculatorPipeline #2647815644 passed Pipeline passed for 6fdcb255 on main in 53 seconds |
Local main branch’i güncelleme ve branch temizliği
Pull çıktısı
| PS E:\ASIYE_DEVELOPMENT\python-training> git pull origin main From https://gitlab.com/asiyeyigit/python-gitlab-workflow-demo cdb6e22..6fdcb25 main -> origin/main Updating cdb6e22..6fdcb25 Fast-forward .gitignore | 7 +++ .gitlab-ci.yml | 9 +++ projects/01-gitlab-sdlc-basic-python/README.md | 67 ++++++++++++++++++++++ …/src/vat_calculator.py | 29 ++++++++++ …/tests/test_vat_calculator.py | 35 +++++++++++ 5 files changed, 147 insertions(+) |
Kapanış ve temizlik çıktıları
| PS E:\ASIYE_DEVELOPMENT\python-training> git status On branch main Your branch is up to date with ‘origin/main’.nothing to commit, working tree clean PS E:\ASIYE_DEVELOPMENT\python-training> git branch -d feature/01-basic-vat-calculator PS E:\ASIYE_DEVELOPMENT\python-training> git fetch –prune |
SDLC Eşleştirmesi
| Aşama | Gerçekleşen aksiyon | Kanıt |
| Requirement | KDV tutarı ve toplam fiyat ihtiyacı belirlendi | README ve MR açıklaması |
| Development | `calculate_vat()` fonksiyonu yazıldı | `vat_calculator.py` |
| Local Testing | 4 adet unit test çalıştırıldı | `Ran 4 tests – OK` |
| Documentation | Proje açıklaması yazıldı | `README.md` |
| CI/CD | GitLab pipeline tanımlandı | `.gitlab-ci.yml` |
| Version Control | Değişiklikler commit edildi | `06ed300` |
| Collaboration / Review | Merge Request açıldı | `!1` |
| Integration | Feature branch main’e merge edildi | `6fdcb255` |
| Validation on main | Main pipeline geçti | `Pipeline #2647815644 passed` |
| Cleanup | Feature branch ve remote reference temizlendi | `git branch -d`, `git fetch –prune` |
Sahadan Öğrenilen Küçük Ama Kritik Dersler
Dosyayı oluşturmak ile kaydetmek aynı şey değildir.
VS Code’da dosya oluşturulduktan sonra içerik kaydedilmezse Python dosyası boş çalışabilir veya beklenen çıktı gelmeyebilir. Bu nedenle `Ctrl + S` basit ama kritik bir adımdır.
`main` branch doğrudan çalışma alanı olmamalıdır.
Küçük bir örnekte bile feature branch açmak, Merge Request ve pipeline pratiğini gerçekçi hale getirir.
Testler yalnızca “hata var mı?” sorusunu cevaplamaz.
Testler aynı zamanda fonksiyonun beklenen davranışını yazılı hale getirir. Bu çalışma için 100/20 ve 200/10 hesaplama senaryoları ile negatif giriş kontrolleri test edildi.
`.gitignore` erken eklenmelidir.
`__pycache__` ve `.pyc` dosyalarının staging alanına girmesi, Python projelerinde sık görülen bir durumdur. `.gitignore` bunu yönetilebilir hale getirir.
Pipeline, kalite kapısı gibi düşünülmelidir.
Feature branch’te testlerin geçmesi yeterli değildir; merge sonrası main branch pipeline’ının da başarılı olması gerekir.
Merge sonrası local ortam güncellenmelidir.
GitLab’de merge tamamlandıktan sonra local `main` branch `git pull origin main` ile güncellenmelidir. Aksi halde GitLab ve local ortam farklı kalır.
Ek A. Kullanılan Temel Komutlar
| Komut | Amaç |
| git remote -v | Local repository’nin hangi GitLab remote repository’ye bağlı olduğunu görmek |
| git status | Working tree ve branch durumunu kontrol etmek |
| git checkout -b feature/01-basic-vat-calculator | Yeni feature branch oluşturmak |
| tree /F | Klasör ve dosya yapısını görmek |
| python projects\01-gitlab-sdlc-basic-python\src\vat_calculator.py | Python uygulamasını çalıştırmak |
| python -m unittest discover -s projects\01-gitlab-sdlc-basic-python\tests | Unit testleri çalıştırmak |
| git add .gitlab-ci.yml projects\01-gitlab-sdlc-basic-python | Dosyaları staging area’ya almak |
| git restore –staged <file> | Yanlışlıkla stage edilen dosyayı staging area’dan çıkarmak |
| git commit -m “Add basic VAT calculator SDLC example” | Değişiklikleri local Git tarihçesine kaydetmek |
| git push -u origin feature/01-basic-vat-calculator | Feature branch’i GitLab’e göndermek |
| git pull origin main | GitLab’deki güncel main branch’i local ortama çekmek |
| git branch -d feature/01-basic-vat-calculator | Merge edilmiş local feature branch’i silmek |
| git fetch –prune | GitLab’de silinmiş remote branch referanslarını local’den temizlemek |
Sonuç
Bu çalışmada gördüğümüz Feature branch açmak, anlamlı commit almak, test yazmak, pipeline çalıştırmak ve Merge Request üzerinden main branch’e almak DevOps kültürünün temel taşlarıdır.
Bir sonraki seviyede bu örneğe branch protection, required approval, code quality kontrolü, coverage raporu, package yapısı ve release/tag yönetimini ekleyeceğiz. GitLab ile SDLC akışını anlamak için bu ilk çalışma iyi bir başlangıçtır.
Sarav Asiye Yiğit * 2 Temmuz 2026






Yorumunuzu Bırakın