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:
-
Node.js 24 via
actions/setup-node -
pnpm 11.4.0 via
pnpm/action-setup -
OpenCode CLI fetched dynamically based on
constants.json— the CI readsrequire('./constants.json').opencodeVersion, downloads the matching release binary for the runner OS/architecture, extracts it, and adds it to$PATH -
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:prvalidates end-to-end specifications -
Unit tests —
pnpm --filter @openwork/app test,pnpm --filter @openwork/server test, andpnpm --filter @openwork/desktop testcover each package -
Release script tests —
node --test scripts/release/*.test.mjsverifies automation logic -
Eval runner tests —
pnpm test:eval-runnerchecks the evaluation infrastructure -
Outbound-access manifest check —
pnpm check:outbound-accessvalidates network permissions -
Server plugin bundling — Mirrors production builds with
--target node -
Electron IPC type-checking —
pnpm --filter @openwork/desktop typecheck:electroncatches contract mismatches -
E2E UI tests —
pnpm --filter @openwork/app test:e2eexercises 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:
-
.github/workflows/ci-openwork-ui-mcp.yml— Validates MCP UI integration -
.github/workflows/ci-no-new-eval-flows.yml— Prevents accidental addition of new evaluation flows -
.github/workflows/ci-i18n.yml— Runs localization validation
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.ymldefines 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-requiredsentinel 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →