Ciągła integracja projektów Django za pomocą Jenkinsa

Jenkins to narzędzie do śledzenia wykonywanych zadań, do "ciągłej integracji" projektów. Aplikacja ta może śledzić wykonywanie zadań z crona, czy też sama wykonywać zadania jak np. testowanie i budowanie aplikacji gdy pojawi się nowa zmiana w repozytorium. Django może skorzystać z django-jenkins by zapewnić efektywną obsługę projektów Django w Jenkinsie. Django-Jenkins zapewnia informacje o pokryciu kodu testami, czy naruszenia pep8, pylint, pyflakes itd.

W tym artykule zaprezentuję jak zacząć z Jenkinsem odpalając go lokalnie dla lokalnego kodu. W wersjach "produkcyjnych" Jenkins obserwowałby jakieś repozytorium, czy współpracował z jakimś systemem do recenzowania kodu (np. Gerritem).

Jenkins

Na stronie Jenkinsa znajdziemy pakiety dla różnych systemów, jak i na samej górze listy plik WAR, który możemy pobrać i odpalić bez integrowania w system (choć mogą być potrzebne jakieś zależności... w szczególności JAVA ;))

  • Pobieramy Jenkins w pliku WAR.
  • Odpalamy go z konsoli za pomocą polecenia
    java -jar jenkins.war
  • Jenkins po chwili powinien uruchomić się. Dostępny będzie pod adresem http://localhost:8080/
Jenkins po uruchomieniu

Jenkins po uruchomieniu z dodanym przeze mnie pierwszym zadaniem

Główna cześć strony to lista zadań ("jobs") jakie Jenkins ma skonfigurowane (brak na początku). Po lewej mamy menu nawigacyjne. "Nowe" służy do dodawania nowych zadań. "Manage Jenkins" jak nazwa wskazuje pozwala konfigurować Jenkinsa. Pozwala także na instalacje wtyczek - a parę z nich musimy zainstalować.
Instalowanie wtyczek w Jenkinsie

Instalowanie wtyczek w Jenkinsie

Na potrzeby django-jenkins trzeba zainstalować dwie wtyczki - Violations i Cobertura. Na potrzeby testów warto też zainstalować File System SCM - pozwoli to podpiąć lokalny katalog z projektem Django w zadaniach. Jeżeli lista wtyczek jest pusta trzeba ją pobrać (powinien je pobrać po chwili przy przechodzeniu między zakładkami). Po instalacji potrzebny może być restart Jenkinsa by się pojawiły jako zainstalowane.

Dodawanie zadania dla projektu Django

Klikamy Nowe i tworzymy nowe zadanie. Podajemy nazwę i wybieramy typ - "Build a free-style software project". Jeżeli mamy już jakieś podobne zadanie możemy je skopiować.
Dodawanie nowego zadania

Dodawanie nowego zadania

Następnie konfigurujemy zadanie by coś konkretnego robiło:
Wskazujemy repozytorium lub ścieżkę do katalogu udającego repozytorium

Wskazujemy repozytorium lub ścieżkę do katalogu udającego repozytorium

Normalnie Jenkins obserwowałbym repozytorium. W ramach testowania i nauki możemy użyć wtyczki File System SCM, która pozwoli wybrać lokalną ścieżkę. Jenkins będzie sprawdzał czy coś się zmieniło w zawartości katalogu - i jeżeli tak to rozpocznie budowę zadania.
Konfiguracja wyzwalaczy dla zadania

Konfiguracja wyzwalaczy dla zadania

Poll SCM oznacza pobieranie repozytorium. Natomiast */30 * * * * oznacza pobieranie co 30 minut (można częściej).
Polecenia do wykonania przy budowaniu aplikacji

Polecenia do wykonania przy budowaniu aplikacji

Budowanie kodu to zazwyczaj instalacja zależności i odpalenie testów. W tym przypadku mam wszystko już zainstalowane w lokalnym systemie więc odpalam testy. Zamiast "manage.py test" używam "manage.py jenkins", który jest częścią django-jenkins (o tym dalej), który odpala testy i generuje raporty używane przez Jenkinsa.
Konfiguracja raportów pokrycia kodu testami

