CI/CD Integration

Continuous Integration and Continuous Deployment (CI/CD) pipelines automate the process of testing code changes and deploying them to production. OpenClaw's CI/CD configuration ensures that every change passes the full test suite before merge and that releases are deployed consistently and repeatably, with automatic rollback triggers on test failures.

CI/CD Pipeline Overview

The CI/CD pipeline has two primary phases: verification (runs on every PR and push to main) and release (runs on version tags). The verification phase runs linting, type checking, unit tests, and optional integration tests. The release phase builds distribution packages, runs the full test suite including E2E behavioral tests, publishes to PyPI, builds and pushes the Docker image, and deploys to staging for final smoke testing before production.

GitHub Actions Workflows

Three workflow files control the CI/CD pipeline:

# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
  test-unit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: {python-version: "3.11"}
      - run: pip install -e ".[dev]"
      - run: pytest tests/unit/ --cov=openclaw --cov-report=xml
      - uses: codecov/codecov-action@v4

  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: {python-version: "3.11"}
      - run: pip install -e ".[dev]"
      - run: black --check . && ruff check . && mypy openclaw/

Test Job Matrix

Unit tests run against a matrix of Python versions (3.10, 3.11, 3.12) and operating systems (Ubuntu, Windows, macOS) to catch platform-specific issues early. The full matrix generates 9 test jobs per push. If any single matrix job fails, the PR is blocked from merging. This ensures that OpenClaw works for users on all supported environments, not just the developer's specific machine.

Caching for Speed

GitHub Actions caches pip dependencies using the actions/cache action, keyed by the hash of pyproject.toml. This reduces CI time from 4 minutes to under 2 minutes for jobs with unchanged dependencies. The Docker build cache is similarly persisted across runs using cache-from: type=gha. Fast CI encourages developers to push early and often rather than batching changes to reduce CI waits.

Deployment Gating

Production deployments are gated on all CI checks passing, a mandatory review from at least one maintainer, and a passing smoke test on the staging environment. The staging smoke test runs a representative sample of agent tasks and verifies that outputs meet a minimum quality threshold. If the smoke test fails, the deployment is automatically rolled back to the previous version and an alert is sent to the on-call maintainer.

Status Badges and Reporting

OpenClaw's README includes CI status badges showing the current build status, test coverage percentage, and PyPI version. These badges give contributors and users an at-a-glance health check. Code coverage reports are uploaded to Codecov on every push — the detailed per-file coverage breakdown helps identify under-tested modules that need more test attention before they accumulate bugs.

Pull Request Checks

Every pull request triggers a set of automated checks that must all pass before the PR can be merged. Understanding each check helps contributors diagnose failures quickly:

  • lint: Checks code formatting (black), style (ruff), and type annotations (mypy). Fix with make format to auto-apply black and ruff --fix, then address any remaining mypy errors manually.
  • test-unit: Runs all unit tests across the Python version matrix. A failure here means a test broke — check the CI log to identify which test and why.
  • codecov: Reports coverage change. A coverage drop comment on the PR is informational, not a blocking check — but PRs with significant coverage drops will be asked to add tests before merge.
  • build: Verifies that the Python package builds cleanly and that the Docker image builds without errors.

Setting Up CI for Your Fork or Plugin

If you're developing an OpenClaw plugin or a fork, you can adapt the project's CI configuration. Copy the .github/workflows/ directory to your repository and adjust the PACKAGE_NAME variable and the test paths. The same GitHub Actions workflows work for any Python package with a pytest test suite — no custom tooling required.

For plugins, the integration test job should be expanded to run the plugin against a real OpenClaw instance using the Docker Compose test environment defined in tests/docker-compose.yml. This validates that the plugin works end-to-end with a real agent rather than just in unit isolation.

Deployment Process

When a release tag (e.g., v0.9.2) is pushed to GitHub, the release workflow runs: it builds distribution packages, runs the complete test suite including integration tests, and publishes to PyPI only if all tests pass. The Docker image is built and pushed to Docker Hub tagged with the version number and updated as the latest tag. This means the latest Docker image always corresponds to the most recent stable release — never a development build.

Managing Secrets in CI

Integration tests require API keys that must not be committed to the repository. GitHub Actions provides encrypted secrets that are injected as environment variables at runtime. Configure secrets at the repository level (Settings → Secrets and variables → Actions) for keys shared across all branches, and at the environment level for keys that should only be used by specific environments (staging, production).

Never log secret values — even accidentally printing an API key to CI output is a security incident. GitHub Actions automatically redacts known secret values from logs, but this protection is defeated if the secret is base64-encoded or otherwise transformed before logging. Design your code to never log secrets, and audit your logging statements in code that handles credentials.

Rotate CI secrets regularly, especially after any team membership changes or suspected compromise. A secret that has never been rotated is a secret that may have been silently leaked months ago. Most CI providers including GitHub Actions support secret rotation without downtime by updating the secret value and triggering a test run to verify the new value works.