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 main branch
  • Pull requests are opened against main or release branches

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 test execution 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:

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 release branch, 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.yml and .github/workflows/ci-full.yml, supported by differential coverage scripts in scripts/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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →