Skip to content
Snippets Groups Projects
README.md 19.28 KiB

GitLab CI template for Python

This project implements a generic GitLab CI template for Python.

It provides several features, usable in different modes (by configuration).

Usage

In order to include this template in your project, add the following to your gitlab-ci.yml:

include:
  - project: 'to-be-continuous/python'
    ref: '5.0.0'
    file: '/templates/gitlab-ci-python.yml'

Global configuration

The Python template uses some global configuration used throughout all jobs.

Name description default value
PYTHON_IMAGE The Docker image used to run Python
⚠️ set the version required by your project
python:3
PYTHON_PROJECT_DIR Python project root directory .
PYTHON_BUILD_SYSTEM Python build-system to use to install dependencies, build and package the project (see below) none (auto-detect)
PIP_INDEX_URL Python repository url none
PIP_OPTS pip extra options none
PYTHON_EXTRA_DEPS Python extra sets of dependencies to install
For Setuptools or Poetry only
none
PYTHON_REQS_FILE Main requirements file (relative to $PYTHON_PROJECT_DIR)
For Requirements Files build-system only
requirements.txt
PYTHON_EXTRA_REQS_FILES Extra dev requirements file(s) to install (relative to $PYTHON_PROJECT_DIR) requirements-dev.txt

The cache policy also makes the necessary to manage pip cache (not to download Python dependencies over and over again).

Multi build-system support

The Python template supports the most popular dependency management & build systems.

By default it tries to auto-detect the build system used by the project (based on the presence of pyproject.toml and/or setup.py and/or requirements.txt), but the build system might also be set explicitly using the $PYTHON_BUILD_SYSTEM variable:

Value Build System (scope)
none (default) or auto The template tries to auto-detect the actual build system
setuptools Setuptools (dependencies, build & packaging)
poetry Poetry (dependencies, build, test & packaging)
pipenv Pipenv (dependencies only)
reqfile Requirements Files (dependencies only)

⚠️ You can explicitly set the build tool version by setting $PYTHON_BUILD_SYSTEM variable including a version identification. For example PYTHON_BUILD_SYSTEM="poetry==1.1.15"

Jobs

py-package job

This job allows building your Python project distribution packages.

It is bound to the build stage, it is disabled by default and can be enabled by setting $PYTHON_PACKAGE_ENABLED to true.

Lint jobs

py-pylint job

This job is disabled by default and performs code analysis based on pylint Python lib. It is activated by setting $PYLINT_ENABLED to true.

It is bound to the build stage, and uses the following variables:

Name description default value
PYLINT_ARGS Additional pylint CLI options none
PYLINT_FILES Files or directories to analyse none (by default analyses all found python source files)

This job produces the following artifacts, kept for one day:

  • Code quality json report in code climate format.
  • Pylint report for SonarQube (if SONAR_URL is defined).

Test jobs

The Python template features four alternative test jobs:

  • py-unittest that performs tests based on unittest Python lib,
  • or py-pytest that performs tests based on pytest Python lib,
  • or py-nosetest that performs tests based on nose Python lib,
  • or py-compile that performs byte code generation to check syntax if not tests are available.

py-unittest job

This job is disabled by default and performs tests based on unittest Python lib. It is activated by setting $UNITTEST_ENABLED to true.

In order to produce JUnit test reports, the tests are executed with the xmlrunner module.

It is bound to the build stage, and uses the following variables:

Name description default value
UNITTEST_ARGS Additional xmlrunner/unittest CLI options none

This job produces the following artifacts, kept for one day:

  • JUnit test report (using the xmlrunner module)
  • code coverage report (cobertura xml format).

⚠️ code coverage report artifact is disabled, due to a deprecated syntax, see Activate code coverage report artifact

⚠️ create a .coveragerc file at the root of your Python project to control the coverage settings.

Example:

[run]
# enables branch coverage
branch = True
# list of directories/packages to cover
source =
    module_1
    module_2

py-pytest job

This job is disabled by default and performs tests based on pytest Python lib. It is activated by setting $PYTEST_ENABLED to true.

It is bound to the build stage, and uses the following variables:

