Pre-Commit Nedir?

Pre-Commit Nedir? - DevOps yazısının kapak görseli

Pre-Commit Nedir?

Pre Türkçe ön demektir. Pre-commit ise commit öncesi işlemi ifade etmektedir. Pre-commit bizim için aslında bir hooktur ve commit esnasında araya girerek istediğimiz kontrolleri çalıştırmaya yarar.

Hızlı Kurulum Nasıl Yapılır ?

Aşağıdaki yöntemle hızlıca bilgisayarınızda bir sanal Python ortamında test edebilirsiniz.

 
pip install pre-commit
 

pre-commit binarysini bilgisayarımıza kurduktan sonra yapmamız gereken proje ana dizininde bir adet .pre-commit-config.yaml oluşturmak ve bu oluşturduğumuz yaml içerisinde istediğimiz pre-commit kontrollerini eklemek.

Örnek olması açısından ben bir tane Go projesi ve içine bazı kontroller ve özelleştirilmiş kontrol mekanizmaları nasıl yazabileceğimizi göstereceğim.

Pre-Commit Nasıl Çalıştırılır?

Biz şu anlık test amaçlı çalıştıracağımız için hook triggerlanmadan yeni kontroller eklediğinizde her seferinde pre-commit atmak zorunda değilsiniz. Terminal üzerinde

 
pre-commit install
pre-commit run --all-files
 

Komutunu çalıştırınca, daha commit atmadan aslında config içindeki kontrollerinizi çalıştırabilirsiniz.

Not: Pre-Commit → git commit -m “message” bu işlemden sonra çalışmaktadır; başarısız olursa commit git versiyon kontrol sistemine işlememektedir.

 
git commit -m "test file added"
[WARNING] The 'rev' field of repo '<https://github.com/miraccan00/blog-wiki>' appears to be a mutable reference (moving tag / branch).  Mutable references are never updated after first install and are not supported.  See <https://pre-commit.com/#using-the-latest-version-for-a-repository> for more details.  Hint: `pre-commit autoupdate` often fixes this.
trim trailing whitespace.................................................Passed
fix end of files.........................................................Passed
check for added large files..............................................Passed
detect private key.......................................................Passed
Repository Validation....................................................Failed
- hook id: repository-validation
- exit code: 1

Repository Validation: Dockerfile kontrolü yapılıyor...
HATA: Repoda 'Dockerfile' bulunamadı!
Lütfen projenizin kök dizinine bir Dockerfile ekleyin.

Trivy Filesystem Scan....................................................Passed
go fmt test..........................................(no files to check)Skipped
go mod tidy..........................................(no files to check)Skipped
go build.............................................(no files to check)Skipped
 

Örnek Github Deposunu Lokalimize Klonlama

Öncelikle repoyu lokal bilgisayarımıza indirelim.

https://github.com/miraccan00/blog-wiki/tree/pre-commit

pre-commit branch geçiş yapalım.

Terminal üzerinde nasıl çalıştırılır kısmında anlattığımız komutu çalıştırınca aşağıdakine benzer bir çıktı almalıyız.

Buraya kadar her şey tamam; artık pre-commit hook çalıştığını görüyoruz. İlgili validasyonları bize sunulanları ekleyebildik.

Burada 2 temel ayrıma dikkat etmeliyiz.

  • Uzak sunucu üzerinden kontrolleri çekebiliriz.
 
  # General checks
  - repo: <https://github.com/pre-commit/pre-commit-hooks>
    rev: v4.5.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-added-large-files
        args: ['--maxkb=1000']
      - id: detect-private-key

  - repo: <https://github.com/miraccan00/blog-wiki>
    rev: pre-commit-ozel-kontroller  # git tag veya commit hash kullanın
    hooks:
      - id: repository-validation
      - id: trivy-fs-scan 

  • Lokal bilgisayar üzerinde kontrolleri direkt çalıştırabiliriz.
 
