How OpenHuman's Two-Lane CI Model Ensures Test Coverage Before Merges
OpenHuman enforces mandatory test coverage through a dual-pipeline system where CI Lite validates changed code with an 80% coverage threshold on every pull request, while CI Full runs the complete test suite against the release branch to catch integration regressions before production deployment.
OpenHuman (tinyhumansai/openhuman) implements a sophisticated continuous integration strategy that balances developer velocity with quality assurance. The repository employs two distinct pipelines—CI Lite and CI Full—that work sequentially to guarantee no code reaches production without adequate test coverage. This architecture ensures rapid feedback during development while maintaining rigorous standards for releases.
The Two-Lane CI Architecture Explained
The CI system operates on a progressive validation principle. CI Lite provides immediate feedback on incremental changes, while CI Full serves as a comprehensive safety net before release. This separation allows developers to iterate quickly on feature branches while ensuring that integrated code meets enterprise-grade quality standards.
According to the source configuration in tinyhumansai/openhuman, the pipelines are defined in .github/workflows/ci-lite.yml and .github/workflows/ci-full.yml, with orchestration scripts located in scripts/ci/.
CI Lite Pipeline: Selective Testing for Rapid Feedback
CI Lite executes on every push to main and every pull request targeting main or release branches. It focuses exclusively on files modified in the current changeset to minimize execution time while maintaining coverage standards.
Trigger Conditions and Scope
The workflow triggers are configured to run when:
- Code is pushed to the
mainbranch - Pull requests are opened against
mainorreleasebranches
This ensures that developers receive immediate validation without waiting for the full matrix to complete.
Selective Test Execution
In .github/workflows/ci-lite.yml, the pipeline identifies changed files and executes targeted test suites. For TypeScript components in app/src/**, the workflow runs Vitest with change detection:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run changed Vitest tests
run: pnpm test:coverage --changed
For Rust components, the pipeline invokes ./scripts/ci/rust-coverage-changed.sh, which filters test execution using cargo llvm-cov to examine only the modified domains:
#!/bin/bash
# scripts/ci/rust-coverage-changed.sh
cargo llvm-cov --lib --filter changed
Enforcing the 80% Coverage Threshold
CI Lite mandates a minimum 80% line coverage on all changed lines. The workflow integrates coverage analysis tools—diff-cover for Vitest outputs and cargo-llvm-cov for Rust artifacts—to calculate differential coverage. If the threshold is not satisfied, the job fails and blocks the merge.
The enforcement logic appears in the workflow configuration:
- name: Verify coverage on changed lines
run: |
pnpm coverage:diff-check --threshold=80
./scripts/ci/verify-rust-diff-cov.sh 80
CI Full Pipeline: Comprehensive Pre-Release Validation
While CI Lite validates incremental changes, CI Full ensures that the entire codebase remains stable before release promotion. This pipeline executes the exhaustive test matrix that would be impractical to run on every commit.
Release Branch Protection
CI Full triggers exclusively on pushes to the long-lived release branch. This includes merges from main and direct commits, ensuring that only fully validated code reaches production environments.
Complete Test Matrix Execution
Defined in .github/workflows/ci-full.yml, the pipeline executes:
- Complete Vitest suite: All unit tests across the TypeScript codebase
- Rust integration tests: Full
cargo testexecution with the mock backend - End-to-end validation: Playwright UI specifications and desktop application E2E tests across Windows, macOS, and Linux runners
jobs:
full-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: pnpm test
- run: pnpm test:e2e
- run: ./scripts/test-rust-with-mock.sh --all
The CI Full Gate
The pipeline aggregates results through the CI Full Gate check, implemented as an artifact upload step that signals completion:
- name: CI Full Gate
uses: actions/upload-artifact@v3
with:
name: ci-full-gate
path: ./ci-full-results/
Branch protection rules require this gate to pass before any code merges into release, preventing regressions that selective testing might miss.
Implementation Details and Source Configuration
The orchestration relies on helper scripts in scripts/ci/ that calculate file differentials and invoke appropriate test filters. The ci-lite.sh script determines which Vitest and Rust tests correspond to the current PR's modifications, while ci-full.sh coordinates the cross-platform E2E execution.
Key implementation files include:
.github/workflows/ci-lite.yml: Defines the fast feedback pipeline and 80% coverage enforcement.github/workflows/ci-full.yml: Configures the exhaustive pre-release validation matrixscripts/ci/ci-lite.sh: Computes changed file sets for selective testingscripts/ci/ci-full.sh: Orchestrates full suite execution including Playwright and desktop E2E
Summary
- OpenHuman's two-lane CI model separates rapid validation from comprehensive verification to balance speed and quality.
- CI Lite runs on every PR to
main, executing only tests for changed files and requiring ≥80% line coverage on modifications before merge. - CI Full activates on the
releasebranch, running the complete test suite—including Vitest, Rust units, Playwright E2E, and desktop cross-platform tests—to prevent integration regressions. - Branch protection rules enforce both pipelines, ensuring no code reaches production without passing selective coverage checks and full matrix validation.
- The implementation resides in
.github/workflows/ci-lite.ymland.github/workflows/ci-full.yml, supported by differential coverage scripts inscripts/ci/.
Frequently Asked Questions
What happens if CI Lite coverage falls below 80%?
The workflow job fails and GitHub blocks the pull request merge. Developers must add tests for the uncovered lines or modify the implementation to reduce untested branches before the PR can proceed.
Why does CI Full only run on the release branch rather than every PR?
Running the complete matrix—including Rust mock-backend E2E and Playwright desktop tests across three operating systems—requires significant runner resources and time. By restricting CI Full to the release branch, OpenHuman preserves developer velocity on feature branches while guaranteeing integration stability before deployment.
How does OpenHuman detect which tests to run in CI Lite?
The scripts/ci/ci-lite.sh script compares the current branch against the merge base to identify modified files. It then maps these files to corresponding Vitest specifications (app/src/** patterns) and Rust crates, invoking pnpm test:coverage --changed and cargo llvm-cov with appropriate filters.
Can CI Lite pass while CI Full fails?
Yes. CI Lite validates only the changed code, so it might miss integration issues between components. If CI Full subsequently fails on the release branch, the merge that promoted the code is identified as faulty, triggering a revert or hotfix process before the code reaches production.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →