Idi alati i GitLab - kako napraviti neprekidnu integraciju kao šef

Fotografirao Todd Quackenbush na Unsplash

U Pantomathu koristimo GitLab za svoj razvojni rad. Svrha ovog rada nije predstaviti GitLab i sve njegove karakteristike, već predstaviti kako koristimo te alate kako bismo olakšali svoj život.

Pa o čemu se radi? Da biste automatizirali sve što je povezano s vašim razvojnim projektom i omogućili vam da se usredotočite na svoj kôd. Pokrivat ćemo obloge, testove jedinica, utrku podataka, sredstva za zaštitu od pamćenja, pokrivenost koda i izgradnju.

Sav kod prikazan u ovom postu dostupan je na https://gitlab.com/pantomath-io/demo-tools. Zato slobodno nabavite spremište i upotrijebite oznake za navigaciju u njemu. Repozitorij treba biti smješten u src mapi vaše $ GOPATH:

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

Idi alati

Srećom, Go dolazi s puno korisnih alata za izgradnju, testiranje i provjeru koda. Zapravo je sve tamo. Samo ćemo dodati dodatne alate kako bismo ih lijepili. Ali prije nego što odemo tamo, moramo ih uzeti jednu po jednu i vidjeti što rade.

Popis paketa

Vaš go projekt je kolekcija paketa, kako je opisano u službenom dokumentu. Većina sljedećih alata nalazit će se s tim paketima, pa je prva naredba koja nam treba je način za popis paketa. Nadamo se da ćete pokriti naša leđa s potkomandom lista (pročitajte dobar priručnik i ovaj odličan post od Davea Cheneyja):

$ go list. / ...

Imajte na umu da želimo izbjeći primjenu naših alata na vanjske resurse i ograničiti ih na naš kod. Stoga se moramo riješiti direktorija dobavljača:

$ go list. / ... | grep -v / dobavljač /

otpaci od prediva

Ovo je prvi alat koji koristimo kod: vezica. Njegova uloga je osigurati da kôd poštuje stil koda. Ovo možda zvuči kao neobavezni alat ili barem „lijepo za imati“, ali zaista pomaže u održavanju dosljednog stila vašeg projekta.

Ova linija nije samostalna, pa je morate zgrabiti i instalirati je ručno (vidi službeni dokument).

Upotreba je prilično jednostavna: pokrećete je samo na paketima vašeg koda (možete i usmjeriti .go datoteke):

$ golint -set_exit_status $ (idi na listu. / ... | grep -v / dobavljač /)

Imajte na umu opciju -set_exit_status. Golint prema zadanim postavkama ispisuje samo stilske probleme i vraća se (sa povratnim kodom 0), tako da CI nikada ne smatra da je nešto pošlo po zlu. Ako navedete -set_exit_status, povratni kôd iz golinta bit će različit od 0 ako se pojavi bilo kakav problem sa stilom.

Jedinica test

Ovo su najčešći testovi koje možete pokrenuti na svom kodu. Za svaku .go datoteku moramo imati povezanu datoteku _test.go koja drži jedinice testova. Testove za sve pakete možete pokrenuti sljedećom naredbom:

$ go test -ort $ (go list. / ... | grep -v / dobavljač /)

Trka podataka

Obično je to teško pokrivati, ali alat go ima ga zadano (ali dostupan samo na linux / amd64, freebsd / amd64, darwin / amd64 i windows / amd64). Više informacija o utrci podataka potražite u ovom članku. U međuvremenu, evo kako to pokrenuti:

$ go test -race -short $ (go list. / ... | grep -v / dobavljač /)

Dezinfekcija pamćenja

