[PYTHON] Easy tox environment with Jenkins

at first

Do you guys test it? "Tox" that executes unit tests in Python in multiple environments. It's convenient, isn't it? If you create a CI environment with Jenkins, you can check the operation with multiple versions in one shot.

However, it takes a lot of time and effort to install pyenv and prepare multiple python environments. Therefore, it is an easy way to build an environment that uses tox in Jenkins.

The procedure is as follows.

  1. Build Jenkins with Docker
  2. Create a DockerFile for the container with Pyenv installed
  3. Create a Jenkins file that uses DockerFile
  4. Create tox.ini to get unit tests and coverage reports
  5. Place DockerFile, Jenkinsfile, tox.ini at the top of the repository
  6. Create a Pipeline job in Jenkins
  7. Build execution

Advance preparation

This time, I will mainly explain the part that dynamically generates the CI environment using Jenkisfile. Therefore, I will omit the construction of Docker environment and Jenkins. However, please be sure to build Jenkins under Docker environment. __

Build Jenkins with Docker

If you are in a Windows environment, you should build it by referring to the following page. https://qiita.com/sh1928kd/items/b248a8d48d16eaab9617

One point, when sharing a Docker socket in Ubuntu environment etc., please be careful about the socket authority of the socket on the host side. If you do not have execute permission from Jenkins side, an error will occur.

The version of Jenkins at the time of writing the article is "Jenkins 2.255".


Put in whatever you like. This time I want to display the result of Unit test and coverage report, so install "JUnit" and "Cobertura".

Create a DockerFile for the container with Pyenv installed

You should be able to build the environment with just the Jenkins file, When I tried to use pyenv when building multiple Python environments, it didn't work. Therefore, we will use DockerFile to build multiple Python environments.

FROM python:3.8

USER root
ENV HOME /root
# ENV HTTP_PROXY '{Proxy server address}'
# ENV HTTPS_PROXY '{Proxy server address'
# ENV FTP_PROXY '{Proxy server address}'

# RUN echo 'Acquire::http::Proxy "{Proxy server address}";' >> /etc/apt/apt.conf
# RUN echo 'Acquire::https::Proxy "{Proxy server address}";' >> /etc/apt/apt.conf
RUN apt-get update && apt-get upgrade -y \
 && apt-get install -y \
    git \
    make \
    build-essential \
    libssl-dev \
    zlib1g-dev \
    libbz2-dev \
    libreadline-dev \
    libsqlite3-dev \
    wget \
    curl \
    llvm \
    libncurses5-dev \
    libncursesw5-dev \
    xz-utils \
    tk-dev \
    libffi-dev \
    liblzma-dev \
 && git clone https://github.com/pyenv/pyenv.git $PYENV_ROOT

RUN echo 'eval "$(pyenv init -)"' >> ~/.bashrc && \
     eval "$(pyenv init -)"

RUN pyenv install 3.5.9
RUN pyenv install 3.6.2
RUN pyenv install 3.7.2
RUN pyenv install 3.8.2

RUN echo '3.5.9' >> .python-version
RUN echo '3.6.2' >> .python-version
RUN echo '3.7.2' >> .python-version
RUN echo '3.8.2' >> .python-version

Create a Jenkins file that uses a Dockerfile

Jenkinsfile is not difficult once you build the environment with Dockerfile

