CI Pipeline
RODENT uses a Gitea Actions workflow to perform automated quality checks whenever changes are pushed or a pull request is opened.
The workflow is:
.gitea/workflows/quality.yml
Pipeline Triggers
The workflow runs on:
push
pull_request
This ensures that both direct repository changes and proposed changes are checked automatically.
Pipeline Structure
The workflow contains two main jobs:
quality.yml
│
├── platform
│
└── godot
The platform job performs Python, JavaScript, backend and UI-related checks.
The godot job performs headless Godot tests.
Platform Job
The platform job prepares the general development environment and executes the non-Godot quality checks.
Environment
The job uses:
Python 3.12
Node.js 20
Coverage tooling is installed using:
coverage 7.10.7
JavaScript Syntax Check
The workflow checks:
node --check web/app.js
This validates the JavaScript syntax without running the application.
The check catches syntax errors before they reach later UI tests.
Preset Validation
The workflow runs:
python tests/validate_presets.py
This validates the JSON presets stored under:
presets/
The validator checks the expected schema and required configuration fields.
It validates:
- schema version
- metadata
- simulation configuration
- arena dimensions
- materials
- regions
- walls
- doors
- stimuli
- protocol
- treatment
- rodent configuration
- controller configuration
- object references
Determinism Configuration Check
The workflow runs:
python tests/test_determinism_ci.py
This checks the determinism-relevant configuration of every preset.
The script requires deterministic configuration values such as:
simulation.seed
simulation.fixed_delta
controller.start_position
controller.start_heading
controller.speed
controller.turn_noise
It also includes arena dimensions and counts of regions, walls and doors in the determinism hash.
The script reads the configuration twice and verifies that the resulting hash is identical.
Importantly, this test checks deterministic configuration stability. It does not execute two complete simulations and compare their trajectories.
Backend and Unit Tests
The platform job runs the backend and headless client unit tests under coverage.
Coverage output is generated as part of the test process.
The workflow enforces a minimum coverage threshold of:
60%
If coverage falls below the configured threshold, the job fails.
Coverage XML is also generated so that the result can be consumed by other quality-reporting systems.
UI Contract Tests
The platform job also executes the project's UI contract tests.
These checks verify that the web interface continues to satisfy the expected application contracts after changes are made.
Godot Job
The second major CI job executes the Godot-specific tests.
Godot Version
The workflow downloads:
Godot 4.7.1 stable
for the Linux CI environment.
Headless Import
The project is imported using Godot in headless mode.
This ensures that project resources can be loaded by the engine without requiring a graphical desktop session.
Headless Godot Tests
The workflow executes the following tests:
tests/test_determinism.gd
tests/test_experiment_features.gd
tests/test_stimuli_recording.gd
tests/test_live_doors.gd
tests/test_ui.gd
These tests cover different parts of the application.
Determinism Test
tests/test_determinism.gd
Checks deterministic behaviour implemented in the Godot application.
Experiment Features Test
tests/test_experiment_features.gd
Checks experiment-related application functionality.
Stimuli Recording Test
tests/test_stimuli_recording.gd
Checks stimulus-related behaviour and recording.
Live Doors Test
tests/test_live_doors.gd
Checks that live door state functionality behaves correctly.
UI Test
tests/test_ui.gd
Checks the Godot UI behaviour covered by the project's automated test suite.
Pipeline Flow
The overall quality process can be represented as:
Push / Pull Request
│
▼
quality.yml
│
├─────────────────────────────┐
│ │
▼ ▼
Platform Job Godot Job
│ │
├── Node syntax check ├── Godot import
│ │
├── Preset validation ├── Determinism
│ │
├── CI determinism ├── Experiment features
│ │
├── Unit tests ├── Stimulus recording
│ │
├── UI contracts ├── Live doors
│ │
└── Coverage └── UI tests
Both jobs must satisfy their configured checks for the workflow to pass.
Preset Validation in CI
Preset validation is important because the application is data-driven.
A malformed preset can cause problems in:
arena construction
simulation setup
stimulus configuration
door configuration
treatment configuration
controller initialization
Running:
python tests/validate_presets.py
in CI prevents invalid preset files from being merged without detection.
Determinism Checks in CI
Deterministic simulation requires important configuration values to remain stable.
The CI determinism script hashes the following configuration information:
seed
fixed_delta
start_position
start_heading
speed
turn_noise
arena dimensions
region count
wall count
door count
The same preset is loaded twice and the resulting configuration hash is compared.
Conceptually:
Preset
│
├── Read #1 ──► SHA-256 hash
│
└── Read #2 ──► SHA-256 hash
│
▼
hashes equal?
/ \
yes no
│ │
pass fail
This provides a lightweight CI guard against unexpected configuration instability.
Coverage Requirement
The platform job enforces:
60% minimum coverage
Coverage is generated during the automated test process and exported as XML.
This gives the project a measurable baseline for automated test coverage.
The threshold applies to the coverage configuration used by the workflow rather than representing a guarantee that every application component has equal coverage.
Why the Pipeline Uses Multiple Jobs
The project contains both general platform code and Godot-specific application code.
Separating the pipeline into:
platform
godot
allows each environment to use the tools appropriate to the code being tested.
The platform job can focus on:
Python
JavaScript
backend
UI contracts
coverage
while the Godot job focuses on:
Godot project import
simulation behaviour
stimuli
doors
Godot UI
determinism
Running the Checks Locally
The most important preset and determinism checks can be run locally.
Preset validation:
python tests/validate_presets.py
Determinism configuration:
python tests/test_determinism_ci.py
The Godot tests can be run through the Godot command-line interface in headless mode using the project test scripts.
The exact CI commands should remain defined by:
.gitea/workflows/quality.yml
so that local and CI execution can be compared against the repository's actual workflow.
Failure Handling
A CI failure should be treated as a development feedback signal.
Typical failures include:
Invalid preset JSON
Missing required preset field
Invalid wall or door reference
Invalid deterministic configuration
JavaScript syntax error
Unit test failure
UI contract failure
Godot test failure
Coverage below threshold
Godot project import failure
Changes should be corrected locally and the relevant tests rerun before pushing again.
Workflow File
The complete CI workflow is maintained in:
.gitea/workflows/quality.yml
This file is the authoritative definition of the automated quality pipeline.
The documentation describes the checks performed by that workflow; changes to the workflow should be reflected here when the pipeline behaviour changes.