Clang ima lijep detektor za neinicijalizirane čitanja koji se naziva MemorySanitizer. Alat za testiranje go je dovoljno ljubazan za interakciju s ovim Clang modulom (čim ste na linux / amd64 host i koristite nedavnu verziju Clang / LLVM (> = 3.8.0). Ova naredba je kako to pokrenuti:

$ go test -msan -short $ (go list. / ... | grep -v / dobavljač /)

Obuhvat koda

Ovo je također potrebno za procjenu zdravlja vašeg koda i da vidite koji je dio koda pod jedinstvenim testovima, a koji nije. Rob Pike napisao je cjelovit post o toj temi.

Da bismo izračunali omjer pokrivenosti koda, moramo pokrenuti sljedeću skriptu:

$ PKG_LIST = $ (idi na listu. / ... | grep -v / dobavljač /)
$ za paket u $ {PKG_LIST}; čini
    go test -covermode = count -coverprofile "cover / $ {package ## * /}. cov" "$ paket";
učinio
$ rep -q -n +2 poklopac / *. cov >> pokrov / pokrivanje.cov
$ go cover cover -func = cover / pokrivenost.cov

Ako želimo dobiti izvješće o pokrivanju u HTML formatu, trebamo dodati sljedeću naredbu:

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

Izgraditi

Posljednje, ali ne najmanje bitno, nakon što je kod u potpunosti testiran, možda ćemo ga htjeti sastaviti da bismo napravili surf, a možemo izgraditi radni binarni zapis.

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

Makefile

git tag: init-makefile

Fotografija Matt Artza na Unsplash-u

Sada imamo sve alate koje možemo koristiti u kontekstu kontinuirane integracije, možemo ih sve zamotati u Makefile i imati dosljedan način da ih nazovemo.

Svrha ovog dokumenta nije predstavljanje izrade, ali možete se obratiti službenoj dokumentaciji kako biste saznali više o tome.

PROJECT_NAME: = "demo-alati"
PKG: = "gitlab.com/pantomath-io/$(PROJECT_NAME)"
PKG_LIST: = $ (popis igara $ {PKG} / ... | grep -v / dobavljač /)
GO_FILES: = $ (shell shell. -Name '* .go' | grep -v / dobavljač / | grep -v _test.go)
.PHONY: svi dep izraditi čistu probu za pokrivanje pokrovahtmlhtml
sve: graditi
lint: ## Obložite datoteke
 @golint -set_exit_status $ {PKG_LIST}
test: ## Pokreni unittestove
 @go test -sort $ {PKG_LIST}
utrka: dep ## Pokrenite detektor utrke podataka
 @go test -race -sort $ {PKG_LIST}
msan: dep ## Pokrenite sanitarni program
 @go test -msan -short $ {PKG_LIST}
pokrivenost: ## Stvori izvješće o pokrivanju globalnog koda
 ./tools/coverage.sh;
coverhtml: ## Generiranje izvješća o pokrivanju globalnog koda u HTML-u
 ./tools/coverage.sh html;
dep: ## Nabavite ovisnosti
 @go get -v -d. / ...
build: dep ## Izradite binarnu datoteku
 @go sastaviti -i -v $ (PKG)
čisto: ## Ukloni prethodnu verziju
 @rm -f $ (PROJECT_NAME)
pomoć: ## Prikaz ovog zaslona pomoći
 @grep -h -E '^ [a-zA-Z _-] +:. *? ##. * $$' $ (MAKEFILE_LIST) | awk 'POČETI {FS = ":. *? ##"}; {printf "\ 033 [36m% -30s \ 033 [0m% s \ n", $$ 1, $$ 2} '

Što sada imamo? Jedan cilj za sve prethodno predstavljene alate i još 3 cilja za:

  • ugradnja ovisnosti (dep);
  • vođenje projekta (čisto);
  • neka lijepa i sjajna pomoć (pomoć).

Imajte na umu da smo također trebali izraditi skriptu za rad na pokrivanju koda. To je zato što boli uvođenje petlje nad datotekama u Makefileu. Dakle, rad se obavlja u bash skripti, a Makefile samo pokreće ovu skriptu.

Makefile možete pokušati sa sljedećim naredbama:

$ pomoć
$ make lint
$ pokriti

Kontinuirana integracija

git tag: init-ci

Fotografija Maxa Panamá na Unsplash-u

Sada su alati na mjestu i možemo pokrenuti razne testove na našem kodu, željeli bismo ih automatizirati, u vašem spremištu. Srećom, GitLab nudi CI cjevovode upravo za to. A postava za to je prilično jednostavna: sve što stvorite je .gitlab-ci.yml datoteka u korijenu spremišta.

Kompletna dokumentacija za ovu Yaml datoteku predstavlja sve mogućnosti, ali možete započeti s ovim .gitlab-ci.yml:

slika: golang: 1.9
cache:
  staze:
    - / apt-cache
    - /go/src/github.com
    - /go/src/golang.org
    - /go/src/google.golang.org
    - /go/src/gopkg.in
faze:
  - test
  - graditi
before_script:
  - mkdir -p /go/src/gitlab.com/pantomath-io / go / src / _ / gradi
  - cp -r $ CI_PROJECT_DIR /go/src/gitlab.com/pantomath-io/pantomath
  - ln -s /go/src/gitlab.com/pantomath-io / go / src / _ / gradi / pantomath-io
  - make dep
unit_tests:
  faza: test
  skripta:
    - napraviti test
race_detector:
  faza: test
  skripta:
    - napraviti utrku
memory_sanitizer:
  faza: test
  skripta:
    - napraviti msan
code_coverage:
  faza: test
  skripta:
    - osigurati pokrivenost
code_coverage_report:
  faza: test
  skripta:
    - napravi coverhtml
  samo:
  - ovladati; majstorski
lint_code:
  faza: test
  skripta:
    - napraviti lint
izgraditi:
  faza: graditi
  skripta:
    - izraditi

Ako razbijete datoteku, evo nekoliko objašnjenja njenog sadržaja:

  • Prva stvar je odabrati koja će se Docker slika koristiti za pokretanje CI-ja. Krenite do Docker Hub-a da odaberete pravu sliku za svoj projekt.
  • Zatim odredite neke mape ove slike u predmemoriranju. Cilj je izbjeći preuzimanje istog sadržaja nekoliko puta. Nakon što posao bude dovršen, navedeni putovi će se arhivirati, a sljedeći će posao koristiti istu arhivu.
  • Definirate različite faze koje će grupirati vaše poslove. U našem slučaju imamo dvije faze (koje treba obraditi tim redoslijedom): testirati i izgraditi. Mogli bismo imati i druge faze, poput raspoređivanja.
  • Odjeljak before_script definira naredbe koje se pokreću u Docker spremniku neposredno prije nego što se posao zaista obavi. U našem kontekstu naredbe samo kopiraju ili povezuju spremište raspoređeno u $ GOPATH i instaliraju ovisnosti.
  • Zatim dolaze stvarni poslovi pomoću ciljeva Makefile. Imajte na umu poseban slučaj za code_coverage_report gdje je izvršenje ograničeno na glavnu granu (na primjer, ne želimo ažurirati izvješće o pokrivanju koda iz grana značajki).

Dok počinimo / potisnemo .gitlab-ci.yml datoteku u spremište, CI se automatski pokreće. I cjevovod ne uspijeva. Kako to?

Posao lint_code ne uspijeva jer ne može pronaći binarni binar:

$ make lint
make: golint: Naredba nije pronađena
Makefile: 11: nije uspio recept za ciljno "vlakno"
make: *** [lint] Pogreška 127

Dakle, ažurirajte svoj Makefile da biste instalirali golint kao dio dep cilja.

Posao memory_sanitizer ne uspijeva jer se gcc žali:

$ make msan
# runtime / cgo
gcc: error: neprepoznati argument za -fsanitize = opcija: 'memory'
Makefile: 20: recept za ciljni 'msan' nije uspio
make: *** [msan] Pogreška 2

Ali zapamtite da trebamo koristiti Clang / LLVM> = 3.8.0 da bismo uživali u -msan opciji u naredbi test testa.

Ovdje imamo dvije mogućnosti:

  • ili u posao postavljamo Clang (koristeći before_script);
  • ili koristimo Docker sliku s Clangom prema zadanim postavkama.

Prva je opcija lijepa, ali podrazumijeva da se ovo postavljanje mora obaviti za svaki pojedinačni posao. To će trajati toliko dugo, trebali bismo to učiniti jednom zauvijek. Stoga preferiramo drugu opciju, što je dobar način igranja s GitLab Registry.

git oznaka: use-own-docker

Moramo stvoriti Dockerfile za spremnik (kao i obično: pročitajte službenu dokumentaciju za dodatne opcije o njemu):

# Osnovna slika: https://hub.docker.com/_/golang/
OD golang: 1.9
GLAVNI DIO Julien Andrieux 
# Instalirajte golint
ENV GOPATH / go
ENV PATH $ {GOPATH} / kanta: $ PATH
RUN go get -u github.com/golang/lint/golint
# Dodajte pogodan ključ za LLVM spremište
RUN wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | dodavanje tipke za apt -
# Dodajte LLVM pogodno spremište
RUN odjek "deb http://apt.llvm.org/stretch/ llvm-toolchain-stretch-5.0 main" | tee -a /etc/apt/sources.list
# Instalirajte clang iz LLVM spremišta
RUN apt-get update && apt-get install -y --no-install-preporučuje \
    clang-5,0 \
    && apt-očistiti \
    && rm -rf / var / lib / apt / liste / * / tmp / * / var / tmp / *
# Postavi Clang kao zadani CC
ENV set_clang /etc/profile.d/set-clang-cc.sh
RUN odjekuje "izvoz CC = clang-5.0" | tee -a $ {set_clang} && chmod a + x $ {set_clang}

Kontejner izgrađen na ovom Dockerfileu zasnivat će se na golang: 1.9 slici (onaj koji se navodi u datoteci .gitlab-ci.yml).

Dok smo kod njega, u spremnik postavljamo golint pa ga imamo na raspolaganju. Zatim slijedi službeni način instaliranja Clang 5.0 iz LLVM spremišta.

Sada imamo Dockerfile na mjestu, moramo napraviti sliku spremnika i učiniti je dostupnom za GitLab:

$ docker prijava register.gitlab.com
$ docker gradi -t register.gitlab.com/pantomath-io/demo-tools.
$ docker push register.gitlab.com/pantomath-io/demo-tools

Prva naredba vas povezuje u GitLab registar. Zatim sastavite sliku spremnika opisanu u Dockerfileu. I na kraju, gurnete ga u GitLab registar.

Pogledajte registar vašeg skladišta, vidjet ćete svoju sliku spremnu za upotrebu. A da bi CI koristio vašu sliku, trebate samo ažurirati .gitlab-ci.yml datoteku:

slika: golang: 1.9

postaje

slika: register.gitlab.com/pantomath-io/demo-tools:latest

Još posljednji detalj: trebate reći CI-u da koristi odgovarajući prevoditelj (tj. Varijabla CC okruženja), pa u datoteku .gitlab-ci.yml dodamo inicijalizaciju varijable:

izvoz CC = clang-5.0

Nakon što se izmjene izvrše, slijedeća obveza pokreće cjevovod, koji sada djeluje:

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

značke

git tag: init-značke

Fotografirao Jakob Owens na Unsplash-u

Sada su alati na mjestu, svako izvršavanje pokrenuće testni paket i vjerojatno ga želite pokazati, a to je legitimno :) Najbolji način za to je korištenje značaka, a najbolje mjesto za to je README datoteka.

