How to Set Up Continuous Integration for OpenWork: A Complete GitHub Actions Guide

OpenWork uses GitHub Actions to automatically run its full test suite on every push and pull request to the dev branch, with workflows defined in .github/workflows/ that support cross-platform testing on Linux and macOS.

Setting up continuous integration for the OpenWork repository ensures that code changes are validated across multiple platforms before merging. According to the different-ai/openwork source code, the CI pipeline is entirely self-contained within workflow files, making it easy to replicate or extend for forks and custom deployments.

The Core CI Architecture: .github/workflows/ci-tests.yml

The main test matrix lives in [.github/workflows/ci-tests.yml](https://github.com/different-ai/openwork/blob/dev/.github/workflows/ci-tests.yml). This file orchestrates the entire validation process through a matrix execution strategy that runs on both blacksmith-4vcpu-ubuntu-2204 and macos-14 runners.

Cross-Platform Matrix Configuration

The matrix is declared under strategy.matrix.os and ensures OpenWork functions correctly on both Linux and macOS environments. This catches platform-specific issues early, particularly important for the Electron desktop application and native binary dependencies.

Toolchain Bootstrap Process

Each CI job performs a consistent toolchain setup in four stages:

  1. Node.js 24 via actions/setup-node

  2. pnpm 11.4.0 via pnpm/action-setup

  3. OpenCode CLI fetched dynamically based on constants.json — the CI reads require('./constants.json').opencodeVersion, downloads the matching release binary for the runner OS/architecture, extracts it, and adds it to $PATH

  4. Bun via oven-sh/setup-bun

OpenCode CLI Installation (Self-Contained)

The CI includes a custom step to fetch the correct OpenCode binary without hardcoding versions:

- name: Install OpenCode CLI
  run: |
    version=$(node -p "require('./constants.json').opencodeVersion")
    curl -L "https://github.com/anomalyco/opencode/releases/download/v${version}/opencode-linux-x64-baseline.tar.gz" | tar -xz -C $HOME/.opencode
    echo "$HOME/.opencode" >> $GITHUB_PATH

This pattern keeps the CLI version synchronized across all CI runs and local development environments.

Cache Management for Fast CI Runs

The pipeline aggressively caches dependencies using actions/cache with keys derived from both pnpm-lock.yaml and evals/pnpm-lock.yaml. This eliminates redundant network requests and reduces typical install times from minutes to seconds on cache hits.

Dependency installation uses strict reproducibility flags:

pnpm install --frozen-lockfile --prefer-offline

The evals workspace is installed separately after the main monorepo dependencies resolve.

The Full Test Execution Pipeline

The CI runs eight distinct validation stages in sequence:

  • Eval specs — pnpm --dir evals run test:pr validates end-to-end specifications

  • Unit tests — pnpm --filter @openwork/app test, pnpm --filter @openwork/server test, and pnpm --filter @openwork/desktop test cover each package

  • Release script tests — node --test scripts/release/*.test.mjs verifies automation logic

  • Eval runner tests — pnpm test:eval-runner checks the evaluation infrastructure

  • Outbound-access manifest check — pnpm check:outbound-access validates network permissions

  • Server plugin bundling — Mirrors production builds with --target node

  • Electron IPC type-checking — pnpm --filter @openwork/desktop typecheck:electron catches contract mismatches

  • E2E UI tests — pnpm --filter @openwork/app test:e2e exercises the full application

Result Aggregation with Required Checks

A sentinel job named openwork-tests-required depends on the matrix job and runs if: always() to guarantee execution. It fails the workflow if any matrix leg failed, providing a single required check that branch protection rules can target. This abstraction hides matrix complexity from repository settings.

Additional Specialized Workflows

Beyond the main test matrix, OpenWork includes focused workflows for specific concerns:

These execute in parallel to the main matrix and add targeted guards without slowing the critical path.

Minimal CI Setup for Forks or New Projects

To set up continuous integration for OpenWork in your own repository, commit the workflow files to .github/workflows/. GitHub Actions automatically discovers and executes them—no additional configuration required.

Copy-Pasteable Minimal Workflow

name: OpenWork CI – Minimal Example
on:
  push:
    branches: [dev]
  pull_request:
    branches: [dev]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - uses: actions/setup-node@v6
        with:
          node-version: 24

      - uses: pnpm/action-setup@v4
        with:
          version: 11.4.0

      - name: Install OpenCode CLI
        run: |
          version=$(node -p "require('./constants.json').opencodeVersion")
          curl -L "https://github.com/anomalyco/opencode/releases/download/v${version}/opencode-linux-x64-baseline.tar.gz" | tar -xz -C $HOME/.opencode
          echo "$HOME/.opencode" >> $GITHUB_PATH

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Run unit tests
        run: pnpm test

Running OpenWork CI Locally

Execute the same validation scripts used in CI on your development machine:


# Clone and enter repository

git clone https://github.com/different-ai/openwork.git
cd openwork

# Install pnpm if needed

npm i -g pnpm

# Reproduce CI install exactly

pnpm install --frozen-lockfile

# Run key validation stages

pnpm --filter @openwork/app test:e2e
pnpm --filter @openwork/desktop typecheck:electron
pnpm test:eval-runner

Local execution uses identical tooling versions and lockfile constraints, minimizing "works on my machine" failures.

Key Files for CI Maintenance

File Purpose
.github/workflows/ci-tests.yml Core test matrix with platform matrix and aggregation
.github/workflows/ci-openwork-ui-mcp.yml MCP UI integration validation
.github/workflows/ci-no-new-eval-flows.yml Eval flow addition guards
.github/workflows/ci-i18n.yml Localization checks
constants.json Single source of truth for OpenCode CLI version
pnpm-lock.yaml Monorepo dependency lock for cache keys
evals/pnpm-lock.yaml Eval workspace dependency lock
scripts/release/*.test.mjs Release automation test suite

Summary

  • Primary entry point: .github/workflows/ci-tests.yml defines the complete OpenWork CI pipeline
  • Platform coverage: Matrix runs on Ubuntu 22.04 and macOS 14 via strategy.matrix.os
  • Toolchain: Node 24, pnpm 11.4.0, Bun, and dynamically-fetched OpenCode CLI
  • Caching: Lockfile-based pnpm store caching accelerates repeat runs
  • Validation stages: Eight distinct test phases from unit tests through E2E UI automation
  • Required checks: openwork-tests-required sentinel job enables simple branch protection
  • Zero configuration: Workflow files alone enable full CI—no external services needed

Frequently Asked Questions

Does OpenWork CI require any external services beyond GitHub Actions?

No. The OpenWork continuous integration pipeline is entirely self-contained within GitHub Actions workflows. The only external dependency is the OpenCode CLI, which the CI fetches automatically from GitHub releases based on the version stored in constants.json. No third-party CI services, secrets, or infrastructure are required.

How does OpenWork handle cross-platform testing in CI?

The ci-tests.yml workflow uses a matrix strategy with strategy.matrix.os set to [blacksmith-4vcpu-ubuntu-2204, macos-14]. This runs all tests on both Linux and macOS runners in parallel. The OpenCode CLI installation step automatically selects the correct binary architecture for each runner platform.

Can I run the OpenWork test suite locally without CI?

Yes. Install pnpm globally, run pnpm install --frozen-lockfile, then execute individual test commands like pnpm test, pnpm --filter @openwork/app test:e2e, or pnpm test:eval-runner. These commands use the same scripts and configuration as the CI pipeline, though local execution won't include the platform matrix coverage.

What prevents the CI from passing if one matrix job fails?

The openwork-tests-required job in ci-tests.yml runs if: always() and aggregates results from all matrix legs. It fails explicitly when any dependency failed, creating a single required status check that branch protection rules can enforce. This ensures partial platform success never masks comprehensive failure.

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 →