diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b48496a3..2a417b10 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,7 +22,7 @@ jobs: - name: Test with pytest run: | - pytest --cov=src --cov-report=lcov + pytest mv coverage.lcov base-coverage.lcov - name: Upload code coverage for base branch @@ -77,13 +77,15 @@ jobs: run: flake8 src - name: Test with pytest - run: pytest --cov=src --cov-report=lcov + run: pytest - name: Upload code coverage uses: actions/upload-artifact@v4 with: name: coverage-${{ matrix.python }} - path: ./coverage.lcov + path: | + ./coverage.lcov + ./coverage.json - name: Analyse with MyPy run: mypy @@ -121,7 +123,7 @@ jobs: - name: Test with pytest if: success() || failure() - run: pytest --cov=src --cov-report=lcov + run: pytest - name: Check quickstart, including installation if: success() || failure() @@ -136,6 +138,26 @@ jobs: with: name: coverage-3.12 + - name: Parse coverage percentage + id: get-coverage + run: | + COVERAGE=$(jq -r '.totals.percent_covered_display' coverage.json) + echo "coverage=$COVERAGE" >> $GITHUB_OUTPUT + + - name: Update Coverage Badge + # Only run this on the main branch so PRs don't overwrite the main badge + if: github.ref == 'refs/heads/main' + uses: Schneegans/dynamic-badges-action@v1.7.0 + with: + auth: ${{ secrets.GIST_SECRET }} + gistID: 936bcec8e1815a49d1e7f947924ffa3f + filename: labthings-fastapi-coverage.json + label: coverage + message: ${{ steps.get-coverage.outputs.coverage }}% + valColorRange: ${{ steps.get-coverage.outputs.coverage }} + maxColorRange: 90 + minColorRange: 50 + - name: Download code coverage report for base branch id: download-base-coverage continue-on-error: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5784c876..a5e6f03e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,122 +1,5 @@ # Contributing to labthings-fastapi -First off, thank you for considering contributing to `labthings-fastapi`! We welcome contributions from everyone, whether it's reporting a bug, suggesting a feature, improving documentation, or writing code. +Thank you for your interest in contributing! -This document outlines the processes for getting help, reporting issues, and contributing to the codebase. - -## Seeking Support - -If you have a question about how to use `labthings-fastapi`, or if you are running into trouble: - -* **Check the Documentation:** Please review the official documentation on [readthedocs]. -* **GitHub Discussions / Issues:** If you cannot find the answer, feel free to open an issue on our [GitHub Issues page]. -* **OpenFlexure Community:** Because `labthings-fastapi` is the underlying framework for v3 of the [OpenFlexure Microscope software], you may also find support by engaging with the broader [OpenFlexure Forum]. - -## Reporting Issues or Bugs - -If you find a bug or have a feature request, please report it by opening an issue on our [GitHub Issues page]. - -When reporting an issue, please include as much detail as possible: - -* **Description:** A clear and concise description of what the bug is. -* **Reproduction steps:** How can we reproduce the problem? (A minimal reproducible example is highly appreciated). -* **Expected behaviour:** What did you expect to happen? -* **Environment:** Include your OS, Python version, and `labthings-fastapi` version. Include full error tracebacks if applicable. - -## Contributing Code or Documentation - -We welcome pull requests for bug fixes, new features, and documentation improvements. - -### 1. Local Development Setup - -To work on the code, you will need to clone the repository and install the development dependencies. -Please see the [installation notes](./README.md#installation-notes) for more detail about compatible Python versions and Windows installation. - -```bash -# Clone the repository -git clone https://github.com/labthings/labthings-fastapi.git -cd labthings-fastapi - -# Install the package in editable mode with development dependencies -pip install -r dev-requirements.txt -``` - -### 2. Linting and Testing - -We use several tools to maintain code quality. All of these run in CI with [GitHub Actions], but you should run them locally before submitting a Pull Request. Both `ruff` and `flake8` are configured from [`pyproject.toml`]. - -* **Linting:** We use [`ruff`] for fast linting and formatting. We highly recommend setting up a pre-commit hook to ensure [`ruff`] passes on every commit. - ```bash - ruff format --check - ruff check . - ``` - -* **Docstrings:** [`flake8`] is primarily used to enable stricter checks on docstrings. - ```bash - flake8 src - ``` - -* **Spelling:** We use [`codespell`] to prevent common spelling mistakes in code and documentation. - ```bash - codespell . - ``` - -* **Type Checking:** We use [`mypy`] for static type checking. It is configured in `pyproject.toml`. - ```bash - mypy - ``` - -* **Testing:** We use [`pytest`] for our test suite and test coverage. Ensure all tests pass locally. - ```bash - pytest --cov=src - ``` - -### 3. Managing Dependencies - -Dependencies are defined in [`pyproject.toml`]. If you need to compile a `dev-requirements.txt` file (e.g., for reproducible CI/CD or local isolated environments), you can do so using [`uv`]: - -```bash -uv pip compile --extra dev pyproject.toml --output-file dev-requirements.txt -``` - -*(If you're not using `uv`, regular `pip-compile` from `pip-tools` will achieve the same thing).* - -### 4. Submitting a Pull Request (PR) - -All changes to the codebase must go via pull requests. Unless you are a core maintainer with write access, please use the standard fork-and-branch workflow: - -1. **Fork the repository** to your own GitHub account using the "Fork" button at the top of the repository page. -2. **Clone your fork** locally and set up the upstream remote: - ```bash - git clone https://github.com/YOUR-USERNAME/labthings-fastapi.git - cd labthings-fastapi - git remote add upstream https://github.com/labthings/labthings-fastapi.git - ``` -3. **Create a new branch** for your feature or bugfix: - ```bash - git checkout -b feature-name - ``` -4. **Commit your changes** with clear, descriptive commit messages. -5. **Push your branch** up to your fork: - ```bash - git push origin feature-name - ``` -6. **Open a Pull Request** against the `main` branch of the `labthings/labthings-fastapi` repository. - -**Pull Request Guidelines:** - -* Code should only be merged once all the checks in the CI test job are passing. -* **Unpinned Dependencies:** Note that we have a specific CI job called `test-with-unpinned-dependencies`. It is acceptable to merge code if only this specific job fails, provided the failure is due to upstream dependency issues. We prefer to deal with upstream dependency issues in a separate PR, particularly when the required fixes are distinct from the code in your current PR. The same applies to the `pip-audit` job. -* Update documentation (`docs/` or docstrings) if your changes modify existing behavior or add new features. - -[readthedocs]: https://labthings-fastapi.readthedocs.io/ -[GitHub Issues page]: https://github.com/labthings/labthings-fastapi/issues -[OpenFlexure Forum]: https://openflexure.discourse.group/ -[OpenFlexure Microscope software]: https://gitlab.com/openflexure/openflexure-microscope-server/ -[GitHub Actions]: https://github.com/labthings/labthings-fastapi/actions -[`ruff`]: https://docs.astral.sh/ruff/ -[`pyproject.toml`]: ./pyproject.toml -[`flake8`]: https://flake8.pycqa.org/en/latest/ -[`mypy`]: https://mypy-lang.org/ -[`pytest`]: https://docs.pytest.org/en/stable/ -[`uv`]: https://docs.astral.sh/uv/ \ No newline at end of file +Please read our full [Contributor Guidelines](./docs/source/contributing.md). diff --git a/README.md b/README.md index 3cb7c009..e4c59e49 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![codecov](https://codecov.io/gh/rwb27/labthings-fastapi/branch/main/graph/badge.svg?token=IR4QNA8X6M)](https://codecov.io/gh/rwb27/labthings-fastapi) +![Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/bprobert97/936bcec8e1815a49d1e7f947924ffa3f/raw/labthings-fastapi-coverage.json) [![Documentation Status](https://readthedocs.org/projects/labthings-fastapi/badge/?version=latest)](https://labthings-fastapi.readthedocs.io/en/latest/?badge=latest) # labthings-fastapi @@ -22,7 +22,7 @@ See [readthedocs] for installation instructions that are automatically tested. Y > > *If you are using a centrally managed machine, you will need administrator privileges to install these system-level dependencies.* -For instructions on how to set up a development environment, run tests, and contribute to this project, please see [CONTRIBUTING.md]. +For instructions on how to set up a development environment, run tests, and contribute to this project, please see our [Contributor Guidelines] and [Testing Guidelines]. ## Demo @@ -33,4 +33,5 @@ See [readthedocs] for a runnable demo. [OpenFlexure Microscope software]: https://gitlab.com/openflexure/openflexure-microscope-server/ [pre-commit hook]: https://openflexure.org/contribute#use-git-hooks-for-ci-checks [readthedocs]: https://labthings-fastapi.readthedocs.io/ -[CONTRIBUTING.md]: ./CONTRIBUTING.md +[Contributor Guidelines]: ./docs/source/contributing.md +[Testing Guidelines]: ./docs/source/testing.md diff --git a/docs/source/contributing.md b/docs/source/contributing.md index b2d2646a..468de7c7 100644 --- a/docs/source/contributing.md +++ b/docs/source/contributing.md @@ -1 +1,125 @@ -```{include} ../../CONTRIBUTING.md +# Contributing to labthings-fastapi + +First off, thank you for considering contributing to `labthings-fastapi`! We welcome contributions from everyone, whether it's reporting a bug, suggesting a feature, improving documentation, or writing code. + +This document outlines the processes for getting help, reporting issues, and contributing to the codebase. + +## Seeking Support + +If you have a question about how to use `labthings-fastapi`, or if you are running into trouble: + +* **Check the Documentation:** Please review the official documentation on [readthedocs]. +* **GitHub Discussions / Issues:** If you cannot find the answer, feel free to open an issue on our [GitHub Issues page]. +* **OpenFlexure Community:** Because `labthings-fastapi` is the underlying framework for v3 of the [OpenFlexure Microscope software], you may also find support by engaging with the broader [OpenFlexure Forum]. + +## Reporting Issues or Bugs + +If you find a bug or have a feature request, please report it by opening an issue on our [GitHub Issues page]. + +When reporting an issue, please include as much detail as possible: + +* **Description:** A clear and concise description of what the bug is. +* **Reproduction steps:** How can we reproduce the problem? (A minimal reproducible example is highly appreciated). +* **Expected behaviour:** What did you expect to happen? +* **Environment:** Include your OS, Python version, and `labthings-fastapi` version. Include full error tracebacks if applicable. + +## Contributing Code or Documentation + +We welcome pull requests for bug fixes, new features, and documentation improvements. + +### 1. Local Development Setup + +To work on the code, you will need to clone the repository and install the development dependencies. +Please see the [installation notes](./README.md#installation-notes) for more detail about compatible Python versions and Windows installation. + +```bash +# Clone the repository +git clone https://github.com/labthings/labthings-fastapi.git +cd labthings-fastapi + +# Install the package in editable mode with development dependencies +pip install -r dev-requirements.txt +``` + +### 2. Linting and Testing + +We use several tools to maintain code quality. All of these run in CI with [GitHub Actions], but you should run them locally before submitting a Pull Request. Both `ruff` and `flake8` are configured from [`pyproject.toml`]. + +More detailed information on our testing and linting can be found in our [Testing Guidelines]. + +* **Linting:** We use [`ruff`] for fast linting and formatting. We highly recommend setting up a pre-commit hook to ensure [`ruff`] passes on every commit. + ```bash + ruff format --check + ruff check . + ``` + +* **Docstrings:** [`flake8`] is primarily used to enable stricter checks on docstrings. + ```bash + flake8 src + ``` + +* **Spelling:** We use [`codespell`] to prevent common spelling mistakes in code and documentation. + ```bash + codespell . + ``` + +* **Type Checking:** We use [`mypy`] for static type checking. It is configured in `pyproject.toml`. + ```bash + mypy + ``` + +* **Testing:** We use [`pytest`] for our test suite and test coverage. Ensure all tests pass locally. + ```bash + pytest --cov=src + ``` + +### 3. Managing Dependencies + +Dependencies are defined in [`pyproject.toml`]. If you need to compile a `dev-requirements.txt` file (e.g., for reproducible CI/CD or local isolated environments), you can do so using [`uv`]: + +```bash +uv pip compile --extra dev pyproject.toml --output-file dev-requirements.txt +``` + +*(If you're not using `uv`, regular `pip-compile` from `pip-tools` will achieve the same thing).* + +### 4. Submitting a Pull Request (PR) + +All changes to the codebase must go via pull requests. Unless you are a core maintainer with write access, please use the standard fork-and-branch workflow: + +1. **Fork the repository** to your own GitHub account using the "Fork" button at the top of the repository page. +2. **Clone your fork** locally and set up the upstream remote: + ```bash + git clone https://github.com/YOUR-USERNAME/labthings-fastapi.git + cd labthings-fastapi + git remote add upstream https://github.com/labthings/labthings-fastapi.git + ``` +3. **Create a new branch** for your feature or bugfix: + ```bash + git checkout -b feature-name + ``` +4. **Commit your changes** with clear, descriptive commit messages. +5. **Push your branch** up to your fork: + ```bash + git push origin feature-name + ``` +6. **Open a Pull Request** against the `main` branch of the `labthings/labthings-fastapi` repository. + +**Pull Request Guidelines:** + +* Code should only be merged once all the checks in the CI test job are passing. +* **Unpinned Dependencies:** Note that we have a specific CI job called `test-with-unpinned-dependencies`. It is acceptable to merge code if only this specific job fails, provided the failure is due to upstream dependency issues. We prefer to deal with upstream dependency issues in a separate PR, particularly when the required fixes are distinct from the code in your current PR. The same applies to the `pip-audit` job. +* Update documentation (`docs/` or docstrings) if your changes modify existing behavior or add new features. + +[readthedocs]: https://labthings-fastapi.readthedocs.io/ +[GitHub Issues page]: https://github.com/labthings/labthings-fastapi/issues +[OpenFlexure Forum]: https://openflexure.discourse.group/ +[OpenFlexure Microscope software]: https://gitlab.com/openflexure/openflexure-microscope-server/ +[GitHub Actions]: https://github.com/labthings/labthings-fastapi/actions +[`ruff`]: https://docs.astral.sh/ruff/ +[`pyproject.toml`]: ./pyproject.toml +[`flake8`]: https://flake8.pycqa.org/en/latest/ +[`mypy`]: https://mypy-lang.org/ +[`pytest`]: https://docs.pytest.org/en/stable/ +[`uv`]: https://docs.astral.sh/uv/ +[Testing Guidelines]: ./testing.md \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst index 6ddf88a6..a4829189 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -19,6 +19,7 @@ Documentation for LabThings-FastAPI updates_and_features.rst see_also.rst examples.rst + testing.md wot_core_concepts.rst removed_features.rst diff --git a/docs/source/testing.md b/docs/source/testing.md new file mode 100644 index 00000000..d929edf4 --- /dev/null +++ b/docs/source/testing.md @@ -0,0 +1,93 @@ +# Testing labthings-fastapi + +Our test suite ensures the framework functions correctly, maintains code quality, and integrates seamlessly with static type checkers. + +## Continuous Integration (CI) Pipeline + +When you submit a Pull Request (PR), our GitHub Actions CI pipeline automatically runs a comprehensive suite of checks. Your PR must pass these checks before it can be merged. +You can find out more about contributing code in our [Contributor Guidelines]. + +Here is what the CI pipeline tests: + +* **Matrix Testing:** We run the core test suite (`pytest`) and static type checks (`mypy`) across Python versions 3.10, 3.11, 3.12, and 3.13. +* **Code Quality & Security:** The pipeline runs `ruff` (formatting and linting), `flake8` (docstrings), `codespell` (spelling), and a `pip-audit` to check for dependency vulnerabilities. +* **Coverage:** We track code coverage. A report is generated on your PR to show if your changes increased or decreased overall test coverage. +* **Dependency Checks:** We run the tests twice: once with pinned dependencies (`dev-requirements.txt`) for reproducibility, and once with unpinned dependencies (`.[dev]`) to catch upstream breakages early. +* **Downstream Integration:** The pipeline installs your version of `labthings-fastapi` alongside the `v3` branch of the OpenFlexure Microscope Server. It then runs the entire OFM test suite (unit, integration, and lifecycle) to guarantee backwards compatibility. *(Note: You can target a specific OFM branch by adding `OFM-Feature-Branch: branch-name` to your PR description).* + +--- + +## Running Core Tests Locally + +To ensure your code will pass CI, you should run these checks locally before pushing your commits. + +### 1. Local Environment Setup + +We recommend running the test suite using the pinned development dependencies to mirror the primary CI environment. Ensure you have cloned the repository, then install the package and dependencies: + +```bash +git clone https://github.com/labthings/labthings-fastapi.git +cd labthings-fastapi +pip install -e . -r dev-requirements.txt +``` + +> **Note: Windows Installations on devices with ARM processors** +> +> Installing on Windows devices with ARM processors requires Visual Studio with the **"Desktop development with C++"** workload enabled. This is necessary because `pydantic` relies on Rust, which in turn requires C++ build tools to compile. +> +> *If you are using a centrally managed machine, you will need administrator privileges to install these system-level dependencies.* + +### 2. Linting, Formatting, and Spelling + +Check that your code adheres to the project's formatting and style guidelines from the root of the repository: + +* **Linting:** `ruff check .` +* **Formatting:** `ruff format --check .` +* **Spelling:** `codespell .` +* **Docstrings:** `flake8 src` + +### 3. Static Type Checking + +`labthings-fastapi` is designed to be fully type-hinted. We explicitly test that `mypy` can infer the correct types for `Thing` attributes. Run static type checking across the source code and our dedicated typing tests folder: + +```bash +mypy +``` + +### 4. Unit Tests & Coverage + +We use `pytest` for our core test suite. Execute the unit tests and generate a coverage report using: + +```bash +pytest +``` + +--- + +## Downstream Integration Testing Locally + +Because `labthings-fastapi` underpins the [OpenFlexure Microscope software], major architectural changes should be tested against the downstream server locally. This matches the `test-against-ofm-v3` job in our CI pipeline. + +Assuming you have both repositories cloned in the same parent directory: + +```bash +# 1. Setup the OpenFlexure Microscope Server +cd ../openflexure-microscope-server +git checkout v3 +pip install -r dev-requirements.txt + +# 2. Install your local version of labthings-fastapi +pip install -e ../labthings-fastapi + +# 3. Pull the OFM web app (required for integration) +python ./pull_webapp.py + +# 4. Run the OFM Test Suite +pytest # Run OFM unit tests +pytest tests/integration_tests # Run OFM integration tests +python tests/lifecycle_test/testfile.py # Run OFM lifecycle tests +mypy src # Run OFM static type checks +``` + +[OpenFlexure Microscope software]: https://gitlab.com/openflexure/openflexure-microscope-server/ +[Contributor Guidelines]: ./contributing.md \ No newline at end of file diff --git a/docs/source/tutorial/installing_labthings.rst b/docs/source/tutorial/installing_labthings.rst index d73d9a01..c52e4df8 100644 --- a/docs/source/tutorial/installing_labthings.rst +++ b/docs/source/tutorial/installing_labthings.rst @@ -23,7 +23,7 @@ then install labthings with: :start-after: BEGIN install :end-before: END install -It is also possible to install LabThings from source, by cloning the GitHub repository and running ``pip install -e .[dev]``, but this is only recommended if you intend to alter the LabThings-FastAPI library; it is best to use the published package unless you have a good reason not to. +It is also possible to install LabThings from source, by cloning the GitHub repository and running ``pip install -r dev-requirements.txt``, but this is only recommended if you intend to alter the LabThings-FastAPI library; it is best to use the published package unless you have a good reason not to. Installation Notes diff --git a/pyproject.toml b/pyproject.toml index dd1ffdca..5b72c8a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,7 +71,8 @@ addopts = [ "--cov-report=xml:coverage.xml", "--cov-report=html:htmlcov", "--cov-report=lcov", - "--cov=src" + "--cov=src", + "--cov-report=json", ] markers = [ "slow: marks tests as slow (deselect with '-m \"not slow\"')",