Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dcb07cfed7 |
No files matched your search
@@ -1,6 +1,6 @@
|
||||
name: Builder image
|
||||
|
||||
# Publishes the AI builder worker image (gbrgames worker, see BUILDER.md).
|
||||
# Publishes the AI builder worker (gbrgames worker) used on the builder VM; watchtower there picks it up.
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
|
||||
@@ -62,7 +62,7 @@ jobs:
|
||||
boot-test:
|
||||
needs: validate
|
||||
if: needs.validate.outputs.games != ''
|
||||
# A dedicated runner whose game containers can reach the internet but not private networks
|
||||
# A dedicated runner on VM 116 whose game containers can reach the internet but not the LAN
|
||||
runs-on: game-test
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
|
||||
+54
-27
@@ -1,15 +1,15 @@
|
||||
# AI builder (gbrgames worker)
|
||||
|
||||
The panel's **AI builder** (Admin → Games → AI Config Generator) is run by a worker we host ourselves.
|
||||
The panel only keeps a queue; every result is a pull request to this repo, which CI validates and
|
||||
boot-tests like any other.
|
||||
The panel's **AI builder** (Admin → Games → AI Config Generator) is run by a worker on our own hardware,
|
||||
not on the panel's droplet and not in CI:
|
||||
|
||||
```
|
||||
Panel Builder worker (gbrgames worker, Docker)
|
||||
───── ─────────────────────────────────────────
|
||||
admin starts a job ──► queued ◄─poll── research: web search + page reader + model
|
||||
progress / log / variants ◄─post── build: first boot → draft → boot with the node-agent
|
||||
"Review draft PR" → branch draft/<id>-<job> + PR as the bot ──► CI (validate + boot test)
|
||||
Panel (droplet) Builder VM (home lab)
|
||||
─────────────── ─────────────────────────────────────────────
|
||||
admin starts a job ──► queued ◄─poll── gbrgames worker (Docker)
|
||||
progress / log / variants ◄─post── research: SearXNG + page reader + Ollama (3090)
|
||||
"Review draft PR" build: first boot → draft → boot with the node-agent
|
||||
→ branch draft/<id>-<job> + PR as gbr-bot ──► CI (validate + boot test)
|
||||
```
|
||||
|
||||
1. **Research** (`gbrgames research -name N`): searches the web, reads the best pages, and has the model list
|
||||
@@ -21,41 +21,68 @@ progress / log / variants ◄─post── build: first boot → draft
|
||||
draft by the model (`draft`, rules in `AUTHORING.md`), then the draft is deployed with the node-agent's
|
||||
`BootTest`, the same check CI runs. Failures (crash, error lines, saves written outside `/server`) go
|
||||
back to the model, three boots at most.
|
||||
4. The worker pushes `games/<id>/` to a branch and opens a pull request as the bot account. A draft that
|
||||
4. The worker pushes `games/<id>/` to a branch and opens a pull request as **gbr-bot**. A draft that
|
||||
validates but never booted still gets a PR, titled `WIP:`, with what's left listed. Nothing reaches
|
||||
players until a person merges it and enables the game.
|
||||
|
||||
The worker only connects out (to the panel, Gitea, the model and the search services).
|
||||
The worker only connects out (to the panel, Gitea, Ollama, SearXNG); nothing needs to reach the VM.
|
||||
|
||||
## Requirements
|
||||
## The VM
|
||||
|
||||
A Docker host with the isolated `gbr-boottest` network (`RUNNER.md`, step 1), so servers booted by the
|
||||
builder can't reach private networks. Enough memory for the largest server it builds (~16 GB for ARK) and
|
||||
disk for SteamCMD downloads. The image `gbr-builder:latest` is published by
|
||||
`.gitea/workflows/builder-image.yml` whenever `cmd/` changes on main.
|
||||
A Proxmox VM of its own, so builds never compete with CI boot tests on VM 126: Debian 13, 4+ cores
|
||||
(`host` CPU type), 24 GB RAM (ARK-sized servers need ~16 GB), 150 GB disk (SteamCMD downloads), Docker.
|
||||
|
||||
## Configuration
|
||||
```bash
|
||||
# as root
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
git clone https://www.gitea.gbreed.com/gbreed-public/gbr-games.git /opt/gbr-games
|
||||
```
|
||||
|
||||
All through environment variables; nothing about where it runs lives in this repo.
|
||||
**Isolated network:** game servers booted here must not reach the LAN. Same setup as the runner
|
||||
(`RUNNER.md`, step 1):
|
||||
|
||||
| Variable | What |
|
||||
| --- | --- |
|
||||
| `PANEL_URL` | The panel the worker takes jobs from |
|
||||
| `BUILDER_TOKEN` | Shared secret the panel checks on `/api/v1/builder/**` (same value in the panel's env) |
|
||||
| `GITEA_TOKEN` | The bot account's token (repository read/write on this repo): pushes draft branches, opens PRs |
|
||||
| `OLLAMA_URL` | Ollama for the model (or `MODEL_PROVIDER=gemini` with `GEMINI_API_KEY`) |
|
||||
| `SEARXNG_URL`, `READER_URL` | A SearXNG instance (JSON API) and a page-to-text reader (`READER_URL/<page url>`) |
|
||||
| `MODEL`, `POLL_INTERVAL`, `WORKER_NAME`, `WORK_DIR` | Optional: model name, poll interval (20s), name shown in the panel, work folder |
|
||||
```bash
|
||||
mkdir -p /opt/gbr-boottest
|
||||
cp /opt/gbr-games/scripts/runner/setup-boottest-network.sh /opt/gbr-boottest/
|
||||
chmod +x /opt/gbr-boottest/setup-boottest-network.sh
|
||||
cp /opt/gbr-games/scripts/runner/gbr-boottest-network.service /etc/systemd/system/
|
||||
systemctl daemon-reload && systemctl enable --now gbr-boottest-network
|
||||
```
|
||||
|
||||
**Worker:**
|
||||
|
||||
```bash
|
||||
mkdir -p /opt/gbr-builder/work && cd /opt/gbr-builder
|
||||
cp /opt/gbr-games/scripts/builder/docker-compose.yml .
|
||||
cp /opt/gbr-games/scripts/builder/env.example .env && chmod 600 .env # then fill it in
|
||||
docker compose up -d && docker logs -f gbr-builder
|
||||
```
|
||||
|
||||
`gbr-builder:latest` is published by `.gitea/workflows/builder-image.yml` whenever `cmd/` changes on
|
||||
main; watchtower on the VM updates the worker within five minutes.
|
||||
|
||||
## Accounts and secrets
|
||||
|
||||
| Where | Name | What |
|
||||
| --- | --- | --- |
|
||||
| Builder `.env` | `GITEA_TOKEN` | Token of the **gbr-bot** Gitea user (Write on `gbr-games`, scope repository read/write) |
|
||||
| Builder `.env` + panel env | `BUILDER_TOKEN` | Shared secret the panel checks on `/api/v1/builder/**`; any long random string |
|
||||
| Builder `.env` | `OLLAMA_URL`, `SEARXNG_URL`, `READER_URL` | The 3090's Ollama, SearXNG, and the page reader |
|
||||
|
||||
## Running a build by hand
|
||||
|
||||
On any machine with Docker and the `gbr-boottest` network, with `OLLAMA_URL`, `SEARXNG_URL` and
|
||||
`READER_URL` set:
|
||||
On any machine with Docker and the `gbr-boottest` network (the builder VM, or the runner):
|
||||
|
||||
```bash
|
||||
export OLLAMA_URL=http://192.168.4.30:11434 SEARXNG_URL=http://192.168.4.38:8080 READER_URL=http://192.168.4.38:3000
|
||||
go run ./cmd/gbrgames research -name Valheim -out research.json
|
||||
# pick a variant from research.json into v.json, then:
|
||||
go run ./cmd/gbrgames build -name Valheim -variant @v.json -out build.json
|
||||
```
|
||||
|
||||
The draft lands in `games/<id>/`, first-boot reports in `firstboot-out/`.
|
||||
|
||||
## Housekeeping
|
||||
|
||||
Like the runner: a weekly `docker system prune -af --filter "until=168h"` keeps images and SteamCMD
|
||||
downloads in check. Each job removes its clone; boot tests remove their containers and volumes.
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# The AI builder worker (gbrgames worker); see BUILDER.md.
|
||||
# The AI builder worker (gbrgames worker), run on our own builder VM; see BUILDER.md.
|
||||
FROM golang:1.24-alpine AS build
|
||||
WORKDIR /src
|
||||
COPY go.mod go.sum ./
|
||||
|
||||
@@ -327,7 +327,7 @@ func (t *teeWriter) Write(p []byte) (int, error) {
|
||||
// buildSummary is the pull request's description: where the facts came from and what was really checked.
|
||||
func buildSummary(o buildOptions, res *buildResult) string {
|
||||
var b strings.Builder
|
||||
fmt.Fprintf(&b, "Drafted by the GBR AI builder. **Review before merging**: check the settings, "+
|
||||
fmt.Fprintf(&b, "Drafted by the GBR builder (AI on our own hardware). **Review before merging**: check the settings, "+
|
||||
"ports and descriptions against the game's documentation.\n\n")
|
||||
fmt.Fprintf(&b, "- Game: **%s**", o.name)
|
||||
if o.variant.Title != "" {
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// worker runs the AI builder. It asks the panel for queued jobs (it only connects out,
|
||||
// worker runs the AI builder on our own hardware. It asks the panel for queued jobs (it only connects out,
|
||||
// like node-agents do), runs research or build in a fresh clone of this repo, streams the output to the
|
||||
// panel as the job's log, and finishes a build with a pull request opened as the bot account. CI then
|
||||
// validates and boot-tests that pull request like any other.
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
# The AI builder worker on the builder VM (BUILDER.md). It polls the panel for jobs, so nothing needs to
|
||||
# reach this VM from outside. Game servers it boots run in the isolated gbr-boottest network.
|
||||
services:
|
||||
gbr-builder:
|
||||
image: www.gitea.gbreed.com/gbreed-public/gbr-builder:latest
|
||||
container_name: gbr-builder
|
||||
restart: unless-stopped
|
||||
env_file: .env
|
||||
environment:
|
||||
WORK_DIR: /work
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
# Job clones and first-boot reports (servers themselves use Docker volumes)
|
||||
- /opt/gbr-builder/work:/work
|
||||
labels:
|
||||
- com.centurylinklabs.watchtower.enable=true
|
||||
|
||||
watchtower:
|
||||
image: containrrr/watchtower:1.7.1
|
||||
container_name: gbr-builder-watchtower
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
WATCHTOWER_LABEL_ENABLE: "true"
|
||||
WATCHTOWER_POLL_INTERVAL: "300"
|
||||
WATCHTOWER_CLEANUP: "true"
|
||||
DOCKER_API_VERSION: "1.44"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
@@ -0,0 +1,19 @@
|
||||
# Copy to /opt/gbr-builder/.env and fill in. Never commit the real file.
|
||||
|
||||
# The panel the worker takes jobs from, and the token both sides share (panel env BUILDER_TOKEN)
|
||||
PANEL_URL=https://api.gbrhosting.com
|
||||
BUILDER_TOKEN=
|
||||
|
||||
# The gbr-bot account's token (repository read/write on gbreed-public/gbr-games): pushes draft branches, opens PRs
|
||||
GITEA_TOKEN=
|
||||
|
||||
# The model on the 3090, and the search + page reader the research step uses
|
||||
OLLAMA_URL=http://192.168.4.30:11434
|
||||
SEARXNG_URL=http://192.168.4.38:8080
|
||||
READER_URL=http://192.168.4.38:3000
|
||||
|
||||
# Optional
|
||||
# MODEL=qwen3.8:27b
|
||||
# MODEL_PROVIDER=ollama # or gemini, with GEMINI_API_KEY
|
||||
# POLL_INTERVAL=20s
|
||||
# WORKER_NAME=gamebuilder
|
||||
Reference in new issue
Block a user