Konfiguracja raportów pokrycia kodu testami

Wtyczka Cobertura pozwoli wizualizować pokrycie kodu testami. Podajemy jako ścieżkę reports/coverage.xml. Same wyniki testów konfigurujemy tak:
Konfiguracja raportów z przebiegu testów

Konfiguracja raportów z przebiegu testów

Jako ścieżkę podajemy reports/junit.xml. Możemy także podpiąć raporty z naruszeń pep8, pylint, pyflakes (a także csslint i jslint). Wtyczkę Violations konfigurujemy tak:
Konfiguracja raportów naruszeń

Konfiguracja raportów naruszeń

Zadanie Jenkinsa jest już gotowe. Trzeba jeszcze skonfigurować django-jenkins w podpiętym projekcie Django.

Django-Jenkins

Aplikację instalujemy standardowo:
pip install django-jenkins
Dodamy do INSTALLED_APPS:
django_jenkins
Następnie dodajemy listę zadań jakie mają zostać wykonane. Podstawowe to:
JENKINS_TASKS = (
        'django_jenkins.tasks.with_coverage',
        'django_jenkins.tasks.django_tests',
        'django_jenkins.tasks.run_pep8',
        'django_jenkins.tasks.run_pyflakes',
    )
Musimy zainstalować także pep8, pylint i pyflakes. Projekt jest gotowy i wykonanie manage.py jenkins powinno odpalić testy i wygenerować raporty. Jeżeli to zadziała to w Jenkinsie też będzie działać.

Odpalanie testów wszystkich aplikacji w INSTALLED_APPS oraz Django to nie najlepsze rozwiązanie. Dla django-jenkins można zdefiniować PROJECT_APPS - listę naszych aplikacji, które chcemy testować. W INSTALLED_APPS umieszczamy aplikacje Djangowskie i inne aplikacje osób trzecich, których testować nie chcemy, np:

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.admin',
    'javascript_settings',
    'django_jenkins'
)
PROJECT_APPS = (
    'jsdemo',
    'testapp',
)
INSTALLED_APPS += PROJECT_APPS

Co ciekawego powie nam Jenkins?

Lista budów naszego zadania w Jenkinsie

Lista budów naszego zadania w Jenkinsie

Nasz testowy Jenkins co 30 minut powinien odpalać budowę podanego w zadaniu projektu Django. Każda budowa dostarcza nam różne informacje. Od podstawowych - czy się udała po raporty z testów, naruszeń, czy pokrycia kodu testami. Wchodząc na daną budowę zadania mamy do dyspozycji opcje takie jak:
  • Podgląd konsoli: przebieg z budowy. Jeżeli budowa się nie udała tutaj zazwyczaj znajdziemy przyczynę. Czasami jeżeli Jenkins ma zainstalować pakiety z pypi może to się nie udać (serwer pypi niedostępny) - wtedy budowa się nie uda nie z naszej winy. Wtedy trzeba ją ponowić (retrigger).
  • Coverage Report: raport pokrycia kodu testami. Zobaczymy, które części kodu są pokryte testami, a które nie. Zobaczymy też czy w pełni testujemy wszystkie conditionale/branche kodu
  • Violations: raporty (ze wskazaniem w plikach) naruszeń zasad, stylistyki kodu itp. (w zależności co jest skonfigurowane) - pep8, pylint, pyflakes standardowo.
Pylint/Pyflakes raportuje naruszenie - nieużyty import
Naruszenia zasad pep8 - najedź na wykrzyknik by zobaczyć szczegóły

Pokrycie kodu testami

Podgląd przebiegu budowy zadania

Więcej można znaleźć na django-jenkins Tutorial , czy Continuous Integration with Jenkins.

RkBlog

Django, 22 July 2012

Comment article
Comment article RkBlog main page Search RSS Contact