Git araçları ve GitLab - Bir patron gibi Sürekli Entegrasyon nasıl yapılır

Unsplash üzerinde Todd Quackenbush tarafından fotoğraf

Pantomath'ta, tüm geliştirme çalışmalarımız için GitLab kullanıyoruz. Bu yazının amacı GitLab'ı ve tüm özelliklerini sunmak değil, bu araçları hayatımızı kolaylaştırmak için nasıl kullandığımızı tanıtmaktır.

Yani bunların hepsi neyle alakalı? Geliştirme projenizle ilgili her şeyi otomatikleştirmek ve kodunuza odaklanmanıza izin vermek için. Tüyoları, ünite testlerini, veri yarışını, hafızayı dezenfektanı, kod kapsamını ve derlemeyi kapsayacağız.

Bu yayında gösterilen tüm kodlar https://gitlab.com/pantomath-io/demo-tools adresinde bulunabilir. Bu nedenle depoyu almaktan çekinmeyin ve içinde gezinmek için etiketleri kullanın. Depo $ GOPATH’ınızın src klasörüne yerleştirilmelidir:

$ go get -v -d gitlab.com/pantomath-io/demo-tools
$ cd $ GOPATH / src / gitlab.com / pantomath-io / demo araçları

Git araçları

Neyse ki, Go kodunuzu oluşturmak, test etmek ve kontrol etmek için birçok faydalı araçla birlikte gelir. Aslında, hepsi orada. Onları bir araya yapıştırmak için sadece ekstra araçlar ekleyeceğiz. Ama oraya gitmeden önce, onları tek tek almalı ve ne yaptıklarını görmeliyiz.

Paket listesi

