Skip to content
README.md 4.32 KiB
Newer Older
Ivan Artiukhov's avatar
Ivan Artiukhov committed
# `ci/component/tox`
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
> A GitLab CI component for running tox commands in Python projects
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
## Getting Started
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
Add the CI component to the `.gitlab-ci.yml`:
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
```yaml
include:
Ivan Artiukhov's avatar
Ivan Artiukhov committed
  - component: "gitlab.arm.com/ci/component/tox@<version>"
Ivan Artiukhov's avatar
Ivan Artiukhov committed
```

Add a job that extends the `.tox` template to test the project using Tox:

```yaml
tox:
  extends: .tox
```

## Variables

The template has some environment variables that can customise the job behaviour.

### `ROOT`
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
To specify the root directory where 'tox.ini' is located:

```yaml
tox:
    extends: .tox
    variables:
        ROOT: "$CI_PROJECT_DIR"
```

### `VERSION`

Selects the Python version to run the job under:

```yaml
tox:
  extends: .tox
  parallel:
    matrix:
      TAG:
        - 3.12-slim-bookworm
        - 3.12-slim-bullseye
        - 3.12-alpine
```
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
### `VARIANT`
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
Describes the `Tox` testing environment to execute (`-e`):
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
```yaml
tox:
    extends: .tox
    parallel:
        matrix:
        - VARIANT:
            - py
            - debug
            - release
Ivan Artiukhov's avatar
Ivan Artiukhov committed
```
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Combine with VERSION to test each variant across multiple Python versions.

#### `TOX_WORK_DIR`

When using the `.tox` template, the `tox` work directory can be cached by adding the following to the `tox.ini`

```ini
[tox]
toxworkdir = {env:TOX_WORK_DIR:{toxinidir}/.tox}
Ivan Artiukhov's avatar
Ivan Artiukhov committed
```

Ivan Artiukhov's avatar
Ivan Artiukhov committed
#### `ROOT`
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
The location of the `tox.ini` for the `tox` testing.
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
Must be absolute, using `$CI_PROJECT_DIR` as a prefix.
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
#### `CACHE_PREFIX`
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
The prefix to add to the `tox` cache, which defaults to `tox-${VERSION}`.
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
This can be used to create different caches.
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
It will always be invalidated when `$ROOT/tox.ini` changes.
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
# YAML References
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
The `.tox` template provides a simple way to invoke `tox` in a job.
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
GitLab CI has a [`!reference`][gitlab-ci-reference] feature that allows parts of a template to be re-used in a fine grained way.
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
[gitlab-ci-reference]: https://docs.gitlab.com/ee/ci/yaml/yaml_optimization.html#reference-tags
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
It is recommended to use this feature to build up a custom `tox` job by using `!reference` to select parts of the `tox.yml` that are relevant.
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
Commonly, this is used to customise the `script` section of a job but still re-using parts of the `.tox` template script:
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
```yaml
  extends:
    - .tox
  before_script:
    - !reference [.tox-fragment, install]
    - tox run
```
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
#### Poetry

When using Poetry to manage developer dependencies the following is the recommended `tox.ini`:

```ini
[tox]
toxworkdir = {env:TOX_WORK_DIR:{toxinidir}/.tox}
isolated_build = true
envlist = py
passenv =
    CI
requires =
  tox-poetry-installer[poetry] == 1.0.0b1

[testenv]
description = "The default Python test environment, runs `pytest`"
require_locked_deps = true
poetry_dep_groups = test
commands =
    pytest {posargs}
setenv =
    PYTHONWARNDEFAULTENCODING = 1


[testenv:debug]
description = "Runs the test environment in Python development mode"
setenv =
    {[testenv]setenv}
    PYTHONDEVMODE = 1


[testenv:release]
description = "Runs the test environment in Python optimised mode"
setenv =
    {[testenv]setenv}
    PYTHONOPTIMIZE = 1
```
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
We lock the `tox-poetry-installer` version for reproducibility.
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
Make sure to regularly check for updates to the that project and update the version.
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
#### JUnit
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
The job will automatically upload any `junit.xml` file that is output.
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
To enable this with `pytest`, add the following to `pyproject.toml`:
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
```toml
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "--doctest-modules --junitxml=junit.xml"
junit_duration_report = "call"
junit_suite_name = "<your-package-name>"
```
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
#### Coverage
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
The job will upload an `coverage.xml` and `htmlcov` directory.

Enable this with the `pytest-cov` plugin and the following `pyproject.toml` configuration:

```toml
[tool.coverage.paths]
source = ["src", "*/site-packages"]

[tool.coverage.report]
precision = 2
sort = "-cover"
show_missing = true
fail_under = 100
exclude_lines = [
    "# coverage: ignore$",
]

[tool.coverage.run]
branch = true
source_pkgs = ["<your-package-name>"]

[tool.pytest.ini_options]
minversion = "6"
testpaths = ["tests"]
addopts = "--cov --cov-report=xml --cov-report=html --cov-report=term"
junit_duration_report = "call"
junit_suite_name = "<your-package-name>"
```
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
Make sure to install the `coverage` dependency with `toml` extra.
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
With Poetry this will be:
Ivan Artiukhov's avatar
Ivan Artiukhov committed

Ivan Artiukhov's avatar
Ivan Artiukhov committed
```toml
[tool.poetry.dev-dependencies.pytest-cov]
extras = ["toml"]
version = "^3.0.0"
```