- HOW_TO_RUN_TESTS: coverage is not collected by a plain pytest run and pytest.ini has no threshold; the only one is --cov-fail-under=52 in the core unit-test job of .github/workflows/test.yml, which runs the whole test/ tree (not an allowlist). Almost no tests carry markers, so -m integration / -m slow select nothing; drop them and -m unit as the quick check. Replace the hardcoded /home/chuck path. - DEVELOPMENT: the rgbmatrix package is built with pip install . from the submodule root (scikit-build-core + CMake + Ninja), as first_time_install.sh does; there is no make build-python / bindings/python step, and the build deps are python-dev-is-python3, cmake and ninja-build, not cython3/scons. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5.9 KiB
Development Guide
This guide provides information for developers and contributors working on the LEDMatrix project.
Git Submodules
rpi-rgb-led-matrix-master Submodule
The rpi-rgb-led-matrix-master submodule is a foundational dependency located at the repository root (not in plugins/). This submodule provides the core hardware abstraction layer for controlling RGB LED matrices via the Raspberry Pi GPIO pins.
Architectural Rationale
Why at the root?
- Core Dependency: Unlike plugins in the
plugins/directory,rpi-rgb-led-matrix-masteris a foundational library required by the core LEDMatrix system, not an optional plugin - System-Level Integration: The
rgbmatrixPython module (built from this submodule) is imported bysrc/display_manager.py, which is part of the core display system - Build Requirements: The submodule must be compiled to create the
rgbmatrixPython bindings before the system can run - Separation of Concerns: Keeping core dependencies at the root level separates them from user-installable plugins, maintaining a clear architectural distinction
Why not in plugins/?
- Plugins are optional, user-installable modules that depend on the core system
rpi-rgb-led-matrix-masteris a required build dependency, not an optional plugin- The core system cannot function without this dependency
Initializing the Submodule
When cloning the repository, you must initialize the submodule:
First-time clone (recommended):
git clone --recurse-submodules https://github.com/ChuckBuilds/LEDMatrix.git
cd LEDMatrix
If you already cloned without submodules:
git submodule update --init --recursive
To initialize only the rpi-rgb-led-matrix-master submodule:
git submodule update --init --recursive rpi-rgb-led-matrix-master
Building the Submodule
After initializing the submodule, build and install the rgbmatrix Python
package from the submodule root. Upstream's pyproject.toml builds it with
scikit-build-core, CMake and Ninja; there is no separate make step:
cd rpi-rgb-led-matrix-master
python3 -m pip install --break-system-packages .
On a board with 1 GB of RAM or less, cap the compile so it doesn't run out of
memory: CMAKE_BUILD_PARALLEL_LEVEL=1 python3 -m pip install --break-system-packages .
Note: The first_time_install.sh script automates this process during
installation, including the parallelism cap and a temporary swapfile on
low-memory boards.
Troubleshooting
Submodule appears empty:
If the rpi-rgb-led-matrix-master directory exists but is empty or lacks a Makefile:
# Remove the empty directory
rm -rf rpi-rgb-led-matrix-master
# Re-initialize the submodule
git submodule update --init --recursive rpi-rgb-led-matrix-master
Build fails: Ensure you have the required build dependencies installed:
sudo apt install -y build-essential python-dev-is-python3 cmake ninja-build
Import error for rgbmatrix module:
- Verify the submodule is initialized:
ls rpi-rgb-led-matrix-master/Makefile - Ensure the Python bindings are built and installed (see "Building the Submodule" above)
- Check that the module is installed:
python3 -c "from rgbmatrix import RGBMatrix; print('OK')"
Submodule out of sync: If the submodule commit doesn't match what the main repository expects:
git submodule update --remote rpi-rgb-led-matrix-master
CI/CD Configuration
When setting up CI/CD pipelines, ensure submodules are initialized before building:
GitHub Actions Example:
- name: Checkout repository
uses: actions/checkout@v3
with:
submodules: recursive
- name: Build rpi-rgb-led-matrix
run: |
cd rpi-rgb-led-matrix-master
pip install .
GitLab CI Example:
variables:
GIT_SUBMODULE_STRATEGY: recursive
build:
script:
- cd rpi-rgb-led-matrix-master
- pip install .
Jenkins Example:
stage('Checkout') {
checkout([
$class: 'GitSCM',
branches: [[name: '*/main']],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'SubmoduleOption',
disableSubmodules: false,
parentCredentials: true,
recursiveSubmodules: true,
reference: '',
trackingSubmodules: false]],
userRemoteConfigs: [[url: 'https://github.com/ChuckBuilds/LEDMatrix.git']]
])
}
General CI/CD Checklist:
- ✓ Use
--recurse-submodulesflag when cloning (or equivalent in your CI system) - ✓ Initialize submodules before any build steps
- ✓ Build the Python bindings if your tests require the
rgbmatrixmodule - ✓ Note: Emulator mode (using
RGBMatrixEmulator) doesn't require the submodule to be built
Plugins
Plugins are not git submodules of this repository. The plugins
directory (configured by plugin_system.plugins_directory in
config/config.json, default plugin-repos/) is populated at install
time by the plugin loader as users install plugins from the Plugin Store
or from a GitHub URL via the web interface. Plugin source lives in a
separate repository:
ChuckBuilds/ledmatrix-plugins.
To work on a plugin locally without going through the Plugin Store, clone
that repo and symlink (or copy) the plugin directory into your configured
plugins directory — by default plugin-repos/<plugin-id>/. The plugin
loader will pick it up on the next display restart. The directory name
must match the plugin's id in manifest.json.
For more information, see:
- PLUGIN_DEVELOPMENT_GUIDE.md — end-to-end plugin development workflow
- PLUGIN_ARCHITECTURE_SPEC.md — plugin system specification
- DEV_PREVIEW.md — preview plugins on a desktop without a Pi