Release Runbook (Gitea-authoritative, GitHub publish)
Terraphim releases follow ADR-0001/0002: Gitea is source of truth; GitHub publishes public artefacts.
Repositories
| Repo | Role |
|------|------|
| git.terraphim.cloud/terraphim/terraphim-ai | Monorepo: server, Docker, Debian, Homebrew |
| git.terraphim.cloud/terraphim/terraphim-clients | Client binaries: agent, cli, grep |
| git.terraphim.cloud/terraphim/terraphim-service | terraphim_service crate + Gitea registry |
| github.com/terraphim/terraphim-ai | Public mirror + GitHub Releases (auto-update URLs) |
Client binaries are built in terraphim-clients and attached to the terraphim-ai GitHub release.
Prerequisites
Verify dual-remote sync before tagging:
&&
Release procedure (vX.Y.Z)
0. Registry: republish broken or changed crates
If terraphim_service (or other registry deps) changed on Gitea:
# In terraphim-service repo on Gitea main
Bump terraphim_service = { version = "X.Y.Z", registry = "terraphim" } in:
terraphim-ai(terraphim_server,terraphim_rlm,terraphim_github_runner*,terraphim_ai_nodejs)terraphim-clients(via polyrepo publish)
1. Gitea CI green on main
Merge features on Gitea; wait for native-ci success.
2. Polyrepo publish (if client/core crates changed)
POLYREPO_DRY_RUN=0
# Repeat for terraphim-service, terraphim-core, etc. as neededThis injects release-binaries.yml into terraphim-clients and syncs to GitHub.
3. Bump workspace version on Gitea main
# Cargo.toml workspace.package.version and dependent crate pins
| 4. Tag and push both remotes
5. Monitor GitHub workflows
On terraphim/terraphim-ai tag vX.Y.Z:
release-comprehensive.yml— server binaries, Docker, Debian, GitHub release- Dispatches
terraphim-clients→release-binaries.yml(attaches agent/cli/grep) wait-for-client-binaries— polls release asset countupdate-homebrew— updates tap formulas
Check:
# Expect server + client assets and checksums.txt6. Acceptance checks
| Check | Command |
|-------|---------|
| Server version | ./terraphim_server --version |
| Release assets | gh release view vX.Y.Z --repo terraphim/terraphim-ai --json assets |
| Registry crate | cargo search terraphim_service --registry terraphim |
| Homebrew | brew update && brew info terraphim-server |
Manual crate publish (monorepo only)
Extracted crates use each polyrepo's publish-crates.yml with crate_list from polyrepo-publish.sh.
Recovery: failed release with zero assets
Do not force-push tags. Fix workflows, bump to next patch (e.g. v1.20.4 → v1.20.5), re-tag after CI green.
Secrets
| Secret | Repo | Purpose |
|--------|------|---------|
| CARGO_REGISTRIES_TERRAPHIM_TOKEN | terraphim-clients | Private registry during build |
| TERRAPHIM_ORG_GITHUB_TOKEN | terraphim-ai (org PAT) | Cross-repo workflow dispatch (desktop + clients) |
| DESKTOP_REPO_TOKEN | terraphim-ai | Legacy alias — same value as TERRAPHIM_ORG_GITHUB_TOKEN |
| CLIENTS_REPO_TOKEN | terraphim-ai | Legacy alias — same value as TERRAPHIM_ORG_GITHUB_TOKEN |
| TERRAPHIM_AI_RELEASE_TOKEN | terraphim-clients (org PAT) | Upload client binaries to terraphim-ai release |
| OP_SERVICE_ACCOUNT_TOKEN | terraphim-ai, terraphim-clients | macOS signing via 1Password |
TERRAPHIM_ORG_GITHUB_TOKEN, DESKTOP_REPO_TOKEN, CLIENTS_REPO_TOKEN, and
TERRAPHIM_AI_RELEASE_TOKEN should share one org-level fine-grained PAT (or classic
PAT) with actions:write and contents:write on terraphim/* repos. The per-job
GITHUB_TOKEN cannot replace them for cross-repo calls.