Pre-commit Nedir?

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

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öntem ile hızlıca bilgisayarınıza 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 istedigimiz pre-commit kontrollerini ekleyeceğiz.

Ö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 şuanlık test amaçlı çalıştıracağımız için hook trigerlanmadan 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.

image.png

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.

image.png

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 reponuz üzerinde git’e pushlayıp ilgili yerleri değişince sizin de sisteminizde entegre 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 hali ile 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....................................................Passed
go fmt test..............................................................Passed
go mod tidy..............................................................Passed
go build.................................................................Passed

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ım da 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.

 

Hayatta en hakiki mürşit ilimdir.
Mustafa Kemal Atatürk