Uredite ga i dodajte 4 sljedeće značke:

  • Status ugradnje: status posljednjeg cjevovoda na matičnoj grani:
[! [Status izrade] (https://gitlab.com/pantomath-io/demo-tools/badges/master/build.svg)] (https://gitlab.com/pantomath-io/demo-tools/commiss /ovladati; majstorski)
  • Izvješće o pokrivanju: postotak koda pokrivenog testovima
[! [Izvještaj o pokriću] (https://gitlab.com/pantomath-io/demo-tools/badges/master/coverage.svg)] (https://gitlab.com/pantomath-io/demo-tools/commiss /ovladati; majstorski)
  • Go Report Card:
[! [Go Report Card] (https://goreportcard.com/badge/gitlab.com/pantomath-io/demo-tools)] (https://goreportcard.com/report/gitlab.com/pantomath-io/ demo-alati)
  • Licenca:
[! [Licenca MIT] (https://img.shields.io/badge/License-MIT-brightgreen.svg)] (https://img.shields.io/badge/License-MIT-brightgreen.svg)

Izvješće o pokrivanju zahtjeva posebnu konfiguraciju. Morate reći GitLabu kako doći do tih podataka, obzirom da u CI postoji posao koji ga prikazuje kada se pokrene.
Postoji konfiguracija za pružanje GitLab regexp, koji se koristi u izlazu bilo kojeg posla. Ako se regexp podudara, GitLab smatra da je podudaranje rezultat pokrivanja koda.

Stoga krenite na Postavke> CI / CD u vašem spremištu, pomaknite se prema dolje do postavke Provjera pokrivenosti raščlanjivanja u odjeljku Opće postavke cjevovoda i upotrijebite sljedeći regexp:

Ukupno: \ s + \ (\ izvještaji) \ s + (\ d + \ d + \%.)

Spreman si! Krenite na pregled svog spremišta i pogledajte README:

Zaključak

Što je sljedeće? Vjerojatno više testova u CI. Možete i pogledati CD (Kontinuirana implementacija) kako biste automatizirali implementaciju vaših sastava. Dokumentacija se može obaviti pomoću GoDoc-a. Imajte na umu da generirate izvješće o pokrivanju s code_coverage_report, ali ga ne upotrebljavate u CI. Posao možete natjerati da kopirate HTML datoteku na web poslužitelj pomoću scp (pogledajte ovu dokumentaciju o tome kako koristiti SSH ključeve).

Veliko hvala Charlesu Francoiseu koji je napisao ovaj članak i https://gitlab.com/pantomath-io/demo-tools.

Trenutno radimo na Pantomathu. Pantomath je moderno rješenje za praćenje otvorenog koda, izgrađeno za postizanje performansi koje premošćuje praznine na svim razinama vaše tvrtke. Dobrobit vaše infrastrukture je posao svih. U tijeku s projektom