Overview

We welcome all community contributions across all OpenFlexure projects.

There are many way to contribute to the project (not all of them involve writing code!):

  • Creating a bug report - Did you have a problem using OpenFlexure. You can open an issue on the relavent repository, this way your problem is automatically added to our TODO list!
  • Editing our documentation - Was something confusing. All our documentation is also online. Suggesting improvements to documentation really help the project.
  • Telling us what you think on the [forum] - We love hearing about what you are doing with the microscope. The more we know the better we can support the community. Let us know if something isn’t working, if we don’t know we can’t help!
  • Submitting code - This is a bit more involved. This page will help you get started.

Full source code is available for all hardware and software available on our GitLab project. If you are thinking about submitting code contributions it may be worth starting a conversation with the developers before getting stuck into big code changes. You can either do this through an issue on the repository, or on our community forum.

Development Guide

This development guide assumes you have Git installed, and have an account on gitlab.com.

Cloning the Repository

First find the repository on the OpenFlexure GitLab that you want to work on, such as the microscope hardware repository or microscope server repository.

The next step is to clone the repository, exactly how you do this will depend on if you are a community member, or an OpenFlexure developer.

Community Contributions

Follow this section if you are not a member with developer permissions in the OpenFlexure Gitlab.

To clone the repository:

  1. Fork the repository using the button in the top right corner of the page.
  2. You should now have a copy of the project under <your-username>/<repository-nmae>
  3. Click the button labelled Code, you’ll find it underneath the page heading.
  4. Select the clipboard icon next to the Clone with SSH or Clone with HTTPS (see the Gitlab docs for more information on these options).
  5. You have now coppied the correct clone command!

Our Internal Development

This section explains the internal process used by the OpenFlexure developers.

  1. Click the button labelled Code, you’ll find it underneath the page heading.
  2. Select the clipboard icon next to the Clone with SSH or Clone with HTTPS (see the Gitlab docs for more information on these options).
  3. You have now coppied the correct clone command!

Now you have the correct command copied you need to paste it somewhere. This might be:

  • In a terminal window (Such as Powershell in Windows)
  • Into a Git GUI client (see options here)
  • If you use VSCode or another Git aware code editor. You can copy it into the clone option your code editor.

From now on this guide will give you Git commands that can be typed into a terminal. If you are using a GUI client or code editor, you will need to find a button of the same name, or check the instructions for the specific program you are using.

Creating Branches and Merge requests

  • The default branch (usually called master or main) is always the latest working version.
  • New features and bug fixes are developed on branches, using one branch for one feature/bug fix.
  • Merge requests are opened to merge into the default branch.

We encourage any ongoing work in branches to also have a corresponding merge request, even if the branch is experimental or a work in progress. Adding Draft: to the start of a merge request title, indicates it is not ready for consideration. Creating Merge Requests for all branches allows everyone to be aware of ongoing work, reducing duplication of effort and conflicting directions for development.

OpenFlexure flow

Use of Branches and Merge Requests

Branches can be used for:

  • Development of a new feature
  • Fixing a bug
  • Experimentation and prototyping, for example for research purposes or meeting a specific use case

Branches used for developing a new feature or fixing a bug should be expected to be merged into the default branch. As such, they should follow the contribution guidelines listed below. Branches used for experimentation and prototyping are largely not expected to be merged into the default branch as they are their own, standalone piece of work. As such, whilst it is recommended that experimental branches follow the contribution guidelines, this is not enforced. If a decision is made to merge an experimental branch into the default branch, then the code on that branch will need to be updated to align with the contribution guidelines.

Non-experimental branches should:

  • Only contain one new feature or bug fix, ideally relating to a pre-raised issue on GitLab.
  • Adhere to the project’s standards on code formatting, readability and testing.
  • Pass the necessary CI checks.
  • Touch as few files as possible, to reduce review effort.
  • Be reviewed by at least two project approvers before being merged into the default branch.
  • Open a Merge Request (MR) as early as possible to allow for high level review, and improve visibility of the work for all contributors.
    • Initially, MRs should be raised in Draft mode, until they are ready for formal review.

Experimental branches should:

  • Ideally adhere to the project’s standards on code formatting, readability and testing, but this is not enforced.
  • Be labelled in a way that makes it obvious that this branch is not intended for merging into the default branch. This can be done by:
    • Setting the branch name to something like experimental-john-smith or prototype-john-smith.
    • When raising a Merge Request (MR), to have structured discussions, view diffs, or check performance against CI, the MR should be in Draft mode. Add a clear comment in the MR description indicating the status of the branch, and the form of interaction/comments that would be useful. For example, “This branch is experimental, do not review”.

Some other considerations for all branches:

  • Branches are generally considered as owned by the author of the branch. Do not commit to another person’s branch unless they specifically ask you to.
  • Branches that stay open for a long time can get very out of date accumulating merge conflicts. Rebasing branches is a good way to keep a branch up to date, however be careful not to run a git pull after rebasing or you will get duplicate copies of commits and the history will need fixing. If in doubt ask for help!
  • Try to avoid merge commits in branches, these can make for a messy history that is difficult to rebase.

Guidance for Regular Contributors

If you’re contributing regularly to the project, here are a few recommendations to help maintain quality and keep things running smoothly.

Plan and Communicate Openly

Before starting any significant work, take time to plan your approach. This could include drafting mock-ups, outlining architecture, or discussing ideas informally with other contributors. Use issues for reporting bugs, proposing features, and coordinating work. For broader or more exploratory discussions, the community forum is the best place. These public channels ensure transparency, help others stay informed, and invite wider feedback.

