
W poprzednim, poświęconym Kubernetesowi, odcinku pojawił się motyw automatyzacji powtarzalnych czynności. Jenkins – bohater dzisiejszego artykułu wynosi tę ideę na jeszcze wyższy poziom.
Uwaga! W tej serii zajmuję się opisowym przedstawieniem tematu, a celem jest zapoznanie z zagadnieniem w sposób luźny i zrozumiały dla nowicjusza. W związku z tym wiele elementów siłą rzeczy musi zostać pominiętych. Tych z was, którzy chcieliby się dowiedzieć więcej, zapraszam do źródeł na końcu artykułu.
Jednym z ciekawszych zagadnień w gramatyce języka angielskiego jest struktura:
to have something done
Powyższy zwrot tłumaczy się luźno na „mieć coś zrobione (przez kogoś)„, a lekcję jemu poświęconą z reguły rozpoczynamy gdybaniem co byśmy zrobili po wygraniu milionów na loterii.
Jeden uczeń opowiada o wymarzonym samochodzie, inny o wycieczce dookoła świata albo o prywatnej wyspie. Kiedy temat zaczyna się wyczerpywać, nauczyciel zagaduje o różne przyziemne rzeczy, które teraz trzeba wykonywać samemu, ale będąc bogaczem moglibyśmy mieć od nich „swoich ludzi”. Dla przykładu:
If I were rich…
- I would have my dinner cooked by a personal chef.
- I would have my lawn mowed by my own gardener.
- I would have my guests welcomed by a hired doorman.
W dzisiejszym odcinku zajmiemy się właśnie tymi aspektami tworzenia aplikacji, które są monotonne, powtarzalne i najchętniej oddelegowalibyśmy je „swoim ludziom”.

Będąc stereotypowym lordem z początku ubiegłego wieku, z pewnością w swej rozległej posiadłości potrzebowałbym woźnicy i koniuszego dbających o mój transport. Do tego ogrodników zajmujących się terenami zielonymi, kucharek przygotowujących posiłki i guwernantek sprawujących opiekę nad dziećmi. A to zaledwie początek listy! Dalej dochodzą nieodzowne pokojówki i kawiarki i odźwierni i praczki i dozorcy i gajowi itd.
Sporo tego. Ja, jako jaśnie panujący i miłościwy pan na włościach nie miałbym ani czasu, ani możliwości, a przede wszystkim ochoty, aby codziennie ogarniać całe to towarzystwo pilnując czy sumiennie i terminowo wykonują swoje obowiązki.
Do tego potrzebowałbym lokaja: Jana.

„Jan” to w Polsce jedno z najpopularniejszych imion i jakoś się tak przyjęło, że przylgnęło do kamerdynerów. Klasyczny „Jan” z żartów i anegdot to wierny sługa, który wyręcza swojego pana we wszystkich niewdzięcznych obowiązkach.
Na zachodzie sytuacja wygląda podobnie,
aczkolwiek zamiast imienia „Jan” jest „Jenkins”.
Do zadań Jana, czy też Jenkinsa, należało podawanie panu posiłków i napojów, zarządzanie domowym budżetem, pomoc w zakresie bezpieczeństwa dworu i rodziny, oraz rzecz jasna: nadzór nad pozostałymi członkami personelu.
Co należy zauważyć, lokaj nie zajmował się tymi sprawami osobiście tylko oddelegowywał je odpowiednim służącym. Szofer zawoził kucharki na targ w celu nabycia produktów spożywczych. Zwiędłe kwiaty były zastępowane nowymi po tym jak Jenkins informował o zaistniałej potrzebie pokojówkę, a ta ogrodnika.
Jenkins sam w sobie niewiele robił,
za to dystrybuował i nadzorował pracę pozostałych sług.

Będąc stereotypowym programistą z początku tego wieku z pewnością na swoim komputerze potrzebowałbym jakiegoś managera projektu, np. Mavena. Przydałby się Git do wersjonowania kodu i GitHub w celu jego współdzielenia z resztą zespołu. W fazie wdrożeniowej nieoceniona byłaby pomoc ze strony Dockera: jego obrazów i kontenerów. Na sam koniec mógłbym nawet chcieć skorzystać z rzadszych rozwiązań np. SonarQube oceniających jakość napisanego kodu.
Sporo tego. Ja, jako jaśnie panujący i miłościwy pan na włościach nie miałbym ani czasu, ani możliwości, a przede wszystkim ochoty, aby codziennie ogarniać całe to towarzystwo pilnując czy sumiennie i terminowo wykonują swoje obowiązki.
Do tego potrzebowałbym lokaja: Areczka.

