Skip to content

Commit

Permalink
Migrate tests and lint suite to Nox (#21)
Browse files Browse the repository at this point in the history
* Basic nox file initiated

* Add lint check in nox sessions

* Use nox in GitHub workflow

* Fix GitHub action workflwo file in wrong place

* Add codecov upload in nox sessions

* Add codecov in dev dependencies

* Add a GitHub action to upload coverage dada

* Define in default sessions run by nox

* Bump minor version to workaround bug in noxfile

* Optimize noxfile to install only used dependencies

* Move coverage report upload in tests workflow

* Add colors in GitHub action logs for Nox

* Update documentation with poetry and nox usage
  • Loading branch information
oncleben31 authored Jul 28, 2020
1 parent 3ca77ef commit 89d9d30
Show file tree
Hide file tree
Showing 8 changed files with 295 additions and 101 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/constraints.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pip==20.1.1
nox==2020.5.24
poetry==1.0.10
42 changes: 0 additions & 42 deletions .github/workflows/python-package.yml

This file was deleted.

47 changes: 47 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: Tests

on:
push:
branches: [master]
pull_request:
branches: [master]

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.6, 3.7, 3.8]

steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
architecture: x64

- name: Upgrade pip
run: |
pip install --constraint=.github/workflows/constraints.txt pip
pip --version
- name: Install Poetry
run: |
pip install --constraint=.github/workflows/constraints.txt poetry
poetry --version
- name: Install Nox
run: |
pip install --constraint=.github/workflows/constraints.txt nox
nox --version
- name: Run Nox
run: nox --force-color

