Skip to content
plsftPublic

About

Local-first runner for GitHub Actions — same YAML, 5–30× faster than act

Resources

Contributing

Stars

2 stars

Watchers

1 watching

Forks

Latest commit

 

History

410 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rehearse

CI feedback in seconds, before you push. Most CI tools start the clock at git push. Rehearse runs your .github/workflows/*.yml on your laptop, on every save, in sub-second. Same YAML, three execution targets, no lock-in.

Rehearse is an OSS GitHub Actions toolchain with a fast pre-push loop plus a same-binary hosted offload target — the combination is what distinguishes us from sibling local runners (nektos/act is the OG in this space; we share the category but ship more features and the hosted-offload story). It reads your existing .github/workflows/*.yml and executes it three ways:

  1. Locally (rh run) — host subprocess or container backend, sub-second on the typey demo workflow
  2. Pro VM (rh run --remote) — single-tenant VM with whole-rootfs persistence, ~5s on the same workflow
  3. GitHub Actions (git push) — same compiled YAML, no Rehearse runtime needed, ~95s for the same workflow

Same source, same output, no lock-in. Free, Apache 2.0, source on github.com/plsft/rehearse.

Comparison with hosted-runner replacements (Blacksmith, Ubicloud, RunsOn, BuildJet, Namespace): see rehearse.sh/vs for the honest take. Short version: those products optimize execution target #3 (post-push). Rehearse adds targets #1 and #2 (pre-push + offload) — different shape, complementary. The OSS runner is your moat against vendor risk: if any hosted-runner SaaS raises prices or disappears, your CI keeps running on a laptop without them.

Quick start

npm install -g @rehearse/cli

# inside any repo with a .github/workflows/*.yml
rh run .github/workflows/ci.yml
rh watch .github/workflows/ci.yml          # re-run on save
rh install-hook                            # pre-push git hook

Numbers

vs GitHub Actions (the comparison most users care about)

The same 9-cell matrix workflow run on three targets — measured today against plsft/typey, a real third-party Bun CLI repo (not a fixture we control):

Target Wall vs GH
Local (rh run, warm) 1.5s 63× faster
Pro (rh run --remote, warm) 5s 19× faster
GitHub Actions (3 OS × 3 Bun, 9 cells) 95s baseline

Workflow exercises checkout + setup-bun + install + format + lint + tsc

  • test + build per cell. The speedup is GH's spin-up tax — cold container, fresh toolchain install, cold module caches on every push. Local skips all of it; Pro keeps everything warm between runs.

Footnote: vs nektos/act (the OSS comparison)

Most folks comparison-shop us against act — the OSS project we share a category with. v0.3.11 warm, GH-hosted Linux:

Target Rehearse act Speedup
our-ci (typecheck + tests, 2 parallel jobs) 12.19s 63.78s 5.23×
node-matrix [18.x, 20.x, 22.x] (3 parallel cells) 1.12s 10.07s 8.99×
service-postgres (postgres:16 + 4 psql) 10.97s timeout (>360s) 32.82× — act fails
hono-bun (real OSS, honojs/hono bun job) 7.58s n/a (act lacks bun) —

Per-OS numbers and full methodology in bench/RESULTS.md. Reproducible with gh workflow run bench.yml.

Repo layout

cli/           — @rehearse/cli   — single binary `rh` (runner + TS-pipeline ergonomics, all-in-one)
ts-ci/         — @rehearse/ci    — author workflows in TypeScript (library)
git-engine/    — internal-only since v0.6.0 — pure-TypeScript git protocol
bench/         — runner-vs-act bench harness + results
poc/           — fixture workflows used by the bench harness (vite/hono/etc.)
.rehearse/     — TypeScript source for this repo's own CI
.github/       — generated workflow YAML (do not edit by hand)

What's supported today

  • run: steps with bash / pwsh / cmd + full $GITHUB_OUTPUT / $GITHUB_ENV / $GITHUB_PATH / $GITHUB_STEP_SUMMARY contract
  • 18 in-process action shims: checkout, setup-{node,python,go,java,dotnet,bun,pnpm,deno,ruby}, rust-toolchain, cache + /save + /restore, upload-artifact, download-artifact, codecov, github-script. setup-dotnet is a real shim that runs Microsoft's dotnet-install.sh and caches the SDK.
  • JavaScript actions (runs.using: node12 / node16 / node20, plus forward-compat acceptance of node22 / 24 / 25) — auto-cloned at the requested ref, full INPUT_* / GITHUB_OUTPUT contract
  • services: with health checks (Docker network alias wired correctly) — local container backend only
  • strategy.matrix (variables × include − exclude) — cells run in parallel via per-cell git worktree
  • needs: with topological scheduling and bounded concurrency
  • if: on jobs and steps — full context: matrix / env / secrets / vars / needs / steps / job / runner / inputs / github
  • Local composite actions (./.github/actions/*) AND remote (org/repo[/sub]@ref — auto-cloned)
  • Local reusable workflows (uses: ./.github/workflows/foo.yml) with with: + secrets: inherit
  • ${{ matrix… }}, ${{ env… }}, ${{ secrets… }}, ${{ vars… }}, ${{ runner… }}, ${{ needs.<job>.outputs.<n> }}, ${{ steps.<id>.outputs.<n> }}, ${{ github.* }}
  • rh run --remote ships the workflow to a Pro VM (auto-detects git origin + SHA + monorepo subdir; ships --env-file secrets to ${{ secrets.* }})

Known gaps

  • Remote reusable workflows (org/repo/.github/workflows/foo.yml@ref) — local form works
  • OIDC / id-token: write — use long-lived creds via --env-file for now
  • concurrency: cancellation — parsed, not enforced
  • Pro-side services: — works locally via container backend, not yet on hosted Pro VMs

Roadmap lives on the GitHub issues for the repo.

Local development

# Requires Node 22+ and pnpm 9+
pnpm install
pnpm turbo typecheck       # passes across all 5 workspace packages
pnpm turbo test             # 162 cli tests + ts-ci snapshot tests, all green
pnpm --filter @rehearse/cli build
node cli/dist/index.js run .github/workflows/ci.yml

To reproduce the benchmark vs act:

git clone --depth 1 https://github.com/honojs/hono.git poc/playground/hono
docker pull node:22-bookworm-slim postgres:16-alpine catthehacker/ubuntu:act-latest
pnpm tsx bench/compare.ts --skip-cold

Open source

All packages are Apache 2.0, published under the @rehearse npm scope.

Package Path What it does
@rehearse/cli cli/ Single binary rh — local runner + TS-pipeline CLI
@rehearse/ci ts-ci/ Author workflows in TypeScript (library)

Releases

Releases are cut by tagging with v*.*.*. The release workflow on github.com/plsft/rehearse handles npm publishing and GitHub Release creation automatically.

# Stable release: bumps version everywhere, commits, tags, pushes.
pnpm release patch       # 0.1.0 → 0.1.1
pnpm release minor       # 0.1.0 → 0.2.0
pnpm release major       # 0.1.0 → 1.0.0

# Prerelease channel: published with `--tag next` (or rc / beta).
pnpm release prerelease           # 0.1.0 → 0.1.1-next.0
pnpm release prerelease:rc        # 0.1.0 → 0.1.1-rc.0
pnpm release prerelease:beta      # 0.1.0 → 0.1.1-beta.0

# Explicit version (rare):
pnpm release 0.2.0-rc.1

# Sanity check what would happen:
pnpm release patch --dry

What the workflow does on every v*.*.* push:

Tag form npm dist-tag GitHub Release npm install @rehearse/cli resolves to
v0.2.0 latest marked --latest 0.2.0
v0.2.0-next.0 next marked --prerelease (unchanged; @next resolves to it)
v0.2.0-rc.1 rc marked --prerelease (unchanged; @rc resolves to it)
v0.2.0-beta.3 beta marked --prerelease (unchanged; @beta resolves to it)

Try a prerelease without affecting latest:

npm install @rehearse/cli@next

GitHub Release notes are auto-generated by gh release create --generate-notes based on the PRs and commits since the previous tag — no hand-written CHANGELOG file to keep up to date.

License

Apache 2.0 across the board. See LICENSE and individual package directories for the per-package copies.

Contributing

See CONTRIBUTING.md. Issues and PRs welcome at https://github.com/plsft/rehearse.

About

Local-first runner for GitHub Actions — same YAML, 5–30× faster than act

Resources

Contributing

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages