Help us shape the future of Go! Take the 2026 Go Developer Survey

ermite

module
v0.26.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 18, 2026 License: AGPL-3.0

README

ermite

Last commit GitHub stars

A single-user Git forge in one Go binary.

Read-only mirror. Development happens at git.bnema.dev; issues and pull requests are closed here.


Features

  • GitHub Actions, as is: your .github/workflows run unchanged, marketplace actions included
  • Isolated runner: ermite-runner runs each job in a Firecracker microVM when KVM is available, else in a container
  • CLI-first: repositories, merge requests, reviews and CI all work from the ermite CLI, for you and for AI agents
  • Safe for agents: an agent token can only push its own branches; you review and merge
  • Git over HTTPS, web interface with live updates

Status: early development.

GitHub Actions

Push a repository with a .github/workflows folder and its workflows run, the same YAML you use on GitHub:

  • Events: push, pull_request, pull_request_target, workflow_dispatch, schedule, workflow_run, create, delete
  • Matrix, needs, concurrency, reusable workflows, job outputs and summaries
  • Secrets, variables, environments and OIDC (id-token: write)
  • actions/checkout, actions/cache, setup-*, upload-artifact / download-artifact v4
  • Actions from github.com or from your own ermite repositories
  • Each job is a check on the commit and the merge request; failing checks block the merge

A feature ermite does not support fails with not supported yet: <feature>, never silently.

Runner

Jobs run on ermite-runner hosts, one fresh sandbox per job:

  • microVM (Firecracker) when /dev/kvm is available: each job gets its own kernel, destroyed at the end
  • container with its own Docker daemon otherwise
ermite token create runner-1 --preset runner   # then register the runner with this token
ermite runner list

CI turns on as soon as a runner is registered. Details: docs/ci.md.

Run

docker build -t ermite .
token=$(head -c 32 /dev/urandom | base64)   # keep it: it is the root credential
docker run -d -p 127.0.0.1:7341:7341 -v ermite-data:/data \
  -e ERMITE_PUBLIC_URL=http://localhost:7341 -e ERMITE_ADMIN_TOKEN="$token" ermite

Without Docker, set ERMITE_DATA_DIR, ERMITE_PUBLIC_URL and ERMITE_ADMIN_TOKEN, then run ermite serve. Requires git 2.45 or newer. Put a TLS proxy in front of it.

All settings: docs/configuration.md.

Use

Point the CLI at the server:

ermite config set url https://git.example.com
ermite config set token.cmd 'pass show ermite/token'   # any command that prints the token

Then:

ermite repo create myrepo
git push https://x:<token>@git.example.com/myrepo.git main   # prefer a credential helper
ermite mr create myrepo --source feature --title "Add feature"
ermite web login   # one-time link to sign in to the web interface

Pushing to a new name also creates a private repository.

Agent workflow

You and the agent use the same CLI. The difference is the token: the agent's is limited to its own branches. It can never push main, tags or settings, and its CI runs get no secrets.

1. You give the agent a token limited to agent/claude/*:

ermite token create claude --preset agent --scope repo:read --repo myrepo --branch-prefix agent/claude/ --expires 30d

2. The agent pushes and opens a merge request:

export ERMITE_URL=https://git.example.com ERMITE_TOKEN=<agent token>
git push origin agent/claude/fix-login
ermite mr create myrepo --source agent/claude/fix-login --title "Fix login redirect"
ermite run watch myrepo <run id>         # follow its CI

3. You review:

ermite mr show myrepo 1 --diff
ermite mr comment myrepo 1 -m "Handle the empty case" --path auth.go --line 42 --side new

4. The agent reads your comments and pushes again:

ermite watch myrepo --json               # live events: pushes, merge requests, comments
ermite mr show myrepo 1 --since-last-read --mark-read

5. You merge (or click Merge in the web interface):

ermite mr merge myrepo 1 --head <head id> --squash --delete-branch

Give the agent the skills/ermite skill so it knows the CLI. Rules of agent tokens: docs/tokens.md.

Documentation

License

AGPL-3.0-or-later. See LICENSE.

Directories

Path Synopsis
cmd
ermite command
Command ermite is a single-user Git forge.
Command ermite is a single-user Git forge.
gen
internal
adapters/ciartifacts
Package ciartifacts implements ports.CIArtifactFiles under $ERMITE_DATA_DIR/ci/artifacts, keyed by the global run id like the logs (a repository rename never moves them):
Package ciartifacts implements ports.CIArtifactFiles under $ERMITE_DATA_DIR/ci/artifacts, keyed by the global run id like the logs (a repository rename never moves them):
adapters/cilogs
Package cilogs implements ports.CILogStore with append-only files under $ERMITE_DATA_DIR/ci/logs/<run id>/<job id>/<attempt>.log.
Package cilogs implements ports.CILogStore with append-only files under $ERMITE_DATA_DIR/ci/logs/<run id>/<job id>/<attempt>.log.
adapters/cisummaries
Package cisummaries implements ports.CISummaryStore with one Markdown file per step under $ERMITE_DATA_DIR/ci/summaries/<run id>/<job id>/<attempt>/<step>.md.
Package cisummaries implements ports.CISummaryStore with one Markdown file per step under $ERMITE_DATA_DIR/ci/summaries/<run id>/<job id>/<attempt>/<step>.md.
adapters/client
Package client is the Connect client of the remote CLI: it turns the ERMITE_URL and ERMITE_TOKEN settings into authenticated service clients for the ermite-api contract, maps Connect errors to one-line messages and keeps a Watch stream alive across reconnections.
Package client is the Connect client of the remote CLI: it turns the ERMITE_URL and ERMITE_TOKEN settings into authenticated service clients for the ermite-api contract, maps Connect errors to one-line messages and keeps a Watch stream alive across reconnections.
adapters/ermitegit
Package ermitegit implements ports.RepoReader over the ermite-git library.
Package ermitegit implements ports.RepoReader over the ermite-git library.
adapters/eventbus
Package eventbus implements ports.EventBus: in-process fan-out to subscribers, never blocking the publisher.
Package eventbus implements ports.EventBus: in-process fan-out to subscribers, never blocking the publisher.
adapters/gitcli
Package gitcli implements the Git ports over the git binary.
Package gitcli implements the Git ports over the git binary.
adapters/githttp
Package githttp serves Git over smart HTTP: it routes, authenticates and authorizes a request, then lets `git http-backend` answer it through net/http/cgi.
Package githttp serves Git over smart HTTP: it routes, authenticates and authorizes a request, then lets `git http-backend` answer it through net/http/cgi.
adapters/githubapi
Package githubapi serves the subset of GitHub's REST API that the actions running on ermite call under github.api_url (/-/github/api, ADR 0025 CI-2):
Package githubapi serves the subset of GitHub's REST API that the actions running on ermite call under github.api_url (/-/github/api, ADR 0025 CI-2):
adapters/githubraw
Package githubraw downloads a reusable workflow file from raw.githubusercontent.com at a commit (ports.WorkflowFetcher).
Package githubraw downloads a reusable workflow file from raw.githubusercontent.com at a commit (ports.WorkflowFetcher).
adapters/gitremote
Package gitremote lists the refs of repositories on github.com with `git ls-remote`, for the resolution of actions (ports.GitRemote).
Package gitremote lists the refs of repositories on github.com with `git ls-remote`, for the resolution of actions (ports.GitRemote).
adapters/httpserver
Package httpserver is the HTTP entry of ermite: the router, the security headers, the request log and the graceful shutdown.
Package httpserver is the HTTP entry of ermite: the router, the security headers, the request log and the graceful shutdown.
adapters/kvstore
Package kvstore implements the metadata ports over ermite-kv.
Package kvstore implements the metadata ports over ermite-kv.
adapters/oidchttp
Package oidchttp serves the OIDC provider of CI jobs under /-/oidc, the issuer (CI-4, D5):
Package oidchttp serves the OIDC provider of CI jobs under /-/oidc, the issuer (CI-4, D5):
adapters/rpc
Package rpc serves the ermite API contract (bnema.dev/ermite-api) with ConnectRPC: handlers that map the messages of the contract to the use cases of usecase and back, the interceptor that authenticates callers, and the error mapping.
Package rpc serves the ermite API contract (bnema.dev/ermite-api) with ConnectRPC: handlers that map the messages of the contract to the use cases of usecase and back, the interceptor that authenticates callers, and the error mapping.
adapters/secretbox
Package secretbox seals the values of CI secrets with AES-256-GCM under the server's master key (ERMITE_SECRETS_KEY, ADR 0019).
Package secretbox seals the values of CI secrets with AES-256-GCM under the server's master key (ERMITE_SECRETS_KEY, ADR 0019).
adapters/sigverify
Package sigverify checks commit signatures against the trusted keys (ADR 0030).
Package sigverify checks commit signatures against the trusted keys (ADR 0030).
adapters/sshsig
Package sshsig signs the commits ermite creates with the instance key (ADR 0022): an ed25519 key, in the SSH signature format Git reads with gpg.format=ssh.
Package sshsig signs the commits ermite creates with the instance key (ADR 0022): an ed25519 key, in the SSH signature format Git reads with gpg.format=ssh.
adapters/web
templ: version: v0.3.1020
templ: version: v0.3.1020
adapters/webauthn
Package webauthn implements ports.PasskeyVerifier over go-webauthn (ADR 0026).
Package webauthn implements ports.PasskeyVerifier over go-webauthn (ADR 0026).
app
Package app is the composition root and the command line of ermite: it parses the CLI, reads the environment, builds the adapters and wires them to the use cases.
Package app is the composition root and the command line of ermite: it parses the CLI, reads the environment, builds the adapters and wires them to the use cases.
clientlimit
Package clientlimit counts failed authentications per client address and finds the address of a request behind trusted proxies.
Package clientlimit counts failed authentications per client address and finds the address of a request behind trusted proxies.
config
Package config parses and validates the server configuration from the environment.
Package config parses and validates the server configuration from the environment.
ports
Package ports declares every interface that crosses a layer, and the parameter and result types of the use case interfaces.
Package ports declares every interface that crosses a layer, and the parameter and result types of the use case interfaces.
readertest
Package readertest is the shared test kit of the RepoReader adapters: Git fixtures built with the git binary, the conformance table every adapter must pass, and the comparison of one adapter with another.
Package readertest is the shared test kit of the RepoReader adapters: Git fixtures built with the git binary, the conformance table every adapter must pass, and the comparison of one adapter with another.
usecase
Package usecase holds the use cases of ermite.
Package usecase holds the use cases of ermite.
scripts
loadtest command
loadtest replays a traffic scenario against an ermite server and reports throughput and latency per request, while holding open the live updates streams that the pages of real visitors keep.
loadtest replays a traffic scenario against an ermite server and reports throughput and latency per request, while holding open the live updates streams that the pages of real visitors keep.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL