{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## ![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n", "
\n", "

Inżynieria uczenia maszynowego

\n", "

6. Jenkins, część 2. [laboratoria]

\n", "

Tomasz Ziętkiewicz (2022)

\n", "
\n", "\n", "![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Plan na dziś\n", "1. Multibranch pipeline\n", "2. Pluginy\n", "3. Zadania" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Multibranch pipeline\n", " - Multibranch Pipeline to rodzaj projektu na Jenkinsie, który automatycznie obsługuje wiele gałęzi (branch) w repozytorium\n", " - W dominującym dziś sposobie utrzymywania i rozwoju kodu możemy wyróżnić:\n", " - gałąź główną (master branch) - tutaj znajduje się aktualna, gotowa do wydania (opulbikowania/wdrożenia) wersja kodu\n", " - gałęzie typu develop/feature/release/hotfix itp. ([tutaj](https://kamiljozwiak.net/gitflow-czyli-jak-korzystac-z-gita-i-nie-zwariowac/) przystępne wyjaśnienie czym się różnią), na których rozwijamy nasz kod/wprowadzamy nowe funkcjonalności/przygotowujemy wersje gotowe do włączenia do gałęzi master, naprawiamy błędy.\n", " - Gałęzi może być sporo i każdą z nich musimy przetestować, najlepiej automatycznie, przed zmergowaniem jej do gałęzi master\n", " - Świetnie nadaje się do tego własnie Multibranch pipeline\n", " - Nawet, jeśli pracujemy tylko na dwóch gałęziach jednocześnie (master i jedna dodatkowa) to i tak warto go zastosować\n", " - Projekt typu Multibranch pipeline automatycznie stworzy pod-projekty (joby) dla każdego (chyba, że ustawimy filtry) brancha znalezionego w podanym przez nas repozytorium" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Multibranch pipeline cd.\n", " - Żeby utworzyć projektu typu Multibranch, wybierz ten rodzaj przy tworzeniu projektu\n", " \n", " - Przy konfiguracji musimy jedynie podać namiary na repozytorium, w którym Jenkins ma szukać naszych branchy.\n", " - Robimy to w polu \"Branch Sources\". Możemy tutaj wybrać \"git\" albo \"gitea\" \n", " " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Multibranch pipeline cd.\n", "- Wybranie \"gitea\" ułatwi nam wybór repozytorium i doda informację o statusie builda w interfejsie Gitea oraz link z Jenkinsa do odpowiedniego brancha w Gitea\n", " " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Multibranch pipeline cd.\n", "- Po zapisaniu konfiguracji Jenkins utworzy joby dla każdej gałązi znalezionej w repozytorium.\n", " " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "- Żeby ograniczyć branche, dla których mają powstać projekty, możesz użyć \"Behaviours\" -> \"Add\" -> \"Filter by name\":\n", " " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ " - Zwróć uwagę:\n", " - Konfigurować można tylko główny projekt\n", " - Jeśli chcesz, żeby konfiguracja projektu Jenkinsowego dla danego brancha była inna niż dla pozostałych, musisz po prostu wprowadzić zmiany w Jenkinsfile na danym branchu.\n", " - Z założenia jednak, konfiguracja powinna być wspólna\n", " - W przypadku kopiowania artefaktów z projektu typu multibranch musisz w nazwie projektu źródłowego, z którego kopiujesz artefaky, zawrzeć również nazwę brancha, w fomracie:\n", " `nazwa-projektu/nazwa-brancha`, np.:\n", " ```Jenkinsfile\n", " copyArtifacts filter: '*', projectName: 'multibranch-hello-world/experiments/'\n", " ```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Pluginy\n", " - Wszsytkie pluginy można przeglądać tutaj: https://plugins.jenkins.io/\n", " - Instalacja przez administratora (poprzez prosty graficzny interfejs w konfiguracji Jenkinsa)\n", " - Po zainstalowaniu pojawiąją się nowe kroki (steps) dostępnę w pipeline albo nowe opcje konfiguracji\n", " - Git parameter plugin: https://plugins.jenkins.io/git-parameter/\n", " - Email extension plugin: https://plugins.jenkins.io/email-ext/\n", " " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Git parameter plugin\n", "- https://plugins.jenkins.io/git-parameter/\n", "- Dodaje parametr umożliwiający wybranie m.in. brancha z repozytorium\n", "```Jenkinsfile\n", " gitParameter branchFilter: 'origin/(.*)', defaultValue: 'master', name: 'BRANCH', type: 'PT_BRANCH'\n", "```\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Email extension plugin\n", "- https://plugins.jenkins.io/email-ext/\n", "- Umożliwia wysłanie emaila, np. z powiadomieniem o zakończonym buildzie\n", "```Jenkinsfile\n", "emailext body: 'Test Message', subject: 'Test Subject', to: 'test@example.com'\n", "```\n", "- Microsoft Teams ma swój własny plugin do powiadomień (https://plugins.jenkins.io/Office-365-Connector/), ale jest on zablokowany od strony Teams przez administratorów\n", "- Na szczęście, kanały Teams mają swój adres email. Adres stworzonego przeze mnie kanału [\"IUM powiadomienia z Jenkins\"](https://teams.microsoft.com/l/channel/19%3a503542f4a8b449f79ba1bd42348c4da1%40thread.tacv2/IUM%2520powiadomienia%2520z%2520Jenkins?groupId=39ed4bde-b916-4da3-921c-92d3c25f1f04&tenantId=73689ee1-b42f-4e25-a5f6-66d1f29bc092) na naszej grupie zajęciowej: e19191c5.uam.onmicrosoft.com@emea.teams.ms\n", "- Wysłanie na niego wiadomości email spowoduje pojawienie się jej na tym kanale" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Zadanie 1 [5 pkt] (termin: 2023-05-12)\n", "1. Stwórz na Jenkins projekt typu Multibranch pipeline o nazwie s123456-training\n", " Projekt ten powinien przeprowadzać trenowanie modelu korzystając z kodu przygotowanego na poprzednich zajęciach. Trenowanie powinno odbywać się wewnątrz kontenera docker. [2 pkt]\n", "2. Projekt powinien odpalać się automatycznie po zakończonym budowaniu projektu s123456-create-dataset i kopiować z niego zbiór danych [1 pkt]\n", "3. Po zakończeniu trenowania powstały model powinien zostać zarchiwizowany [1 pkt]\n", "\n", "5. Dodaj parametr umożliwiający przekazanie do skryptu trenującego parametrów trenowania. Najprościej zrobić to dodając parametr typu String i doklejać jego wartość do wywołania skryptu trenującego. [1 pkt]" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Zadanie 2 [15 pkt] (termin: 2023-05-12)\n", "1. Stwórz na Jenkins projekt typu Multibranch pipeline o nazwie s123456-evaluation.eg\n", " Projekt ten będzie przeprowadzał ewaluację modelu stworzonego w s123456-training na danych ze zbioru testującego [1 pkt]\n", "2. Ewaluacja polega na:\n", " - skopiowanie modelu z artefaktu z projektu training\n", " - wczytaniu tego modelu\n", " - dokonaniu predykcji na zbiorze testowym za pomocą wczytanego modelu i zapisanie wyników tej predykcji do pliku\n", " - wyliczeniu zbiorczych metryk (1-3 metryki) na zbiorze testującym (np. Accuracy, Micro-avg precission/recall, F1, RMSE - patrz [wykład 4. \"Metody ewaluacji\"])(https://git.wmi.amu.edu.pl/AITech/aitech-uma/src/branch/master/wyk/04_Metody_ewaluacji.ipynb) z przedmiotu Uczenie Maszynowe), \n", " - zapisaniu metryk do pliku\n", " - zarchiwizowaniu go\n", " [6 pkt]\n", "3. W celu śledzenia zmian wartości metryk, zapisuj wartości kumulatywnie w jednym pliku. Żeby to osiągnąć można: \n", " - zapisywać metryki w ścieżce zewnątrznej w stosunku do Jenkinsa (w innym przypadku mogą zostać nadpisane np. podczas checkout repozytorium) - tej opcji nie wykorzystamy\n", " - dopisywać metrykę do końca pliku skopiowanego z artefaktów poprzedniego builda (należy uczynić kopiowanie tego artefaktu opcjonalnym, żeby pierwszt build na danym branchu nie \"wywalił się\" przy próbie skopiowania artefaktów z nieistniejącego joba) [2 pkt]\n", "4. Mając skumulowane wartości metryk z wszystkich dotychczasowych buildów, stwórz wykres: na osi X numer builda, na osi Y wartość metryk(i). [2 pkt]\n", " Możesz w tym celu użyć:\n", " - pluginu [plot](https://plugins.jenkins.io/plot)\n", " - [Matplotlib](https://matplotlib.org/) - biblioteka pythonowa - w tym przypadku archiwizuj wygenerowany obrazek z wykresem\n", " - [Gnuplot](http://www.gnuplot.info/) - w tym przypadku archiwizuj wygenerowany obrazek z wykresem\n", "5. Projekt powinien odpalać się automatycznie po zakończonym trenowaniu (s123456-training) i kopiować model z artefaktów. Zauważ, że żeby odpalony projekt (s123456-evaluation) skopiował artefakty z odpowiedniego brancha (tego, który go odpalił), projekt s123456-evaluation musi być wywołany przez s123456-training z odpowiednią wartością parametru branch (patrz punkt 7.) [1 pkt]\n", "6. Dane testujące powinny być skopiowane z projektu s123456-create-dataset [1pkt]\n", "7. Dodaj parametry umożliwiające wybór:\n", " - gałęzi (branch) projektu s123456-training z której ma być skopiowany model. Można by tutaj użyć prostego parametru typu String, ale użyj łatwiejszego (w użytkowaniu) parametru typu \"Git parameter\" (patrz wyżej)[1 pkt]\n", " - numeru builda projektu s123456-training (\"Build selector for Copy artifact\", patrz zajęcia 3.) [1pkt]" ] } ], "metadata": { "author": "Tomasz Ziętkiewicz", "celltoolbar": "Slideshow", "email": "tomasz.zietkiewicz@amu.edu.pl", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "lang": "pl", "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.16" }, "slideshow": { "slide_type": "slide" }, "subtitle": "6.Jenkins-2[laboratoria]", "title": "Inżynieria uczenia maszynowego", "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": false, "sideBar": false, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": false, "toc_window_display": false }, "year": "2021" }, "nbformat": 4, "nbformat_minor": 4 }