Skip to main content

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.