---
name: build-pipeline
description: Never run build-agents.sh manually; all builds go through the Gitea webhook pipeline (push to main)
applies-to: gururmm
---

# GuruRMM Build Pipeline

## The rule

Never run `build-agents.sh` manually via SSH unless recovering from a specific failure (e.g., a stale zombie lock file). All agent and server builds go through the Gitea webhook pipeline: push to `main` on `azcomputerguru/gururmm` triggers the build automatically.

Running the build script manually can create version conflicts, bypass the Authenticode signing step for Windows binaries, and leave the build log in an inconsistent state that causes false "build complete" notifications on the next real build.

## Normal build flow

```
1. Edit code locally or on the server
2. Commit changes
3. Push to Gitea: git push origin main (or push to azcomputerguru/gururmm via Gitea remote)
4. Gitea webhook fires POST to http://172.16.3.30:9000/webhook/build (HMAC-SHA256 signed)
5. webhook-handler.py on Saturn spawns build-agents.sh (Linux) and triggers Pluto (Windows)
6. Monitor: tail -f /var/log/gururmm-build.log on Saturn
```

## Build lock

The build script uses `/var/run/gururmm-build.lock` to prevent concurrent builds. If a build crashes mid-run, the lock file is not cleaned up and the next webhook trigger will fail silently (webhook handler sees the lock and exits).

**Check for zombie lock before triggering any manual build:**

```bash
# Check lock exists and get PID
cat /var/run/gururmm-build.lock

# Check if PID is a zombie (os.kill returns 0 for zombies)
# If PID no longer exists or is zombie, remove the lock
sudo rm -f /var/run/gururmm-build.lock
```

The build script should add a defensive `rm -f /var/run/gururmm-build.lock` at startup (pending improvement). Until that is added, manual lock cleanup before triggered builds is required after any build failure.

## Server build

The server binary is built separately from agents:

```bash
# Trigger server build (as guru user on Saturn, or via SSH)
ssh guru@172.16.3.30 "sudo /opt/gururmm/build-server.sh 2>&1"

# Monitor
ssh guru@172.16.3.30 "tail -f /var/log/gururmm-build.log"
```

The server build uses `SQLX_OFFLINE=true` (set in `/home/guru/.cargo/env`) to avoid the sqlx proc macro querying the live database during compilation.

## Service binary path

The deployed server binary is at `/opt/gururmm/gururmm-server` — this is what systemd's ExecStart points to. Do not deploy to `/usr/local/bin/gururmm-server` (that path has no service backing and has caused "deployed but not running" confusion in past sessions).

```bash
# Correct deploy sequence
sudo systemctl stop gururmm-server
sudo cp /home/guru/gururmm/server/target/release/gururmm-server /opt/gururmm/gururmm-server
sudo systemctl start gururmm-server
```

## Windows agent build (Pluto)

Windows agent builds and Authenticode signing run on Pluto (172.16.3.36). The webhook handler triggers Pluto automatically. Signed binaries avoid the Windows SmartScreen warning that affected unsigned 0.6.2 builds.

The build generates all agent variants:
- `gururmm-agent-linux-x86_64`
- `gururmm-agent-linux-aarch64`
- `gururmm-agent-windows-x86_64.exe`
- `gururmm-agent-windows-x86.exe`
- `gururmm-agent-macos-x86_64`
- `gururmm-agent-macos-aarch64`

All are placed in `/var/www/gururmm/downloads/` on Saturn after build.

## Changelog generation

`build-agents.sh` calls `generate-changelog.sh` before the "Build complete" log line. This creates `changelogs/agent/v{VERSION}.md` and updates `changelogs/LATEST_AGENT.md` automatically on each build. Do not create changelog files manually.
