Skip to content

Instantly share code, notes, and snippets.

@marothstein
Created March 20, 2026 05:41
Show Gist options
  • Select an option

  • Save marothstein/4e757d0ecb6c5c971068097e5fd30132 to your computer and use it in GitHub Desktop.

Select an option

Save marothstein/4e757d0ecb6c5c971068097e5fd30132 to your computer and use it in GitHub Desktop.

Ollie's Self-Hosted GitHub Actions Runner

Why self-hosted?

Ollie is an Electron macOS app that needs to be code-signed, built, and E2E tested on real Apple Silicon hardware for every PR. GitHub's hosted macOS runners are slow and expensive for this — a self-hosted runner on a local Mac gives us fast builds with native arm64 performance and access to the macOS keychain for code signing.

What runs where

Runner Workflow What it does
Self-hosted (macOS arm64) pr-check.yml Unit tests, service tests, code-signed build, Playwright E2E tests, artifact upload
GitHub-hosted (macos-latest) build-electron.yml Release builds on push to master
GitHub-hosted (macos-latest) review-pr.yml, implement-issue.yml AI-powered PR review and issue implementation
GitHub-hosted (ubuntu-latest) issue-triage.yml, rebase-auto-prs.yml, pipeline-digest.yml, etc. Lightweight CI/CD automation

The self-hosted runner is only used for PR validation — the heavy lift where build speed matters most.

How the PR check pipeline works

When a PR is opened against master (ignoring cloud/, docs/, and *.md changes):

  1. Unit testsnpm ci + vitest runs the full test suite
  2. Service tests — Builds and tests each extracted service package (planning-service, scheduler-service, etc.)
  3. Code-signed build — Imports a P12 certificate into a temporary keychain, writes .env secrets, runs build-dist.cjs
  4. Build verification — Checks the .app bundle exists, validates the code signature with codesign --verify, checks for DMG output
  5. E2E tests — Playwright launches the built Electron app with OLLIE_TEST_MODE=1 and an isolated temp data dir (/tmp/ollie-e2e-*), runs 6 test suites (app launch, window behavior, navigation, tasks, brain dump, planning)
  6. Artifact upload — DMG and zip uploaded to GitHub with 7-day retention
  7. PR comment — Bot posts/updates a comment with download link, commit info, and test status
  8. Cleanup — Temp dirs, .env, build output, and the signing keychain are all removed

Key details:

  • Concurrency: one run per PR number, cancel-in-progress (new push kills the old run)
  • 30-minute timeout on the whole job
  • Test isolation: each E2E suite gets its own temp OLLIE_DATA_DIR so tests never touch real user data

Runner setup

The runner is registered on a local Mac (Apple Silicon) using GitHub's standard self-hosted runner registration flow — labels: self-hosted, macos, arm64. There's no containerization or custom service wrapper; it runs the stock actions/runner agent. Code signing secrets (CSC_LINK, CSC_KEY_PASSWORD, APPLE_ID, etc.) are stored as GitHub repo secrets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment