add AUTOMATED_DEV.md: Gitea + Mattermost + CI + µPaaS pipeline
All checks were successful
check / check (push) Successful in 12s

This commit is contained in:
clawbot 2026-02-28 02:38:27 -08:00
parent 0db057ff4a
commit 3950e33fff
2 changed files with 254 additions and 0 deletions

249
AUTOMATED_DEV.md Normal file
View File

@ -0,0 +1,249 @@
# Automated Development Systems
How we connect self-hosted Gitea, Mattermost, CI, and a lightweight PaaS into a
continuous development pipeline where code goes from PR to production with
minimal human intervention.
---
## The Hub: Self-Hosted Gitea
[Gitea](https://gitea.io) is the coordination center. Every repo, issue, PR, and
code review lives here. We self-host it because:
- Full API access for automation (the agent has its own Gitea user with API
token)
- Gitea Actions for CI (compatible with GitHub Actions syntax)
- Webhooks on every repo event
- No vendor lock-in, no rate limits, no surprise pricing changes
- Complete control over visibility (public/private per-repo)
The agent (OpenClaw) has its own Gitea account (`clawbot`) separate from the
human user. This matters because:
- The agent's commits, comments, and PR reviews are clearly attributed
- The human can @-mention the agent in issues to assign work
- Assignment is unambiguous — issues assigned to `clawbot` are the agent's
queue, issues assigned to the human are theirs
- The agent can be given write access per-repo (some repos it can push to
directly, others it must fork and PR)
- API rate limits and permissions are independent
## Real-Time Activity Feed: Gitea → Mattermost
Every repo has a Gitea webhook that sends all activity (pushes, PRs, issues,
comments, reviews, CI status) to a channel in our self-hosted
[Mattermost](https://mattermost.com) instance. This creates a real-time feed
where everyone — human and agent — can see what's happening across all projects
without cross-communication overhead.
The agent also has its own Mattermost bot user (`@claw`), separate from the
human. This means:
- The agent posts status updates to dedicated channels (`#git` for Gitea work,
`#claw` for general work narration)
- The human's DMs stay clean — only direct alerts and responses
- In group channels, it's clear who said what
- The agent can be @-mentioned in any channel
### Channel Architecture
A practical setup:
- **#git** — Real-time Gitea webhook feed (all repos) + agent's work status
updates. Everyone sees commits, PRs, reviews, CI results as they happen.
- **#claw** — Agent's internal work narration. Useful for debugging what the
agent is doing, but notifications muted so it doesn't disturb anyone.
- **DM with agent** — Private conversation, sitreps, sensitive commands
- **Project-specific channels** — For coordination with external collaborators
The webhook feed in #git means nobody needs to check Gitea's notification inbox
manually. PRs, reviews, and CI results flow into a channel that's always open.
The agent monitors the same feed (via its notification poller) and can react to
events in near-realtime.
## CI: Gitea Actions
Every repo has a CI workflow in `.gitea/workflows/` that runs on push. The
standard workflow is one line:
```yaml
- name: Build and check
run: docker build .
```
Because the Dockerfile runs `make check` (which runs tests, linting, and
formatting checks), a successful Docker build means everything passes. A failed
build means something is broken. Binary signal, no ambiguity.
### PR Preview Deployments
For web projects (like a blog or documentation site), CI can go further than
pass/fail. When a PR is opened against a site repo, CI can:
1. Build the site from the PR branch
2. Deploy it to a preview URL
3. Post the preview URL as a comment on the PR or drop it into a Mattermost
channel
This lets reviewers see the actual rendered result before merging, not just the
code diff. For a Jekyll/Hugo blog, this means you can see how a new post looks
on the real site layout, on mobile, with real CSS — before it goes live.
## Deployment: µPaaS
[µPaaS](https://git.eeqj.de/sneak/upaas) is a lightweight, self-hosted
platform-as-a-service that auto-deploys Docker containers when code changes. It
exists because:
- Full PaaS platforms (Kubernetes, Nomad, etc.) are massive overkill for a small
fleet of services
- Heroku/Render/Fly.io mean vendor dependency and recurring costs
- We wanted: push to main → live in production, automatically, with zero human
intervention
### How It Works
µPaaS is a single Go binary that:
1. **Receives Gitea webhooks** on push/merge events
2. **Clones the repo** using deploy keys (read-only SSH keys per-repo)
3. **Runs `docker build`** to build the new image
4. **Swaps the running container** with the new image
5. **Routes traffic** via Traefik reverse proxy with automatic TLS
The deploy flow:
```
Developer merges PR to main/prod
→ Gitea fires webhook to µPaaS
→ µPaaS clones repo, builds Docker image
→ µPaaS stops old container, starts new one
→ Traefik routes traffic to new container
→ Site is live on its production URL with TLS
```
Time from merge to live: typically under 2 minutes (dominated by Docker build
time).
### Deploy Keys
Each repo that deploys via µPaaS has a read-only SSH deploy key. This means:
- µPaaS can clone the repo to build it, but can't push to it
- Each key is scoped to one repo — compromise of one key doesn't affect others
- No shared credentials, no broad API tokens
### What's Deployed This Way
Any Docker-based service or site:
- Static sites (Jekyll, Hugo) — Dockerfile builds the site, nginx serves it
- Go services — Dockerfile builds the binary, runs it
- Web applications — same pattern
Everything gets a production URL with automatic TLS via Traefik.
## The Full Pipeline
Putting it all together, the development lifecycle looks like this:
```
1. Issue filed in Gitea (by human or agent)
2. Agent picks up the issue (via notification poller)
3. Agent posts "starting work on #N" to Mattermost #git
4. Agent (or sub-agent) creates branch, writes code, pushes
5. Gitea webhook fires → #git shows the push
6. CI runs docker build → passes or fails
7. Agent creates PR "(closes #N)"
8. Gitea webhook fires → #git shows the PR
9. Agent reviews code, runs make check locally, verifies
10. Agent assigns PR to human when all checks pass
11. Human reviews, requests changes or approves
12. If changes requested → agent reworks, back to step 6
13. Human merges PR
14. Gitea webhook fires → µPaaS deploys to production
15. Gitea webhook fires → #git shows the merge
16. Site/service is live on production URL
```
Steps 2-10 can happen without any human involvement. The human's role is reduced
to: review the PR, approve or request changes, merge. Everything else is
automated.
### Observability
Because everything flows through Mattermost channels:
- The human can glance at #git to see the current state of all projects
- CI failures are immediately visible (Gitea Actions posts status)
- Deployments are immediately visible (µPaaS can log to the same channel)
- The agent's work narration in #claw shows what it's currently doing
- No need to check multiple dashboards — one chat client shows everything
## Identity Separation
A key architectural decision: the agent has its own identity everywhere.
| System | Human Account | Agent Account |
| ---------- | ------------- | ------------- |
| Gitea | @sneak | @clawbot |
| Mattermost | @sneak | @claw |
This separation means:
- **Clear attribution.** Every commit, comment, and message shows who did it.
When reviewing git history, you know which commits were human and which were
agent.
- **Independent permissions.** The agent can have write access to repos where
it's trusted, fork-and-PR access where it's not. The human can have admin
access without the agent inheriting it.
- **Mentionability.** The human can @-mention the agent in an issue comment to
assign work. The agent can @-mention the human when it needs review. This
works exactly like human-to-human collaboration.
- **Separate notification streams.** The agent's notification poller watches
`@clawbot`'s inbox. The human's notifications are separate. No cross-talk.
## Why Self-Host Everything
The stack — Gitea, Mattermost, µPaaS, OpenClaw — is entirely self-hosted. This
isn't ideological; it's practical:
- **No API rate limits.** The agent makes dozens of API calls per hour to Gitea.
GitHub's API limits would throttle it.
- **No surprise costs.** CI minutes, seat licenses, storage — all free when
self-hosted.
- **Full API access.** Every feature of every tool is available via API. No
"enterprise only" gates.
- **Custom webhooks.** We can wire up any event to any action. Gitea push →
Mattermost notification → µPaaS deploy → agent notification, all custom.
- **Data sovereignty.** Code, issues, conversations, and deployment
infrastructure all live on machines we control.
- **Offline resilience.** If GitHub/Slack/Vercel have an outage, our pipeline
keeps running.
The trade-off is maintenance burden, but with an AI agent handling most of the
operational work (monitoring, updates, issue triage), the maintenance cost is
surprisingly low.
---
_This document describes a production system that's been running since
early 2026. The specific tools (Gitea, Mattermost, µPaaS) are interchangeable —
the patterns (webhook-driven deployment, real-time activity feeds, identity
separation, automated CI gates) apply to any self-hosted stack._

View File

@ -7,6 +7,11 @@ agent) under the direction of [@sneak](https://sneak.berlin).
## What's Here ## What's Here
- **[AUTOMATED_DEV.md](AUTOMATED_DEV.md)** — How self-hosted Gitea, Mattermost,
Gitea Actions CI, and µPaaS connect into a continuous pipeline where code goes
from PR to production automatically. Covers webhook-driven deployments,
real-time activity feeds, PR preview sites, identity separation (agent vs
human accounts), and why self-hosting the entire stack matters.
- **[OPENCLAW_TRICKS.md](OPENCLAW_TRICKS.md)** — Tested configuration recipes - **[OPENCLAW_TRICKS.md](OPENCLAW_TRICKS.md)** — Tested configuration recipes
for OpenClaw agents: workspace bootstrapping, daily context state files, for OpenClaw agents: workspace bootstrapping, daily context state files,
sitrep (situation report) prompts, sleep tracking, medication tracking, sitrep (situation report) prompts, sleep tracking, medication tracking,