Provide documentation

It is important that any changes leave the documentation as complete as it was previously (or better!). Documentation can take many forms, the the hardware repositories it is predominantly the the Assembly Instructions, but is also the code documentation. For the Assembly Instructions the compiled result can be viewed in the merge request interface (see the section on the CI).

For code it is important to ensure that the comments and documentation match the style used in the repository. Predominantly, our software repositories are in Python, and the core documentation are function and module doc strings.

Test Thoroughly Where Possible

When contributing to the hardware repository, standard unit tests are not possible in most places (though there are some unit tests for certain functions). As such, the physical part needs to be printed and tested. Please indicate in the description of any Merge Request whether the parts have been printed/assembled, providing photos and provide photos and/or screenshots of the new part

We are trying to improve the test coverage of the Python code. Contributions to Python code should include relevant unit tests, written using pytest. Features and bug fixes should also be tested on an OpenFlexure Microscope. This helps ensure that changes don’t break existing functionality and are safe to merge.

We currently do not have an established unit testing procedure for the Javascript Web App. We would welcome advice and support with establishing testing for the front end.

The GitLab CI

We make extensive use of GitLab’s “Continuous Integration” or CI pipelines, usually referred to as “the CI”. The CI is a set of computer scripts that at pre-defined times such as on every commit added to a merge request. We use these to:

  • Automatically check for code style and code quality
  • Automatically run tests that code is functioning correctly
  • Automatically compile software
  • Automatically re-build all STLs
  • Automatically re-generate all rendered assembly images
  • Automatically build documentation
  • Automatically build our website

A CI pipeline is the full set of scripts that run. A pipeline can be divided into multiple jobs, some of which may run in parallel.

The CI status can be identified in the GitLab interface by:

  • Green circles with a tick inside - indicating jobs/pipeline passed
  • Red circles a cross inside - indicating a job/pipeline failed
  • Orange circles a exclamation mark inside - indicating a job/pipeline passed with warnings.

It is possible to click on the circle for more details, and to inspect the files created by the jobs. Merge requests can not be merged unless all jobs in the CI pipeline pass.

For certain repositories (such as the main microscope hardware repository) we use a the CI to serve a website showing the current status of the documentation on the branch to be merged. This can be accessed via the “View app” button.

CI pipelines and the "View app" button

Use Git Hooks for CI Checks

To avoid committing code that breaks the CI pipeline, we recommend using Git hooks to run checks before pushing. A pre-commit hook can automatically validate your code using tools like ruff.

Here’s an example of a pre-commit hook script:

#!/bin/bash

set -e

function angrymessage()
{
    RED='\033[1;31m'
    NC='\033[0m' # No Color
    printf "\n${RED}Not committing as ruff failed${NC}\n\n"
}

trap angrymessage ERR

ruff format --check
ruff check

Save this script as .git/hooks/pre-commit in your repository. For Linux systems, you will also need to make it executable (chmod +x .git/hooks/pre-commit). On Windows, you can execute bash scripts via a Git Bash terminal, or through WSL.

Guidance for Reviewers

Code review is a key part of maintaining high standards across both hardware and software contributions. This guidance applies broadly to all merge requests (MRs), regardless of language or domain. Over time, we aim to develop more specific best practices per language or toolchain, but for now, here are the general principles to follow.

Use the Tools

Make use of GitLab’s features to streamline the review process:

  • Inline Suggestions: Use these to propose changes directly in comments.

Adding an Inline Suggestion Displaying an Inline Suggestion

  • Thread resolution via Issues: If a discussion requires a follow-up rather than blocking the MR, open an issue and resolve the thread accordingly.

Thread Resolution via Issues

Respect Review Readiness

Authors can indicate that a merge request is not yet ready for review in the description. If this is the case:

  • Do not leave low-level feedback (e.g. formatting, naming, specific implementation details).
  • It’s fine to give high-level feedback on direction, scope, or design choices.
  • Always respect the author’s signal — they’ll request a full review when ready.

Merge Request Descriptions

The MR description should:

  • Clearly state the reason for the change.
  • Highlight any key changes, such as architectural shifts, design decisions, or autogenerated code.
  • You can also use comments in the diff to draw attention to areas that need special scrutiny.

Review Requirements

Each MR requires two reviewers to approve before merging.

When reviewing, look out for:

  • Bugs or logic issues
  • Typos and clarity of naming
  • Accessibility, especially for user-facing components
  • Testing: Are tests present and appropriate?
  • Readability: Is the code clear and maintainable?
  • Documentation: Check for missing or out-o-date docstrings, comments, assembly steps, assembly renders, or usage notes
  • Type hints (where applicable)

This applies equally to software and hardware contributions. Both are treated as code and deserve the same level of rigour and attention.

Before approval the the reviewer should verify (or ask the authour to verify):

  • Any code runs and does its intended function in the final environment (i.e. for microscope server code, that it runs on a microscope)
  • That any modified hardware components (such as STLs) have been printed and functionally tested.

Releases

  • Once we’ve merged a few things in and want to make a release, we tag it on the default branch.
    • These things will include some pre-defined feature additions and bug fixes, along with other emerging additions.
  • Not every commit on the default branch will get a tag, we accumulate a number changes before making a release, unless there’s a reason to release straight away.
  • After a release tag, the default branch becomes the development branch of the next significant release.
  • Hotfixes for releases may be developed on specific hotfix branches.
  • One a release has been tested and tagged, it will be announced on the community forum