Go projeniz, resmi belgede açıklandığı gibi bir paket koleksiyonudur. Aşağıdaki araçların çoğu bu paketlerle beslenecektir ve bu nedenle ihtiyacımız olan ilk komut paketleri listelemenin bir yoludur. Umarım, gidip liste alt komutuyla sırtımızı örter (iyi kılavuzu ve Dave Cheney'den bu mükemmel yazıyı okuyun):

$ go list. / ...

Araçlarımızı dış kaynaklara uygulamaktan kaçınmak istediğimizi ve onu kodumuzla sınırlandırdığımızı unutmayın. Bu yüzden satıcı dizinlerinden kurtulmamız gerekiyor:

$ go list. / ... | grep -v / satıcı /

keten tiftiği

Bu, kodda kullandığımız ilk araçtır: linter. Rolü, kodun kod stiline uyduğundan emin olmaktır. Bu isteğe bağlı bir araç veya en azından “olması güzel” gibi görünebilir, ancak projenizde tutarlı bir stil oluşturmanıza yardımcı olur.

Bu linter, başlı başına bir işlem değildir, bu yüzden onu almanız ve elle kurmanız gerekir (resmi doktora bakınız).

Kullanımı oldukça basittir: sadece kodunuzun paketlerinde çalıştırın (.go dosyalarını da işaretleyebilirsiniz):

$ golint -set_exit_status $ (listeye gir. / ... | grep -v / vendor /)

-Set_exit_status seçeneğini not edin. Varsayılan olarak, golint yalnızca stil sorunlarını basar ve geri döner (0 dönüş kodu ile), böylece CI hiçbir şeyin yanlış gittiğini düşünmez. -Set_exit_status öğesini belirtirseniz, herhangi bir stil sorunuyla karşılaşılırsa golint'in dönüş kodu 0'dan farklı olacaktır.

Ünite testi

Bunlar kodunuzda yapabileceğiniz en yaygın testlerdir. Her .go dosyası için, birim testlerini tutan ilişkili bir _test.go dosyasına sahip olmamız gerekir. Tüm paketler için testleri aşağıdaki komutla çalıştırabilirsiniz:

$ go test -short $ (listeye gir. / ... | grep -v / vendor /)

Veri yarışı

Bu genellikle kaplanması zor bir konudur, ancak go aracı varsayılan olarak içerir (ancak yalnızca linux / amd64, freebsd / amd64, darwin / amd64 ve windows / amd64'te bulunur). Veri yarışı hakkında daha fazla bilgi için bu makaleye bakın. Bu arada, işte nasıl çalıştırılacağı:

$ go test -race -short $ (listeye gir. / ... | grep -v / vendor /)

Bellek dezenfektanı

Clang, MemorySanitizer adlı başlatılmamış okumalar için hoş bir detektöre sahiptir. Go test aracı, bu Clang modülüyle etkileşime girecek kadar naziktir (linux / amd64 ana bilgisayarındayken ve Clang / LLVM'nin yeni bir sürümünü kullanıyorsanız (> = 3.8.0).

$ go testi -msan -short $ (listeye gir. / ... | grep -v / vendor /)

Kod kapsamı

Bu aynı zamanda kodunuzun sağlığını değerlendirmek zorundadır ve kodun hangi bölümünün birim testinde olduğunu ve hangi bölümün olmadığını görmek zorundadır. Rob Pike, bu konuda tam bir yazı yazdı.

Kod kapsamı oranını hesaplamak için aşağıdaki betiği çalıştırmamız gerekir:

$ PKG_LIST = $ (listeye git. / ... | grep -v / vendor /)
$ {PKG_LIST} paketindeki $; yap
    go test -covermode = count -coverprofile "cover / $ {package ## * /}. cov" "$ package";
tamam
$ tail -q -n +2 kapak / *.
$ go aracı kapağı -func = cover / extension.cov

Kapsam raporunu HTML biçiminde almak istiyorsak, aşağıdaki komutu eklememiz gerekir:

$ go tool cover -html = cover / clearance.cov -o thickness.html

İnşa etmek

Son fakat en az değil, kod tamamen test edildikten sonra, çalışan bir ikili oluşturabileceğimizden emin olmak için derlemek isteyebiliriz.

$ go build -i -v gitlab.com/pantomath-io/demo-tools

Makefile

git etiketi: init-makefile

Unsplash'ta Matt Artz tarafından fotoğraf

Artık Sürekli Entegrasyon bağlamında kullanabileceğimiz tüm araçlara sahibiz, hepsini bir Makefile içine sarabilir ve bunları çağırmak için tutarlı bir yolumuz olabilir.

Bu dokümanın amacı marka sunmak değildir, ancak bu konuda daha fazla bilgi edinmek için resmi belgelere başvurabilirsiniz.

PROJECT_NAME: = "demo araçları"
PKG: = "gitlab.com/pantomath-io/$(PROJECT_NAME)"
PKG_LIST: = $ (kabuk listesi {$ PKG} / ... | grep -v / vendor /)
GO_FILES: = $ (kabuk bul. -Adı '* .go' | grep -v / vendor / | grep -v _test.go)
.PHONY: Tüm bölümler temiz test kapsamı oluşturur.
hepsi: yapı
lint: ## Dosyaları lint
 @golint -set_exit_status $ {PKG_LIST}
test: ## Unittests çalıştır
 @ go test -short $ {PKG_LIST}
race: dep ## Run data yarış dedektörü
 @ go test -race -short $ {PKG_LIST}
msan: dep ## Hafıza temizleyiciyi çalıştır
 @ go test -msan -short $ {PKG_LIST}
kapsamı: ## Genel kod kapsamı raporu oluşturun
 ./tools/coverage.sh;
coverhtml: ## HTML’de genel kod kapsamı raporu oluştur
 ./tools/coverage.sh html;
dep: ## Bağımlılıkları al
 @ go get -v -d. / ...
build: dep ## İkili dosyayı oluşturun
 @ go build -i -v $ (PKG)
clean: ## Önceki yapıyı kaldır
 @rm -f $ (PROJECT_NAME)
yardım: ## Bu yardım ekranını görüntüle
 @grep -h -E '^ [a-zA-Z _-] +:. *? ##. * $$' $ (MAKEFILE_LIST) | awk 'BEGIN {FS = ":. *? ##"}; {printf "\ 033 [% 36m% -30s \ 033 [% 0m s \ n", $$ 1, $$ 2} '

Şimdi neyimiz var? Daha önce sunulan herhangi bir araç için bir hedef ve bunun için 3 hedef daha:

  • bağımlılıkların kurulması (dep);
  • projenin temizliği (temiz);
  • Bazı güzel ve parlak yardım (yardım).

Ayrıca kod kapsamı çalışması için bir komut dosyası oluşturmak zorunda olduğumuzu unutmayın. Bunun nedeni, Makefile'daki dosyalara döngü uygulamak bir acıdır. Böylece iş bir bash betiğinde yapılır ve Makefile sadece bu betiği tetikler.

Makefile komutunu aşağıdaki komutlarla deneyebilirsiniz:

$ yardım yap
$ tiftik
$ teminat yapmak

Sürekli Bütünleşme

git etiketi: init-ci

Unsplash'ta Max Panamá tarafından fotoğraf

Artık araçlar var ve kodumuz üzerinde çeşitli testler yapabiliriz, bunları depoda otomatik hale getirmek istiyoruz. Neyse ki, GitLab sadece bunun için CI boru hatları sunuyor. Ve bunun için kurulum oldukça basittir: oluşturduğunuz tek şey, deponun kökündeki bir .gitlab-ci.yml dosyasıdır.

Bu Yaml dosyasındaki tam belgeler tüm seçenekleri sunar, ancak bu .gitlab-ci.yml ile başlayabilirsiniz:

image: golang: 1.9
cache:
  yolları:
    - / apt-cache
    - /go/src/github.com
    - /go/src/golang.org
    - /go/src/google.golang.org
    - /go/src/gopkg.in
aşamaları:
  - Ölçek
  - inşa etmek
before_script:
  - mkdir -p /go/src/gitlab.com/pantomath-io / go / src / _ / oluşturuyor
  - cp -r $ CI_PROJECT_DIR /go/src/gitlab.com/pantomath-io/pantomath
  - ln -s /go/src/gitlab.com/pantomath-io / go / src / _ / yapı / pantomath-io
  - dep yapmak
unit_tests:
  sahne: test
  senaryo:
    - test yapmak
race_detector:
  sahne: test
  senaryo:
    - yarış yap
memory_sanitizer:
  sahne: test
  senaryo:
    - msan yap
kod kapsamı:
  sahne: test
  senaryo:
    - kapsama alanı yapmak
code_coverage_report:
  sahne: test
  senaryo:
    - coverhtml yapın
  sadece:
  - usta
lint_code:
  sahne: test
  senaryo:
    - tüy bırak
inşa etmek:
  sahne: yapı
  senaryo:
    - Yapmak

Dosyayı yıkarsanız, içeriği hakkında bazı açıklamalar bulunmaktadır:

  • İlk şey, CI'yi çalıştırmak için hangi Docker görüntüsünün kullanılacağını seçmektir. Projenize uygun görüntüyü seçmek için Docker Hub'a gidin.
  • Ardından, önbelleğe alınacak bu görüntünün bazı klasörlerini belirlersiniz. Buradaki amaç aynı içeriği birkaç kez indirmekten kaçınmak. Bir iş tamamlandığında, listelenen yollar arşivlenecek ve bir sonraki iş aynı arşivi kullanacaktır.
  • İşlerinizi gruplayacak farklı aşamaları siz belirlersiniz. Bizim durumumuzda, iki aşamaya sahibiz (bu sırada işlenecek): test et ve inşa et. Dağıtım gibi başka aşamalarımız da olabilirdi.
  • Before_script bölümü, iş gerçekten yapılmadan hemen önce Docker konteynerinde çalıştırılacak komutları tanımlar. Bağlamımızdaki komutlar, $ GOPATH'ta dağıtılan depoyu kopyalayıp bağlar ve bağımlılıkları kurar.
  • Ardından Makefile hedeflerini kullanarak asıl işleri gerçekleştirin. Uygulamanın ana dalla sınırlı olduğu code_coverage_report özel durumuna dikkat edin (örneğin kod kapsamı raporunu, özellik dallarından güncellemek istemiyoruz).

Depodaki .gitlab-ci.yml dosyasını teslim ettiğimizde / gönderdiğimizde, CI otomatik olarak tetiklenir. Ve boru hattı başarısız olur. Nasıl olur?

Lint_code işi başarısız olur, çünkü golint ikilisini bulamaz:

$ tiftik
make: golint: Komut bulunamadı
Makefile: 11: 'lint' hedefinin tarifi başarısız oldu
make: *** [lint] Hata 127

Bu yüzden, golfil'i dep hedefinin bir parçası olarak kurmak için Makefile'inizi güncelleyin.

Memory_sanitizer işi başarısız oluyor çünkü gcc şikayet ediyor:

$ msan yapmak
# runtime / cgo
gcc: error: -fsanitize = option: 'memory' ile tanınmayan argüman
Makefile: 20: 'msan' hedefinin tarifi başarısız oldu
make: *** [msan] Hata 2

Fakat go test komutunda -msan seçeneğinin tadını çıkarmak için Clang / LLVM> = 3.8.0 kullanmamız gerektiğini unutmayın.

Burada 2 seçeneğimiz var:

  • ya Clang'ı işte kurarız (before_script'i kullanarak);
  • veya varsayılan olarak Clang yüklü bir Docker görüntüsü kullanıyoruz.

İlk seçenek hoş, ancak bu kurulumun her bir iş için yapılması anlamına geliyor. Bu çok uzun sürecek, bir kere ve herkes için yapmalıyız. Bu yüzden ikinci seçeneği tercih ediyoruz, bu GitLab Registry ile oynamak için iyi bir yol.

git etiketi: use-own-docker

Konteyner için bir Docker dosyası oluşturmamız gerekiyor (her zamanki gibi: bu konuda daha fazla seçenek için resmi belgelerini okuyun):

# Temel resim: https://hub.docker.com/_/golang/
Golang’dan: 1.9
BAKIMCI Julien Andrieux 
# Golint'i yükle
ENV GOPATH / devam et
ENV PATH $ {GOPATH} / bin: $ PATH
ÇALIŞTIR git git -u github.com/golang/lint/golint
# LLVM deposu için apt anahtarı ekle
RUN wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
# LLVM uygun depo ekle
RUN echo "deb http://apt.llvm.org/stretch/ llvm-toolchain-stretch-5.0 ana" | tee -a /etc/apt/sources.list
# LLVM deposundan clang'ı kurun
RUN apt-get güncelleme && apt-get install -y - no-install-recommend \
    clang-5.0
    && apt-get \
    && rm -rf / var / lib / apt / listeler / * / tmp / * / var / tmp / *
# Clang'ı varsayılan CC olarak ayarla
ENV set_clang /etc/profile.d/set-clang-cc.sh
RUN echo "CC dışa aktar = clang-5.0" | tee -a $ {set_clang} && chmod a + x $ {set_clang}

Bu Docker dosyasının dışına yerleştirilen kap golang'a dayalı olacaktır: 1.9 görüntü (.gitlab-ci.yml dosyasında başvurulan).

Biz varken, golint'i konteynerin içine yerleştiriyoruz, böylece elimizde mevcut. Ardından Clang 5.0'ın LLVM deposundan kurulmasının resmi yolunu izliyoruz.

Şimdi Dockerfile'i yerleştirdik, konteyner görüntüsünü oluşturmalı ve GitLab için kullanılabilir hale getirmeliyiz:

$ docker giriş registry.gitlab.com
$ docker build -t registry.gitlab.com/pantomath-io/demo-tools.
$ docker push kayıt defteri.gitlab.com/pantomath-io/demo-tools

İlk komut sizi GitLab Kayıt Defterine bağlar. Sonra Dockerfile'da açıklanan konteyner görüntüsünü oluşturursunuz. Ve son olarak, GitLab Kayıt Defterine iletin.

Deponuzun Kayıt Defterine bir göz atın, kullanıma hazır bir görüntü göreceksiniz. Ve CI’nın resminizi kullanması için, sadece .gitlab-ci.yml dosyasını güncellemeniz gerekir:

image: golang: 1.9

olur

image: registry.gitlab.com/pantomath-io/demo-tools:latest

Son bir ayrıntı: CI'ye doğru derleyiciyi kullanmasını söylemeniz gerekir (yani, CC ortam değişkeni), bu nedenle değişken başlatma işlemini .gitlab-ci.yml dosyasına ekleriz:

dışa aktarma CC = clang-5.0

Değişiklik yapıldıktan sonra, bir sonraki işlem şu anda çalışan boru hattını tetikleyecektir:

https://gitlab.com/pantomath-io/demo-tools/pipelines/13497136

Rozetler

git etiketi: init-badges

Unsplash'ta Jakob Owens tarafından fotoğraf

Artık araçlar yerinde, her taahhüt bir test paketi açacak ve muhtemelen göstermek isteyeceksiniz ve bu meşru. :) Bunu yapmanın en iyi yolu, rozetleri kullanmak ve bunun için en iyi yer README dosyası.

Düzenleyin ve aşağıdaki 4 rozeti ekleyin:

  • Yapı Durumu: ana daldaki son boru hattının durumu:
[! [Yapı Durumu] (https://gitlab.com/pantomath-io/demo-tools/badges/master/build.svg)] (https://gitlab.com/pantomath-io/demo-tools/commits) / Master)
  • Kapsam Raporu: Testlerin kapsadığı kod yüzdesi
[! [Kapsam Raporu] (https://gitlab.com/pantomath-io/demo-tools/badges/master/coverage.svg)]] (https://gitlab.com/pantomath-io/demo-tools/commits) / Master)
  • Git Rapor Kartı:
[! [Git Rapor Kartı] (https://goreportcard.com/badge/gitlab.com/pantomath-io/demo-tools)]] (https://goreportcard.com/report/gitlab.com/pantomath-io/ demo-araçları)
  • Lisans:
[! [Lisans MİT] (https://img.shields.io/badge/License-MIT-brightgreen.svg)] (https://img.shields.io/badge/License-MIT-brightgreen.svg)

Kapsam raporunun özel bir konfigürasyona ihtiyacı var. GitLab’a bu bilgiyi nasıl elde edeceğinizi söylemelisiniz, CI’de çalışırken onu gösteren bir iş olduğunu düşünün.
GitLab’a herhangi bir iş çıktısında kullanılan bir regexp sağlamak için bir yapılandırma var. Eğer regexp eşleşirse, GitLab eşleşmeyi kod kapsamı sonucu olarak kabul eder.

Bu nedenle, havuzunuzdaki Ayarlar> CI / CD'ye gidin, Genel boru hatları ayarları bölümünde Test kapsamı ayrıştırma ayarına gidin ve aşağıdaki regexp'yi kullanın:

toplam: \ s + \ (ifadeler \) \ s + (\ d + \ d + \%).

Hazırsınız! Deponuza genel bakış bölümüne gidin ve README'inize bakın:

Sonuç

Sıradaki ne? Muhtemelen sizde daha fazla test CI. Yapılarınızın dağıtımını otomatikleştirmek için CD'ye (Sürekli Dağıtım) da bakabilirsiniz. Belgeler GoDoc kullanılarak yapılabilir. Code_coverage_report ile bir kapsama raporu oluşturduğunuzu, ancak bunu CI'da kullanmadığınızı unutmayın. İşin, scp kullanarak HTML dosyasını bir web sunucusuna kopyalamasını sağlayabilirsiniz (SSH anahtarlarını kullanma hakkında bu belgeye bakın).

Bu makaleyi birlikte yazan Charles Francoise'a ve https://gitlab.com/pantomath-io/demo-tools adresine çok teşekkürler.

Şu anda Pantomath üzerinde çalışıyoruz. Pantomath, şirketinizin tüm seviyelerindeki boşlukları dolduran, performans için tasarlanmış modern, açık kaynaklı bir izleme çözümüdür. Altyapınızın iyiliği herkesin işidir. Projeye ayak uydurmak