- name: Create coverage report
run: |
nox --force-color --session=coverage -- xml
- name: Upload coverage report
uses: codecov/[email protected]
137 changes: 81 additions & 56 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,77 +8,102 @@ Vous trouverez les instructions en français [ici](#contribuer).

Vous êtes tous invités à contribuer à ce projet pour le maintenir ou l'améliorer.
Même si vous n'êtes pas un développeur, vous pouvez suremnent donner un coup de
main à la documentation.

### Préparer votre Pull Request (PR)

- Commencez par faire un `fork` de ce dépot.
- Clonez votre dépot sur votre machine de developpement.
- Choisissez et installez votre environement de developpement (environement
virtuel, container, etc...).
- Installez le package python en mode edition avec ses prérequis de test:
`pip install -e .[testing]`.
- Créez une branche pour votre contribution.
- Testez vos modifications avec la commande `pytest`.
- Créez et envoyez la PR quand elle est prête.
- Attendez les commentaires des relecteurs, répondez à leur questions ou demandes
de mise au point.
- Votre contribution est fusionnée dans le projet. Merci.

### Bonnes pratiques

Pour faciliter la maintenance et la relecture il est fortement recommandé
d'utiliser des outils pour s'assurer de la qualité du code et de son formatage.
Avec les librairies installées par la comande `pip install -e .[testing]`, vous
pouvez utiliser les commandes:

- `pytest --cov` pour vérifer que les tests couvrent bien tout le code du
package.
- `flake8` pour vérfier que les bonnes pratiques Python sont respectées.
- `pydocstyle` pour vérifier que les bonnes pratique des docstrings sont
respectées.

Vous pouvez utiliser les lignes de commandes ci-dessus ou paramétrer votre
environnement de developpement pour utiliser ces outils ou similaires.
main en remontant les bugs constatés, en partageant vos idées d'amélioration ou
en participant à la documentation.

## Préparer votre environement de développement

Vous aurez besoin de Python 3.6+ et des outils suivants:

- [Poetry](https://python-poetry.org)
- [Nox](https://nox.thea.codes/en/stable)

Installez le package avec les dépendances de développement:

`$ poetry install`

Vous pouvez maintenant utiliser une session interactive Python:

`$ poetry run python`

## Tester le projet

Dérouler la suite de tests complète:

`$ nox`

Lister toutes les sessions disponibles dans Nox:

`$ nox --list-sessions`

Vous pouvez lancer une session Nox spécifique. Par exemple, lancez la suite de
tests unitaires avec:

`$ nox --session=tests`

Les tests unitaires sont dans le répertoire `tests` et utilisent le framework pytest.

### Soumettre votre Pull Request (PR)

Oouvrez une [pull requet](https://github.com/hacf-fr/meteofrance-api/pulls) pour proposer des changements à ce projet.

Votre pull request doit vérifier les conditions suivantes pour être acceptée:

- La suite de tests Nox doit réussir sans erreurs ni warning.
- Doit inclure des tests unitaires. Ce projet maintien une couverture de code à 100%.

### Proposer une nouvelle fonctionnalité

Pour proposer vos idées d'amélioration, ouvrez une `issue` en utilisant le
Pour proposer vos idées d'amélioration, ouvrez une [issue](https://github.com/hacf-fr/meteofrance-api/issues) en utilisant le
modèle `feature request`.

## Contributing

You are all invited to contribute to this project for maintenance or improvement.
Even if you are not a developer, you can probably help to improve the documentation.
Even if you are not a developer, you can probably help to report some bugs, share
improvements ideas, or contribute to the documentation.

### How to set up your development environment

You need Python 3.6+ and the following tools:

- [Poetry](https://python-poetry.org)
- [Nox](https://nox.thea.codes/en/stable)

Install the package with development requirements:

`$ poetry install`

You can now run an interactive Python session, or the command-line interface:

`$ poetry run python`

### How to test the project

Run the full test suite:

`$ nox`

List the available Nox sessions:

`$ nox --list-sessions`

You can also run a specific Nox session. For example, invoke the unit test suite like this:

### Prepare your Pull Request (PR)
`$ nox --session=tests`

- Start by forking this repository.
- Clone this repository on your development machine.
- Choose and setup your development environement (virtual environement, container,
etc.).
- Install the python package in edition mode with the test prerequisits:
`pip install -e .[testing]`.
- Create a branch for your contribution.
- Test your change using the `pytest` command.
- Create and send your PR when ready.
- Wait for feedbacks from the reviewers, answer their questions or updates.
- You contribution is merged in the project. Thank you.
Unit tests are located in the tests directory, and are written using the pytest testing framework.

### Guidelines
### How to submit changes

To make maintenance and review easier, we recommand you to use some tools ensuring
good code and format quality. With the librairies installed by
`pip install -e .[testing]` command, you can use the following commands:
Open a [pull requet](https://github.com/hacf-fr/meteofrance-api/pulls) to submit changes to this project.

- `pytest --cov` to check code coevrage of the test suite.
- `flake8` to check Python code best practices.
- `pydocstyle` to check docstrings bespractices.
Your pull request needs to meet the following guidelines for acceptance:

You can use those commands or setup your development environnement to use those
tools or silmilar ones.
- The Nox test suite must pass without errors and warnings.
- Include unit tests. This project maintains 100% code coverage.

### Feature suggestion

If you want to suggest a new feature for this project, please open an issue by
If you want to suggest a new feature for this project, please open an [`issue`](https://github.com/hacf-fr/meteofrance-api/issues) by
using the `feature request` template.
142 changes: 142 additions & 0 deletions noxfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
"""Nox sessions."""
import contextlib
import tempfile
from pathlib import Path
from typing import Iterator, cast

import nox
from nox.sessions import Session

python_versions = ["3.8", "3.7", "3.6"]
package = "meteofrance_api"
nox.options.sessions = "lint", "tests"
locations = "src", "tests", "noxfile.py"


class Poetry:
"""Helper class for invoking Poetry inside a Nox session.
Attributes:
session: The Session object.
"""

def __init__(self, session: Session) -> None:
"""Constructor."""
self.session = session

@contextlib.contextmanager
def export(self, *args: str) -> Iterator[Path]:
"""Export the lock file to requirements format.
Args:
args: Command-line arguments for ``poetry export``.
Yields:
The path to the requirements file.
"""
with tempfile.TemporaryDirectory() as directory:
requirements = Path(directory) / "requirements.txt"
self.session.run(
"poetry",
"export",
*args,
"--format=requirements.txt",
f"--output={requirements}",
external=True,
)
yield requirements

def version(self) -> str:
"""Retrieve the package version.
Returns:
The package version.
"""
output = self.session.run(
"poetry", "version", external=True, silent=True, stderr=None
)
return cast(str, output).split()[1]

def build(self, *args: str) -> None:
"""Build the package.
Args:
args: Command-line arguments for ``poetry build``.
"""
self.session.run("poetry", "build", *args, external=True)


def install_package(session: Session) -> None:
"""Build and install the package.
Build a wheel from the package, and install it into the virtual environment
of the specified Nox session.
The package requirements are installed using the versions specified in
Poetry's lock file.
Args:
session: The Session object.
"""
poetry = Poetry(session)

with poetry.export() as requirements:
session.install(f"--requirement={requirements}")

poetry.build("--format=wheel")

version = poetry.version()
session.install(
"--no-deps", "--force-reinstall", f"dist/{package}-{version}-py3-none-any.whl"
)


def install(session: Session, *args: str) -> None:
"""Install development dependencies into the session's virtual environment.
This function is a wrapper for nox.sessions.Session.install.
The packages must be managed as development dependencies in Poetry.
Args:
session: The Session object.
args: Command-line arguments for ``pip install``.
"""
poetry = Poetry(session)
with poetry.export("--dev") as requirements:
session.install(f"--constraint={requirements}", *args)


@nox.session(python=python_versions)
def tests(session: Session) -> None:
"""Run the test suite."""
install_package(session)
install(session, "coverage[toml]", "pytest", "requests-mock")
try:
session.run("coverage", "run", "--parallel", "-m", "pytest", *session.posargs)
finally:
session.notify("coverage")


@nox.session(python=python_versions)
def lint(session):
"""Lint using flake8."""
args = session.posargs or locations
install_package(session)
install(session, "flake8", "flake8-docstrings")
session.run("flake8", *args)


@nox.session
def coverage(session: Session) -> None:
"""Produce the coverage report."""
# Do not use session.posargs unless this is the only session.
has_args = session.posargs and len(session._runner.manifest) == 1
args = session.posargs if has_args else ["report"]

install(session, "coverage[toml]")

if not has_args and any(Path().glob(".coverage.*")):
session.run("coverage", "combine")

session.run("coverage", *args)
Loading

0 comments on commit 89d9d30

Please sign in to comment.