Zara, zara! Jakiego Areczka? A gdzie Jenkins?
Kiedy już zainstalujemy sobie Jenkinsa to w naszej przeglądarce, na localhoscie, pod domyślnym portem 8080 pojawi nam się jego panel sterowania w formie webowej aplikacji.
Problem leży w tym, że taki „świeży” Jenkins niewiele potrafi.
Sam lokaj, bez pomocy reszty służących może otworzyć drzwi gościom, nalać im jakiegoś napoju, zabawić rozmową i w sumie tyle. Podobnie jest z czystą instancją Jenkinsa.
Wobec tego, dlaczego to rozwiązanie jest takie popularne?

Ażeby „Areczek” stał się Jenkinsem i mógł robić coś więcej poza „parzeniem herbaty” potrzebuje personelu: Gita, Mavena, Dockera itp. Ale aby mógł się z nimi komunikować, niezbędne będzie wzbogacenie instancji naszego lokaja o adekwatne rozszerzenia.
Ok, no to mamy Jenkinsa,
mamy pluginy, mamy zewnętrzne aplikacje.
Co nam to daje?

Jenkins posiada opcję tworzenia tzw. „pipeline’ów” czyli swoistych linii produkcyjnych gdzie z jednej strony wkładamy surowy kod, a z drugiej wyciągamy świeżutką, przetestowaną, pachnącą i jeszcze cieplutką aplikację.
Taki „pajplajn” to kawałek kodu* podzielony na kroki/fazy (ang. stage), który, jedno po drugim (tudzież równolegle w osobnych wątkach), wykonuje umieszczone weń polecenia – zazwyczaj przepuszczając kod przez kolejnych „służących”.
(*) Pisany w Groovy, języku wywodzącym się z Javy, ale skierowanym w potrzeby DevOps. Tak przy okazji – to już trzeci raz w tym cyklu jak spotykam się z Groovym (Gradle i Spock też go używają) więc jak to mówią: „do trzech razy szuka” – już wiem na nauce jakiego drugiego języka spędzę nadchodzące wakacje.
stages {
stage('Checkout') {
steps {
git 'https://github.com/repo.git'
}
}
stage('Build') {
steps {
sh 'mvn clean package'
}
}
stage('Test') {
steps {
sh 'mvn test'
}
}
stage('Build Docker') {
steps {
script {
def app = docker.build
("${env.DOCKERHUB_REPO}:
${env.BUILD_NUMBER}")
}
}
}
}
Powyższy przykład najpierw pobiera kod z GitHuba (Checkout), potem buduje projekt przy użyciu Mavena (Build), testuje (Test), a następnie tworzy dockerowy obraz (Build Docker).
Oczywiście nic nie stoi na przeszkodzie aby to jakoś zaplanować – powyższa robota może być automatycznie wykonywana w każdy wtorek o 5 rano. Albo jak tylko GitHub wyśle Jenkinsowi powiadomienie, że wpadł nowy commit.

CI/CD
W tym miejscu wypadałoby wyjaśnić powyższe skróty, które nawet częściej od samego Jenkinsa widnieją w ofertach pracy. Otóż, Jenkins to tylko jedno z wielu (aczkolwiek najbardziej znane) narzędzi do obsługi CI/CD na rynku i nie każdy musi tworzyć automatyzacje właśnie za pomocą tego lokaja. Skrótowiec „CI/CD” jest znacznie bardziej uniwersalny.
- CI jako Continuous Integration (Ciągła Integracja) to idea polegająca na tworzeniu pipeline’a kończącego się po fazie testów. Integracja/łączenie starego kodu z nowym. Czyli kiedy robimy git commit + push to cały projekt jest automatycznie budowany i odpalane są wszystkie testy (ale jak chociaż jeden nie przejdzie to cały proces jest przerywany!)
- CD jako Continuous Delivery (Ciągłe Dostarczanie) to w sumie to samo co powyżej, ale ubogacone o np. dockerowe obrazy, gotowe do wskoczenia na produkcję.
- CD jako Continuous Deployment (Ciągłe Wdrażanie) różni się od poprzednika tym, że nowy build automatycznie zastępuje stary (już na produkcji) – jest to najwygodniejsza opcja, gdyż automatyzujemy CAŁY proces (ale też najłatwiej coś zepsuć – pod koniec nikt nie musi tego obejrzeć i zatwierdzić)

Jenkins jest w rzeczy samej fantastycznym narzędziem pomagającym nam pozbyć się tych mniej fascynujących elementów pracy programisty. Ale, jak to już zaznaczyłem wyżej – NIE JEDYNYM.
Jak przyjrzycie się bliżej usługom oferowanym przez największych dostawców chmurowych to z pewnością znajdziecie tam bliźniacze rozwiązania, idealnie wpasowane w ofertę. Są łatwiejsze w użyciu, szybsze, pewniejsze i… płatne.
Jeśli miałbym wam polecić coś innego – coś co przy minimalnym wysiłku i zerowym nakładzie finansowym pomoże rozpocząć przygodę z CI/CD to bez wątpienia byłyby to
GitHub Actions
Konto na GitHubie jest darmowe, a sam GitHub na tyle popularny, że trudno znaleźć nawet początkującego deva który nie miałby tam swojego repozytorium. Do tego nie trzeba nic instalować u siebie, bo wszystko dzieje się na serwerach GH.
Podczas gdy Jenkins operuje na pipeline’ach pisanych w Groovym, GitHubowe automatyzacje (nazywane „workflows„) są tworzone w plikach .yml* z użyciem składni podobnej do tej którą znamy choćby z Kubernetesowych deploymentów.
(*) Tak na marginesie, Jenkinsowe pipe’y są również przechowywane w tzw. Jenkinsfile w katalogu projektu przez co są jego integralną częścią, a nie jakimś odległym bytem w bazie należącej do zewnętrznej aplikacji.
Przykładowy workflow, może wyglądać jak w kodzie poniżej i nie trzeba być orłem z anglika żeby domyśleć się co tam się dzieje:
name: MyWorkflow
on: [push, workflow_dispatch]
jobs:
greet:
runs-on: ubuntu-latest
steps:
- name: Print Greeting
run: echo "Good morning!"
prepare-environment:
runs-on: ubuntu-latest
steps:
- name: Get Code
uses: actions/checkout@v3
- name: Install JDK
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
Największym plusem GitHub Actions są… no właśnie te „Actions” czyli już sporządzone gotowce z najpopularniejszymi czynnościami. W powyższym przykładzie wystarczy, że skorzystamy z akcji instalującej Javę w podanej wersji (setup-java@v4) i nic więcej nas nie interesuje. Natomiast to samo w Jenkinsie byłoby nieco bardziej skomplikowane:
def javaHome =
tool name: 'JDK 17', type: 'jdk'
env.JAVA_HOME = javaHome
env.PATH = "${javaHome}/bin:${env.PATH}"
Jednocześnie, wciąż miejmy na uwadze, że Jenkins to projekt open-source z którego każdy może korzystać bezpłatnie. Jest niezależny od korporacji i używanej platformy czy języka programowania. Tymczasem GH Actions wywodzi się z Microsoftu i działa na jego serwerach, a liczba dziennych użyć jest ograniczona (na bezpłatnym koncie).

Na dzisiaj tyle i jak zwykle – dziękuję za uwagę. Zainteresowanych głębszym wejściem w temat automatyzacji odsyłam do źródeł poniżej.
Zapraszam was również do kolejnego odcinka serii, gdzie „spojrzymy w chmury” i sprawdzimy ofertę Amazon Web Services (AWS).
Źródła:
Jenkins Tutorial YT/ANG
Vlog Przemka Bykowskiego: Jenkins YT/POL
Kurs Jenkins na Udemy (płatne) ANG
Blog Przemka Bykowskiego: CI/CD POL
Wprowadzenie do GitHub Actions YT/ANG
Kurs Git + GitHub Actions na Udemy (płatne) ANG