# Go formatting and checks (Windows compatible)
  - repo: local
    hooks:
      - id: go-fmt
        name: go fmt test
        entry: go fmt ./...
        language: system
        types: [go]
        pass_filenames: false

      - id: go-mod-tidy
        name: go mod tidy
        entry: go mod tidy
        language: system
        types: [go]
        pass_filenames: false
      - id: go-build
        name: go build
        entry: go build ./...
        language: system
        types: [go]
        pass_filenames: false

 

Tabii lokal kontrol merkezi bir yere bağlı olmadığı için 100’lerce github repomuzun bulunduğu bir sistem de bunu merkezi bir yerden yönetmek daha iyi olacaktır.

Pre-Commit Kontrolleri Nasıl Yazılır ve Entegre Edilir?

Öncelikle yapmamız gereken bir tane github reposu açmak. Ben blog yazılarım için kullandığım mevcut repo üzerinde bu kullanıma devam edeceğim. Siz kodları kopyalayıp kendi reponuza Git’e pushlayıp ilgili yerleri değiştirdiğinizde, sizin de sisteminizde entegrasyon otomatik olacaktır.

  - repo: <https://github.com/miraccan00/blog-wiki>
    rev: pre-commit-ozel-kontroller  # git tag veya commit hash kullanın
    hooks:
      - id: repository-validation
      - id: trivy-fs-scan 
.pre-commit-config.yaml ekleyip.
 
 pre-commit clean
 pre-commit install
 pre-commit run --all-files 
 

Çalıştırdığımızda artık .pre-commit-config.yaml dosyaları güncel hâliyle indirecek ve kontrolleri çalıştırıyor olacak.

 
OUTPUT:
$ pre-commit run --all-files
[WARNING] The 'rev' field of repo '<https://github.com/miraccan00/blog-wiki>' appears to be a mutable reference (moving tag / branch).  Mutable references are never updated after first install and are not supported.  See <https://pre-commit.com/#using-the-latest-version-for-a-repository> for more details.  Hint: `pre-commit autoupdate` often fixes this.
[INFO] Initializing environment for <https://github.com/pre-commit/pre-commit-hooks>.
[WARNING] repo `https://github.com/pre-commit/pre-commit-hooks` uses deprecated stage names (commit, push) which will be removed in a future version.  Hint: often `pre-commit autoupdate --repo <https://github.com/pre-commit/pre-commit-hooks`> will fix this.  if it does not -- consider reporting an issue to that repo.
[INFO] Initializing environment for <https://github.com/miraccan00/blog-wiki>.
[INFO] Installing environment for <https://github.com/pre-commit/pre-commit-hooks>.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
[INFO] Installing environment for <https://github.com/miraccan00/blog-wiki>.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
trim trailing whitespace.................................................Passed
fix end of files.........................................................Passed
check for added large files..............................................Passed
detect private key.......................................................Passed
Repository Validation....................................................Failed
- hook id: repository-validation
- exit code: 1

Repository Validation: Dockerfile kontrolü yapılıyor...
HATA: Repoda 'Dockerfile' bulunamadı!
Lütfen projenizin kök dizinine bir Dockerfile ekleyin.

Trivy Filesystem Scan.....................................

Bu şekilde bir çıktı aldık. Bu sayede artık reposunda Dockerfile olmayan repolar artık Git’e commit dahi atamıyor. Sola kaydırma tekniği (Shift Left Technique) olarak bilinen bir yapı kurguladık. Bu sayede daha developer Git’e kod pushlamadan birçok validasyonu burada yaparak aslında daha hızlı bir CI/CD akışı tasarlayabiliriz.

Not: Eğer developer bilinçli bir şekilde.

 
git push --no-verify
 

Komutu ile yazılım süreçleri sistemine kodlarını gönderebilse bile, bizim CI adımında ilk çalıştıracağımız adım repo kontrolleri olduğu için burada standartlarımıza uymayan kısmı ilk adımda yakalıyor olacağız.

Sonuç

Pre-commit bizim merkezi bir yerden standartların belirlenmesinde, yazılım süreçleri sisteminin üzerindeki yüklerin kısmi olarak developer bilgisayarında gerçekleştirilmesine ve daha stabil bir süreç yönetmemize yardımcı olmaktadır.