pipeline {
    agent { 
        dockerfile {
            filename 'Dockerfile'
            args '-u root:sudo'
    stages {
        stage('setup') {
            steps {
                sh 'pip install flake8'
                sh 'pip install tox'
                sh 'pip install tox-pyenv'
        stage('test') {
            steps {
                sh 'tox'
                //Get coverage
                cobertura coberturaReportFile: 'coverage.xml'
                //Get test results
                junit 'junit_reports/*.xml'

It might have been good to describe the contents of setup in DockerFile.

Create tox.ini to get unit tests and coverage reports

Write tox.ini. This time we will get a test report and a coverage report, so we have set it to output each report


envlist = py35, py36, py37, py38, flake8

python =
    3.8: py38
    3.7: py37
    3.6: py36
    3.5: py35

basepython = python
deps = flake8
commands = flake8 {Module name to analyze} tests

exclude = tests/*

setenv =
    PYTHONPATH = {toxinidir}
deps = 
commands =
    rm -rf junit_reports
    python -m xmlrunner discover -o junit_reports
    coverage erase
    coverage run --append setup.py test
    coverage report --omit='.tox/*'
    coverage xml --omit='.tox/*'

Place DockerFile, Jenkinsfile, tox.ini at the top of the repository

Basically, if it is a PYPI format project, it will have the following structure.


Create a Pipeline job in Jenkins

Push the completed script to Github etc.


Choose to create a new job,

  1. Enter the job name in item name
  2. Select a pipeline


On the settings screen

  1. Select "Pipeline script from SCM" as the definition
  2. Select "Git" for SCM
  3. Enter the repository path in the repository URL

Build execution


If you do "build execution" from the Jenkins job screen, you can build the environment from the Dockerfile and Jenkins will get the result of executing tox.


I introduced the environment to easily execute tox with Jenkins. I really wanted to build it with only Jenkinsfile, but I didn't understand the behavior around PATH, so I used a Dockerfile.

If you have a PyPI-style project structure, you can almost use it in this way, which makes it easier to build a test environment. In addition, since the raw environment is completed, there is an advantage that you should be aware of module registration omissions and dependent libraries.

Recommended Posts

Easy tox environment with Jenkins
Easy Jupyter environment construction with Cloud9
Easy deployment environment with gaffer + fabric
[Linux] Build a jenkins environment with Docker
Make your Python environment "easy" with VS Code
Easy Grad-CAM with pytorch-gradcam
Python environment with docker-compose
Easy debugging with ipdb
Virtual environment with Python 3.6
Easy TopView with OpenCV
From Kafka to KSQL --Easy environment construction with docker
Create an environment with virtualenv
[Co-occurrence analysis] Easy co-occurrence analysis with Python! [Python]
Minimal website environment with django
Install Python environment with Anaconda
Manage python environment with virtualenv
venv environment with windows powershell
Easy folder synchronization with Python
Build python3 environment with ubuntu 16.04
ML environment construction with Miniconda
Easy to make with syntax
Easy image classification with TensorFlow
Prepare python3 environment with Docker
Easy web scraping with Scrapy
Build python environment with direnv
Easy Python compilation with NUITKA-Utilities
Easy HTTP server with Python
Easy proxy login with django-hijack
Building a pyhon environment without using Anaconda (with easy startup)
Switch virtual environment with jupyter
Set environment variables with lambda-uploader
Building a kubernetes environment with ansible 2
Prepare pipenv environment with amazon Linux 2
Activate Anaconda's virtual environment with PowerShell
Easy time series prediction with Prophet
Get started with Python! ~ ① Environment construction ~
[Python] Easy parallel processing with Joblib
Be careful with easy method references
Easy Slackbot with Docker and Errbot
Build python virtual environment with virtualenv
Setup modern Python environment with Homebrew
ruby environment construction with aws EC2
Build Mysql + Python environment with docker
Create a virtual environment with Python!
Building a virtual environment with Python 3
Easy GUI app with Tkinter Text
Easy to install pyspark with conda
Build Flask environment with Dockerfile + docker-compose.yml
Easy Python + OpenCV programming with Canopy
Build PyPy execution environment with Docker
Easy email sending with haste python3
Bayesian optimization very easy with Python
Build IPython Notebook environment with boot2docker
Easy AWS S3 testing with MinIO
Automate environment construction with Shell Script
Easy Japanese font setting with matplotlib
Python3 environment construction with pyenv-virtualenv (CentOS 7.3)
Easy data visualization with Python seaborn.
Using Chainer with CentOS7 [Environment construction]
Easy with Slack using Bot #NowPlaying
Easy to draw graphs with matplotlib