Name description default value
PYTEST_ARGS Additional pytest or pytest-cov CLI options none

This job produces the following artifacts, kept for one day:

  • JUnit test report (with the --junit-xml argument)
  • code coverage report (cobertura xml format).

⚠️ code coverage report artifact is disabled, due to a deprecated syntax, see Activate code coverage report artifact

⚠️ create a .coveragerc file at the root of your Python project to control the coverage settings.

Example:

[run]
# enables branch coverage
branch = True
# list of directories/packages to cover
source =
    module_1
    module_2

py-nosetest job

This job is disabled by default and performs tests based on nose Python lib. It is activated by setting $NOSETESTS_ENABLED to true.

It is bound to the build stage, and uses the following variables:

Name description default value
NOSETESTS_ARGS Additional nose CLI options none

By default coverage will be run on all the directory. You can restrict it to your packages by setting NOSE_COVER_PACKAGE variable. More info

This job produces the following artifacts, kept for one day:

  • JUnit test report (with the --with-xunit argument)
  • code coverage report (cobertura xml format + html report).

⚠️ code coverage report artifact is disabled, due to a deprecated syntax, see Activate code coverage report artifact

⚠️ create a .coveragerc file at the root of your Python project or use nose CLI options to control the coverage settings.

py-compile job

This job is a fallback if no unit test has been setup ($UNITTEST_ENABLED and $PYTEST_ENABLED and $NOSETEST_ENABLED are not set), and performs a compileall.

It is bound to the build stage, and uses the following variables:

Name description default value
PYTHON_COMPILE_ARGS compileall CLI options *

Activate code coverage report artifact

Code coverage report artifact is disabled, due to a deprecated syntax.

In order to activate code coverage report artifact, you need to override your actual unit test job depending on our GitLab version.

Here is an example with py-pytest job (change to py-unittest or py-nosetests depending on your unit tests library):

  • for GitLab < 14.10:
py-pytest:
  artifacts:
    reports:
      cobertura: $PYTHON_PROJECT_DIR/reports/coverage.xml
  • for GitLab >= 14.10:
py-pytest:
  artifacts:
    reports:
      coverage_report:
        ​coverage_format: cobertura
        path: ​$PYTHON_PROJECT_DIR/reports/coverage.xml

SonarQube analysis

If you're using the SonarQube template to analyse your Python code, here is a sample sonar-project.properties file:

# see: https://docs.sonarqube.org/latest/analysis/languages/python/
# set your source directory(ies) here (relative to the sonar-project.properties file)
sonar.sources=.
# exclude unwanted directories and files from being analysed
sonar.exclusions=**/test_*.py

# set your tests directory(ies) here (relative to the sonar-project.properties file)
sonar.tests=.
sonar.test.inclusions=**/test_*.py

# tests report: generic format
sonar.python.xunit.reportPath=reports/unittest/TEST-*.xml
# coverage report: XUnit format
sonar.python.coverage.reportPaths=reports/coverage.xml

More info:

py-bandit job (SAST)

This job is disabled by default and performs a Bandit analysis.

It is bound to the test stage, and uses the following variables:

Name description default value
BANDIT_ENABLED Set to true to enable Bandit analysis none (disabled)
BANDIT_ARGS Additional Bandit CLI options --recursive .

This job outputs a textual report in the console, and in case of failure also exports a JSON report in the reports/ directory (relative to project root dir).

py-safety job (dependency check)

This job is disabled by default and performs a dependency check analysis using Safety.

It is bound to the test stage, and uses the following variables:

Name description default value
SAFETY_ENABLED Set to true to enable Safety job none (disabled)
SAFETY_ARGS Additional Safety CLI options --full-report

This job outputs a textual report in the console, and in case of failure also exports a JSON report in the reports/ directory (relative to project root dir).

py-trivy job (dependency check)

This job is disabled by default and performs a dependency check analysis using Trivy.

It is bound to the test stage, and uses the following variables:

Name description default value
PYTHON_TRIVY_ENABLED Set to true to enable Trivy job none (disabled)
PYTHON_TRIVY_ARGS Additional Trivy CLI options --vuln-type library